Mark Crispin wrote:
If I had to guess, it would be that the DIR_SIZE macro is miscalculating the size of the direct struct that's assigned to p in line 53, leading to a buffer overflow in line 55.

Try adding an assert that verifies that DIR_SIZE(d) is greater than, or equal to, ((d->d_name + strlen(d->d_name) + 1) - d). If that assert bites, that's the cause of the problem.

The whole reason why a private Scandir is used is that, for the longest time, Solaris didn't have a scandir() call at all and when it did it was broken. I forget why. Maybe SUN finally figured out how to do a working scandir() call, but if they've broken DIR_SIZE() that is bad news.
Well, it's none of the above...

It's lines 45 and 46 in scandir.c:
45:  if ((!dirp) || (fstat (dirp->dd_fd,&stb) < 0)) return -1;
46:  nlmax = stb.st_size / 24;     /* guesstimate at number of files */

It relies on undefined behaviour, calling stat() on the fd inside a DIR structure.

On a ZFS file system, st_size returns the number of entries in the directory, not the number of bytes allocated to names and inodes, like it did/does for an older file system type. (Who else remember 2 bytes for inode, and 14 bytes for the file name?) (On an XFS file system it returns the number of blocks allocated for directory entries * block size. I don't have any other *NIX file systems within easy reach at the moment.)

The directory that caused the problem had 8 entries, and 8 / 24 == 0 ==> SEGV.

The fix (for my problem) is to use the system-supplied scandir() for current Solaris variants.

The code in scandir should be modified, the call to fstat() should be removed and the initial guess at nlmax set to something reasonable, say, 16.

        Cheers,
                Gary    B-)
_______________________________________________
Imap-uw mailing list
[email protected]
http://mailman2.u.washington.edu/mailman/listinfo/imap-uw

Reply via email to