|
Michal Schmidt |
14c310 |
From 9697feabd63b19b4cbcebb8e6a369eb99e684a65 Mon Sep 17 00:00:00 2001
|
|
Michal Schmidt |
14c310 |
From: Lennart Poettering <lennart@poettering.net>
|
|
Michal Schmidt |
14c310 |
Date: Tue, 13 Mar 2012 02:29:27 +0100
|
|
Michal Schmidt |
14c310 |
Subject: [PATCH] util: add brute-force fallback for close_all_fds()
|
|
Michal Schmidt |
14c310 |
|
|
Michal Schmidt |
14c310 |
If /proc is not available (i.e. in chroot envs) let's fall back to brute
|
|
Michal Schmidt |
14c310 |
forcing our way through the fd table.
|
|
Michal Schmidt |
14c310 |
|
|
Michal Schmidt |
14c310 |
https://bugzilla.redhat.com/show_bug.cgi?id=784921
|
|
Michal Schmidt |
14c310 |
(cherry picked from commit b19be9eb9e231ccf350e0e051b687fc425c61904)
|
|
Michal Schmidt |
14c310 |
---
|
|
Michal Schmidt |
14c310 |
src/util.c | 54 ++++++++++++++++++++++++++++++++++++++----------------
|
|
Michal Schmidt |
14c310 |
1 files changed, 38 insertions(+), 16 deletions(-)
|
|
Michal Schmidt |
14c310 |
|
|
Michal Schmidt |
14c310 |
diff --git a/src/util.c b/src/util.c
|
|
Michal Schmidt |
14c310 |
index 0c9537e..3a66c3b 100644
|
|
Michal Schmidt |
14c310 |
--- a/src/util.c
|
|
Michal Schmidt |
14c310 |
+++ b/src/util.c
|
|
Michal Schmidt |
14c310 |
@@ -2147,13 +2147,47 @@ int fd_cloexec(int fd, bool cloexec) {
|
|
Michal Schmidt |
14c310 |
return 0;
|
|
Michal Schmidt |
14c310 |
}
|
|
Michal Schmidt |
14c310 |
|
|
Michal Schmidt |
14c310 |
+static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
|
|
Michal Schmidt |
14c310 |
+ unsigned i;
|
|
Michal Schmidt |
14c310 |
+
|
|
Michal Schmidt |
14c310 |
+ assert(n_fdset == 0 || fdset);
|
|
Michal Schmidt |
14c310 |
+
|
|
Michal Schmidt |
14c310 |
+ for (i = 0; i < n_fdset; i++)
|
|
Michal Schmidt |
14c310 |
+ if (fdset[i] == fd)
|
|
Michal Schmidt |
14c310 |
+ return true;
|
|
Michal Schmidt |
14c310 |
+
|
|
Michal Schmidt |
14c310 |
+ return false;
|
|
Michal Schmidt |
14c310 |
+}
|
|
Michal Schmidt |
14c310 |
+
|
|
Michal Schmidt |
14c310 |
int close_all_fds(const int except[], unsigned n_except) {
|
|
Michal Schmidt |
14c310 |
DIR *d;
|
|
Michal Schmidt |
14c310 |
struct dirent *de;
|
|
Michal Schmidt |
14c310 |
int r = 0;
|
|
Michal Schmidt |
14c310 |
|
|
Michal Schmidt |
14c310 |
- if (!(d = opendir("/proc/self/fd")))
|
|
Michal Schmidt |
14c310 |
- return -errno;
|
|
Michal Schmidt |
14c310 |
+ assert(n_except == 0 || except);
|
|
Michal Schmidt |
14c310 |
+
|
|
Michal Schmidt |
14c310 |
+ d = opendir("/proc/self/fd");
|
|
Michal Schmidt |
14c310 |
+ if (!d) {
|
|
Michal Schmidt |
14c310 |
+ int fd;
|
|
Michal Schmidt |
14c310 |
+ struct rlimit rl;
|
|
Michal Schmidt |
14c310 |
+
|
|
Michal Schmidt |
14c310 |
+ /* When /proc isn't available (for example in chroots)
|
|
Michal Schmidt |
14c310 |
+ * the fallback is brute forcing through the fd
|
|
Michal Schmidt |
14c310 |
+ * table */
|
|
Michal Schmidt |
14c310 |
+
|
|
Michal Schmidt |
14c310 |
+ assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
|
|
Michal Schmidt |
14c310 |
+ for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
|
|
Michal Schmidt |
14c310 |
+
|
|
Michal Schmidt |
14c310 |
+ if (fd_in_set(fd, except, n_except))
|
|
Michal Schmidt |
14c310 |
+ continue;
|
|
Michal Schmidt |
14c310 |
+
|
|
Michal Schmidt |
14c310 |
+ if (close_nointr(fd) < 0)
|
|
Michal Schmidt |
14c310 |
+ if (errno != EBADF && r == 0)
|
|
Michal Schmidt |
14c310 |
+ r = -errno;
|
|
Michal Schmidt |
14c310 |
+ }
|
|
Michal Schmidt |
14c310 |
+
|
|
Michal Schmidt |
14c310 |
+ return r;
|
|
Michal Schmidt |
14c310 |
+ }
|
|
Michal Schmidt |
14c310 |
|
|
Michal Schmidt |
14c310 |
while ((de = readdir(d))) {
|
|
Michal Schmidt |
14c310 |
int fd = -1;
|
|
Michal Schmidt |
14c310 |
@@ -2171,20 +2205,8 @@ int close_all_fds(const int except[], unsigned n_except) {
|
|
Michal Schmidt |
14c310 |
if (fd == dirfd(d))
|
|
Michal Schmidt |
14c310 |
continue;
|
|
Michal Schmidt |
14c310 |
|
|
Michal Schmidt |
14c310 |
- if (except) {
|
|
Michal Schmidt |
14c310 |
- bool found;
|
|
Michal Schmidt |
14c310 |
- unsigned i;
|
|
Michal Schmidt |
14c310 |
-
|
|
Michal Schmidt |
14c310 |
- found = false;
|
|
Michal Schmidt |
14c310 |
- for (i = 0; i < n_except; i++)
|
|
Michal Schmidt |
14c310 |
- if (except[i] == fd) {
|
|
Michal Schmidt |
14c310 |
- found = true;
|
|
Michal Schmidt |
14c310 |
- break;
|
|
Michal Schmidt |
14c310 |
- }
|
|
Michal Schmidt |
14c310 |
-
|
|
Michal Schmidt |
14c310 |
- if (found)
|
|
Michal Schmidt |
14c310 |
- continue;
|
|
Michal Schmidt |
14c310 |
- }
|
|
Michal Schmidt |
14c310 |
+ if (fd_in_set(fd, except, n_except))
|
|
Michal Schmidt |
14c310 |
+ continue;
|
|
Michal Schmidt |
14c310 |
|
|
Michal Schmidt |
14c310 |
if (close_nointr(fd) < 0) {
|
|
Michal Schmidt |
14c310 |
/* Valgrind has its own FD and doesn't want to have it closed */
|