]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic: be more careful when closing fds based on RLIMIT_NOFILE
authorLennart Poettering <lennart@poettering.net>
Mon, 7 May 2018 15:54:59 +0000 (17:54 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 17 May 2018 18:40:04 +0000 (20:40 +0200)
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

index 4b3e7ed5575f861ff5f47f85749a77343d3c7032..9536a50b740c9d5b6ddd9d72f6bcb1b7d3963fa9 100644 (file)
@@ -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))