Bug 8463 - Buffer-overflow in dirsort plugin when directory contents change at wrong time.
Buffer-overflow in dirsort plugin when directory contents change at wrong time.
Status: NEW
Product: Samba 4.1 and newer
Classification: Unclassified
Component: VFS Modules
unspecified
All All
: P5 normal
: ---
Assigned To: Samba QA Contact
Samba QA Contact
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-09-17 05:11 UTC by (account disabled)
Modified: 2016-09-14 16:37 UTC (History)
0 users

See Also:


Attachments
Prevent buffer overflow when directory contents change (1.07 KB, patch)
2011-09-17 05:11 UTC, (account disabled)
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description (account disabled) 2011-09-17 05:11:36 UTC
Created attachment 6901 [details]
Prevent buffer overflow when directory contents change

The dirsort vfs plugin opens the directory and reads all entries to count
them and figure out how much data to allocate; it then uses rewinddir()
and reads the entries again, this time copying them into the allocated
buffer. The problem is that the second time through you're not guaranteed
to get the same list of entries - if a new file/directory was created in
the mean time then readdir() will return that new entry too and the code
will attempt to write more into the buffer than it allocated space for.

The following little test demonstrates this behaviour:

-------------------------------------------------------------
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>

#define DIR_PATH "/tmp/rewinddir_test"
#define NEW_FILE (DIR_PATH "/foobar")

int main() {
  DIR *dir;
  int  cnt;

  /* set up test directory */
  mkdir(DIR_PATH, 0755);

  dir = opendir(DIR_PATH);

  /* first read of directory */
  cnt = 0;
  while (readdir(dir))
    cnt++;
  printf("first pass: num-files=%d\n", cnt);

  /* create new file and rewind */
  fclose(fopen(NEW_FILE, "a"));
  rewinddir(dir);

  /* second read of directory */
  cnt = 0;
  while (readdir(dir))
    cnt++;
  printf("second pass: num-files=%d\n", cnt);

  /* clean up */
  closedir(dir);
  unlink(NEW_FILE);
  rmdir(DIR_PATH);

  return 0;
}
-------------------------------------------------------------

The attached patch fixes this by breaking out of the loop if we would
write too much into the buffer.