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);