From: Florian Weimer Date: Tue, 16 Oct 2012 08:33:50 +0000 (+0200) Subject: __alloc_dir: avoid integer overflow in malloc argument X-Git-Tag: glibc-2.17~402 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=172a631a1fc8ec8fcef80af1f91438d092957c3e;p=thirdparty%2Fglibc.git __alloc_dir: avoid integer overflow in malloc argument --- diff --git a/ChangeLog b/ChangeLog index 0c05941f6f6..8e83c46e2c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-10-16 Florian Weimer + + [BZ #14700] + * sysdeps/posix/opendir.c (MAX_DIR_BUFFER_SIZE): New constant. + (__alloc_dir): Limit buffer to MAX_DIR_BUFFER_SIZE. + 2012-10-16 Maxim Kuvyrkov * NEWS: Mention BZ #14716. diff --git a/sysdeps/posix/opendir.c b/sysdeps/posix/opendir.c index e093142f626..f1cc1aeb576 100644 --- a/sysdeps/posix/opendir.c +++ b/sysdeps/posix/opendir.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1991-1996,98,2000-2003,2005,2007,2009,2011 - Free Software Foundation, Inc. +/* Copyright (C) 1991-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -33,6 +32,11 @@ #include #include +/* The st_blksize value of the directory is used as a hint for the + size of the buffer which receives struct dirent values from the + kernel. st_blksize is limited to MAX_DIR_BUFFER_SIZE, in case the + file system provides a bogus value. */ +#define MAX_DIR_BUFFER_SIZE 1048576U /* opendir() must not accidentally open something other than a directory. Some OS's have kernel support for that, some don't. In the worst @@ -192,8 +196,11 @@ __alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp) ? sizeof (struct dirent64) : BUFSIZ); size_t allocation = default_allocation; #ifdef _STATBUF_ST_BLKSIZE - if (statp != NULL && default_allocation < statp->st_blksize) - allocation = statp->st_blksize; + /* Increase allocation if requested, but not if the value appears to + be bogus. */ + if (statp != NULL) + allocation = MIN (MAX ((size_t) statp->st_blksize, default_allocation), + MAX_DIR_BUFFER_SIZE); #endif DIR *dirp = (DIR *) malloc (sizeof (DIR) + allocation);