From 37bc14de5bd74a056d55ec14f63dc9ec999e974e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 May 2018 17:54:59 +0200 Subject: [PATCH] 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. --- src/basic/fd-util.c | 15 +++++++++++---- 1 file 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))