Hi,

the library function getusershell(3) assumes that the smallest possible
line in /etc/shells would be 3 chars (slash, a char, new line):
In that case, there are at max sb.st_size / 3 of lines.  Well, that is not
entirely correct.  The last line could be just 2 chars, skipping the
trailing new line.  The integer division rounds down, therefore an off by
one is possible.

If you are able to just get past the allocated page into the next guard
page, users of getusershell(3) crash:

$ uname -m
i386
$ head -n2 /etc/shells # and so on
/a
/a
$ ls -l /etc/shells
-rw-r--r--  1 root  wheel  49152 Jan 15 22:40 /etc/shells
$ chpass
Segmentation fault

Okay?


Tobias

Index: getusershell.c
===================================================================
RCS file: /var/www/cvs/src/lib/libc/gen/getusershell.c,v
retrieving revision 1.11
diff -u -p -r1.11 getusershell.c
--- getusershell.c      24 Nov 2013 23:51:29 -0000      1.11
+++ getusershell.c      16 Jan 2014 19:14:43 -0000
@@ -109,7 +109,7 @@ initshells(void)
                (void)fclose(fp);
                return (okshells);
        }
-       shells = calloc((size_t)(statb.st_size / 3), sizeof (char *));
+       shells = calloc((size_t)(statb.st_size / 3 + 1), sizeof (char *));
        if (shells == NULL) {
                (void)fclose(fp);
                free(strings);

Reply via email to