[patch] Fix BZ #18660 -- overflow in getusershell
Paul Pluzhnikov
ppluzhnikov@gmail.com
Tue Aug 18 23:54:00 GMT 2015
On Mon, Aug 17, 2015 at 3:59 AM, Joseph Myers <joseph@codesourcery.com> wrote:
> Since you're increasing an allocation size, don't you also need to adjust
> the check a few lines earlier for whether the allocation size calculation
> would overflow?
Thanks. Revised patch attached.
2015-08-15 Paul Pluzhnikov <ppluzhnikov@google.com>
Tobias Stoeckmann <tobias@stoeckmann.org>
[BZ #18660]
* misc/getusershell.c (initshells): Fix possible overflow.
--
Paul Pluzhnikov
-------------- next part --------------
diff --git a/misc/getusershell.c b/misc/getusershell.c
index fc2c43b..a5d861e 100644
--- a/misc/getusershell.c
+++ b/misc/getusershell.c
@@ -31,6 +31,7 @@
static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
+#include <assert.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/stat.h>
@@ -99,6 +100,7 @@ initshells (void)
FILE *fp;
struct stat64 statb;
size_t flen;
+ off64_t max_shells;
free(shells);
shells = NULL;
@@ -114,12 +116,13 @@ initshells (void)
okshells[1] = _PATH_CSHELL;
return (char **) okshells;
}
- if (statb.st_size > ~(size_t)0 / sizeof (char *) * 3)
+ max_shells = (statb.st_size / 3) + 2;
+ if (max_shells > ~(size_t)0 / sizeof (char *))
goto init_okshells;
flen = statb.st_size + 3;
if ((strings = malloc(flen)) == NULL)
goto init_okshells;
- shells = malloc(statb.st_size / 3 * sizeof (char *));
+ shells = malloc(max_shells * sizeof (char *));
if (shells == NULL) {
free(strings);
strings = NULL;
@@ -130,13 +133,16 @@ initshells (void)
while (fgets_unlocked(cp, flen - (cp - strings), fp) != NULL) {
while (*cp != '#' && *cp != '/' && *cp != '\0')
cp++;
- if (*cp == '#' || *cp == '\0' || cp[1] == '\0')
+ /* Reject non-absolute paths, or anything too short. */
+ if (cp[0] != '/' || cp[1] == '\0' || isspace(cp[1]))
continue;
*sp++ = cp;
while (!isspace(*cp) && *cp != '#' && *cp != '\0')
cp++;
+ assert (cp < strings + flen);
*cp++ = '\0';
}
+ assert (sp < shells + max_shells);
*sp = NULL;
(void)fclose(fp);
return (shells);
More information about the Libc-alpha
mailing list