Subject: lib/36464: scandir(3) corrupts heap when run on ZFS directories
To: None <lib-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <eravin@panix.com>
List: netbsd-bugs
Date: 06/09/2007 20:55:01
>Number:         36464
>Category:       lib
>Synopsis:       scandir(3) corrupts heap when run on ZFS directories
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jun 09 20:55:00 +0000 2007
>Originator:     Ed Ravin
>Release:        3.1
>Organization:
Public Access Networks Corp
>Environment:
NetBSD panix5.panix.com 3.1_RC3 NetBSD 3.1_RC3 (PANIX-35) #0: Wed Oct 18 22:28:22 EDT 2006  root@juggler.panix.com:/devel/netbsd/3.1-RC3/src/sys/arch/i386/compile/PANIX-35 i386

>Description:
The following code near the top of scandir.c:

    /*
     * estimate the array size by taking the size of the directory file
     * and dividing it by a multiple of the minimum size entry.
     */
    arraysz = (size_t)(stb.st_size / 24);
    names = malloc(arraysz * sizeof(struct dirent *));

causes the program using the library to crash when it calls scandir() for a directory that is mounted on a Solaris server with the ZFS filesystem.  ZFS reports the number of directory entries inside the directory as the directory's st_size rather than the bytesize.  For example, a ten-entry directory is reported as only 10 bytes.  arraysz thus is calculated as (10 / 24) and becomes zero, the malloc allocates zero bytes, and scandir() then merrily reads in the 240 bytes (10 * 24) of directory entries into unallocated memory.


>How-To-Repeat:

>Fix:
teach scandir() to sanity-check the numbers it gets from st_size, maybe use st_blocks * st_blksize as an alternate value for size if st_size is suspicious, or check the size of the allocated memory before copying in directory entries.