Summary: | Off-by-one under-read in FontFileMakeDir() | ||||||||
---|---|---|---|---|---|---|---|---|---|
Product: | xorg | Reporter: | Nathan <nathans.spam.and.friends> | ||||||
Component: | Security | Assignee: | X.Org Security <xorg_security> | ||||||
Status: | NEW --- | QA Contact: | X.Org Security <xorg_security> | ||||||
Severity: | normal | ||||||||
Priority: | medium | ||||||||
Version: | git | ||||||||
Hardware: | All | ||||||||
OS: | All | ||||||||
Whiteboard: | |||||||||
i915 platform: | i915 features: | ||||||||
Attachments: |
|
Description
Nathan
2018-11-25 21:23:07 UTC
Created attachment 142634 [details] signature.asc On Sun, Nov 25, 2018 at 09:23:07PM +0000, bugzilla-daemon@freedesktop.org wrote: > https://bugs.freedesktop.org/show_bug.cgi?id=108859 > int > BuiltinReadDirectory (const char *directory, FontDirectoryPtr *pdir) > { > FontDirectoryPtr dir; > int i; > > static BuiltinDirPtr saved_builtin_dir; > static BuiltinAliasPtr saved_builtin_alias; > > dir = FontFileMakeDir ("", builtin_dir_count); > > As you can see, we call FontFileMakeDir() with an empty string. Let's see how > FontFileMakeDir() handles an empty string: > > FontDirectoryPtr > FontFileMakeDir(const char *dirName, int size) > { > FontDirectoryPtr dir; > int dirlen; > int needslash = 0; > const char *attrib; > int attriblen; > > #if !defined(WIN32) > attrib = strchr(dirName, ':'); > #else > /* OS/2 uses the colon in the drive letter descriptor, skip this */ > attrib = strchr(dirName+2, ':'); > #endif Does anything prevent hitting the #else branch with an empty input string? Thanks Good question! Answer is no, which is also another bug for WIN32 platforms ;) We should add something akin to: ... const char *attrib = NULL; ... #if !defined(WIN32) attrib = strchr(dirName, ':'); #else /* OS/2 uses the colon in the drive letter descriptor, skip this */ if (strlen(dirName) > 2) attrib = strchr(dirName+2, ':'); #endif Created attachment 142635 [details] [review] Proposed patch Here is the proposed patch for the off-by-one and the strchr() pointer arithmetic logic bug. Comment on attachment 142635 [details] [review] Proposed patch >Date: Sun, 25 Nov 2018 13:32:02 -0800 >Subject: [PATCH] libXfont: Fix ASAN errors in FontFileMakeDir() > >FontFileMakeDir() will automatically read one byte before >the dirName buffer if an empty string is passed in, which >one of its callers automatically does. Add a check to make >sure we don't subtrct one from the array index unless it is >non-zero. In addition, on WIN32 platforms, we will read >past the buffer via an unchecked strchr() call. Add a check >to ensure the pointer arithmetic does not reach beyond the >buffer. >--- > src/fontfile/fontdir.c | 13 +++++-------- > 1 file changed, 5 insertions(+), 8 deletions(-) > >diff --git a/src/fontfile/fontdir.c b/src/fontfile/fontdir.c >index 7271603..ab87068 100644 >--- a/src/fontfile/fontdir.c >+++ b/src/fontfile/fontdir.c >@@ -105,28 +105,25 @@ FontDirectoryPtr > FontFileMakeDir(const char *dirName, int size) > { > FontDirectoryPtr dir; >- int dirlen; >+ int dirlen = (int)strlen(dirName); > int needslash = 0; >- const char *attrib; >+ const char *attrib = NULL; > int attriblen; > > #if !defined(WIN32) > attrib = strchr(dirName, ':'); > #else > /* OS/2 uses the colon in the drive letter descriptor, skip this */ >- attrib = strchr(dirName+2, ':'); >+ if (dirlen > 2) >+ attrib = strchr(dirName+2, ':'); > #endif > if (attrib) { > dirlen = attrib - dirName; > attriblen = strlen(attrib); > } else { >- dirlen = strlen(dirName); > attriblen = 0; > } >- if (dirName[dirlen - 1] != '/') >-#ifdef NCD >- if (dirlen) /* leave out slash for builtins */ >-#endif >+ if (dirlen && dirName[dirlen - 1] != '/') > needslash = 1; > dir = malloc(sizeof *dir + dirlen + needslash + 1 + > (attriblen ? attriblen + 1 : 0)); >-- >2.17.1 > |
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.