From 30e328cbf14d03fc9f6569e93e0dac41526264d8 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Mon, 3 Nov 2014 00:43:27 +0100 Subject: [PATCH] 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 --- src/closefrom.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) 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; -- 2.47.3