Do not close file descriptors while scanning the /proc filesystem

Closing file descriptors changes the content of the fd directories in
the /proc filesystem, which means readdir() might get very confused.

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=85663
This commit is contained in:
Guillem Jover 2014-11-03 00:43:27 +01:00
parent 4cc43915f2
commit 30e328cbf1

View File

@ -129,6 +129,10 @@ closefrom_procfs(int lowfd)
const char *path; const char *path;
DIR *dirp; DIR *dirp;
struct dirent *dent; struct dirent *dent;
int *fd_array = NULL;
int fd_array_used = 0;
int fd_array_size = 0;
int i;
/* Use /proc/self/fd (or /dev/fd on FreeBSD) if it exists. */ /* Use /proc/self/fd (or /dev/fd on FreeBSD) if it exists. */
# if defined(__FreeBSD__) || defined(__APPLE__) # if defined(__FreeBSD__) || defined(__APPLE__)
@ -145,10 +149,30 @@ closefrom_procfs(int lowfd)
int fd; int fd;
fd = strtonum(dent->d_name, lowfd, INT_MAX, &errstr); fd = strtonum(dent->d_name, lowfd, INT_MAX, &errstr);
if (errstr == NULL && fd != dirfd(dirp)) if (errstr != NULL || fd == dirfd(dirp))
closefrom_close(fd); continue;
if (fd_array_used >= fd_array_size) {
int *ptr;
if (fd_array_size > 0)
fd_array_size *= 2;
else
fd_array_size = 32;
ptr = reallocarray(fd_array, fd_array_size, sizeof(int));
if (ptr == NULL)
break;
fd_array = ptr;
}
fd_array[fd_array_used++] = fd;
} }
for (i = 0; i < fd_array_used; i++)
closefrom_close(fd_array[i]);
free(fd_array);
(void)closedir(dirp); (void)closedir(dirp);
return 0; return 0;