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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
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;