From: Guillem Jover Date: Sun, 2 Nov 2014 23:43:27 +0000 (+0100) Subject: Do not close file descriptors while scanning the /proc filesystem X-Git-Tag: 0.8.0~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=30e328cbf14d03fc9f6569e93e0dac41526264d8;p=thirdparty%2Flibbsd.git 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 --- diff --git a/src/closefrom.c b/src/closefrom.c index 27aa26f..b6d9834 100644 --- a/src/closefrom.c +++ b/src/closefrom.c @@ -129,6 +129,10 @@ closefrom_procfs(int lowfd) const char *path; DIR *dirp; 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. */ # if defined(__FreeBSD__) || defined(__APPLE__) @@ -145,10 +149,30 @@ closefrom_procfs(int lowfd) int fd; fd = strtonum(dent->d_name, lowfd, INT_MAX, &errstr); - if (errstr == NULL && fd != dirfd(dirp)) - closefrom_close(fd); + if (errstr != NULL || fd == dirfd(dirp)) + 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); return 0;