diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-05-07 17:54:59 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2018-05-17 20:40:04 +0200 |
commit | 37bc14de5bd74a056d55ec14f63dc9ec999e974e (patch) | |
tree | ddad4bfcee8389c85ac20c739883e05dd270b550 /src/basic/fd-util.c | |
parent | 1752d69a8bd2fed951b0298806440fbd2dbb07f8 (diff) | |
download | systemd-37bc14de5bd74a056d55ec14f63dc9ec999e974e.tar.gz |
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/basic/fd-util.c')
-rw-r--r-- | src/basic/fd-util.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 4b3e7ed557..9536a50b74 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -199,15 +199,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)) |