summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-05-07 17:54:59 +0200
committerSven Eden <yamakuzure@gmx.net>2018-08-24 16:47:08 +0200
commit7a8e201643552eff3aac06128f782ace20e2af8a (patch)
tree7eb696ee3c9b3dcde2d2019001e70e1dd1482bd9 /src
parent479f41009ad4ea369a382b255bdf0378a3153356 (diff)
basic: be more careful when closing fds based on RLIMIT_NOFILE
Let's make sure we properly handle cases where RLIMIT_NOFILE is set to infinity, zero or values outside of the "int" range.
Diffstat (limited to 'src')
-rw-r--r--src/basic/fd-util.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index 9bc78b585..5adbd05f6 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -201,15 +201,22 @@ int close_all_fds(const int except[], size_t n_except) {
d = opendir("/proc/self/fd");
if (!d) {
- int fd;
struct rlimit rl;
+ int fd, max_fd;
- /* When /proc isn't available (for example in chroots)
- * the fallback is brute forcing through the fd
+ /* When /proc isn't available (for example in chroots) the fallback is brute forcing through the fd
* table */
assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
- for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
+
+ if (rl.rlim_max == 0)
+ return -EINVAL;
+
+ /* Let's take special care if the resource limit is set to unlimited, or actually larger than the range
+ * of 'int'. Let's avoid implicit overflows. */
+ max_fd = (rl.rlim_max == RLIM_INFINITY || rl.rlim_max > INT_MAX) ? INT_MAX : (int) (rl.rlim_max - 1);
+
+ for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
int q;
if (fd_in_set(fd, except, n_except))