From: Lennart Poettering Date: Mon, 7 May 2018 15:54:59 +0000 (+0200) Subject: basic: be more careful when closing fds based on RLIMIT_NOFILE X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=7a8e201643552eff3aac06128f782ace20e2af8a;p=elogind.git 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. --- 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))