On Thu, Jan 16, 2014 at 08:23:52PM +0100, Tobias Stoeckmann wrote:
> 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?
>
ok gilles@
> 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);
>
--
Gilles Chehade
https://www.poolp.org @poolpOrg