]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: invoke rlimit_nofile_safe() before various exec{v,ve,l}() invocations
authorLennart Poettering <lennart@poettering.net>
Mon, 26 Nov 2018 15:06:26 +0000 (16:06 +0100)
committerLennart Poettering <lennart@poettering.net>
Sat, 1 Dec 2018 11:50:45 +0000 (12:50 +0100)
Whenever we invoke external, foreign code from code that has
RLIMIT_NOFILE's soft limit bumped to high values, revert it to 1024
first. This is a safety precaution for compatibility with programs using
select() which cannot operate with fds > 1024.

This commit adds the call to rlimit_nofile_safe() to all invocations of
exec{v,ve,l}() and friends that either are in code that we know runs
with RLIMIT_NOFILE bumped up (which is PID 1 and all journal code for
starters) or that is part of shared code that might end up there.

The calls are placed as early as we can in processes invoking a flavour
of execve(), but after the last time we do fd manipulations, so that we
can still take benefit of the high fd limits for that.

12 files changed:
src/basic/process-util.c
src/core/main.c
src/core/shutdown.c
src/fsck/fsck.c
src/import/pull-common.c
src/journal-remote/journal-remote-main.c
src/libsystemd/sd-bus/bus-socket.c
src/nspawn/nspawn-setuid.c
src/shared/exec-util.c
src/shared/pager.c
src/systemctl/systemctl.c
src/udev/udev-event.c

index 5cf4e37f242339614db9686bdea1f4f7214c15aa..e69566c8a422335f963aa3221ef9a7032b932a70 100644 (file)
@@ -1521,6 +1521,8 @@ int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret
                 safe_close_above_stdio(fd);
         }
 
+        (void) rlimit_nofile_safe();
+
         /* Count arguments */
         va_start(ap, path);
         for (n = 0; va_arg(ap, char*); n++)
index 6d03b066847d5c45c5c52b1e64f7fc2a28a26f46..839dc062ff780700c9213beec517468c6ed66bcb 100644 (file)
@@ -236,6 +236,7 @@ _noreturn_ static void crash(int sig) {
                 else if (pid == 0) {
                         (void) setsid();
                         (void) make_console_stdio();
+                        (void) rlimit_nofile_safe();
                         (void) execle("/bin/sh", "/bin/sh", NULL, environ);
 
                         log_emergency_errno(errno, "execle() failed: %m");
@@ -1733,6 +1734,7 @@ static void do_reexecute(
         /* Reenable any blocked signals, especially important if we switch from initial ramdisk to init=... */
         (void) reset_all_signal_handlers();
         (void) reset_signal_mask();
+        (void) rlimit_nofile_safe();
 
         if (switch_root_init) {
                 args[0] = switch_root_init;
index eae7295acb20a3f63efaef1a31ae2ee5597d599f..368a92dd38ed95b03df6868deff65e3e0a48b3bb 100644 (file)
@@ -28,6 +28,7 @@
 #include "parse-util.h"
 #include "process-util.h"
 #include "reboot-util.h"
+#include "rlimit-util.h"
 #include "signal-util.h"
 #include "string-util.h"
 #include "switch-root.h"
@@ -443,6 +444,8 @@ int main(int argc, char *argv[]) {
         arguments[2] = NULL;
         execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments, NULL);
 
+        (void) rlimit_nofile_safe();
+
         if (can_initrd) {
                 r = switch_root_initramfs();
                 if (r >= 0) {
index 995cf92ef121cbd3ddfcfd75d1af26e68abf97a7..7fc4a283ce838ff762a1a7f91ef82261739a06e3 100644 (file)
@@ -27,6 +27,7 @@
 #include "path-util.h"
 #include "proc-cmdline.h"
 #include "process-util.h"
+#include "rlimit-util.h"
 #include "signal-util.h"
 #include "socket-util.h"
 #include "special.h"
@@ -401,6 +402,8 @@ static int run(int argc, char *argv[]) {
                 cmdline[i++] = device;
                 cmdline[i++] = NULL;
 
+                (void) rlimit_nofile_safe();
+
                 execv(cmdline[0], (char**) cmdline);
                 _exit(FSCK_OPERATIONAL_ERROR);
         }
index a90693c802b83be1a936e557ea596e28897dc577..acfe3809695dc9324f42fc95ee469349d90f91ec 100644 (file)
@@ -14,6 +14,7 @@
 #include "process-util.h"
 #include "pull-common.h"
 #include "pull-job.h"
+#include "rlimit-util.h"
 #include "rm-rf.h"
 #include "signal-util.h"
 #include "siphash24.h"
@@ -472,6 +473,8 @@ int pull_verify(PullJob *main_job,
                         _exit(EXIT_FAILURE);
                 }
 
+                (void) rlimit_nofile_safe();
+
                 cmd[k++] = strjoina("--homedir=", gpg_home);
 
                 /* We add the user keyring only to the command line
index c46e0acdd369354d4a20ec64484b1d4e6d2e2614..b82d4b4a1b61e254194f5ddbfbf1793b650359a4 100644 (file)
@@ -81,6 +81,8 @@ static int spawn_child(const char* child, char** argv) {
                         _exit(EXIT_FAILURE);
                 }
 
+                (void) rlimit_nofile_safe();
+
                 execvp(child, argv);
                 log_error_errno(errno, "Failed to exec child %s: %m", child);
                 _exit(EXIT_FAILURE);
index f7485211ac60ec15c6eedef4c1dba6246fe75424..ed185131b83ae40215398b0453191cc67b2db2b4 100644 (file)
@@ -21,6 +21,7 @@
 #include "missing.h"
 #include "path-util.h"
 #include "process-util.h"
+#include "rlimit-util.h"
 #include "selinux-util.h"
 #include "signal-util.h"
 #include "stdio-util.h"
@@ -932,6 +933,8 @@ int bus_socket_exec(sd_bus *b) {
                 if (rearrange_stdio(s[1], s[1], STDERR_FILENO) < 0)
                         _exit(EXIT_FAILURE);
 
+                (void) rlimit_nofile_safe();
+
                 if (b->exec_argv)
                         execvp(b->exec_path, b->exec_argv);
                 else {
index e865d5b2a824bcc518d298d86e7748ef3bbb83bb..86fd9deec0fee11dd533d8a45589fd977639eabd 100644 (file)
@@ -12,6 +12,7 @@
 #include "mkdir.h"
 #include "nspawn-setuid.h"
 #include "process-util.h"
+#include "rlimit-util.h"
 #include "signal-util.h"
 #include "string-util.h"
 #include "strv.h"
@@ -44,6 +45,8 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
 
                 close_all_fds(NULL, 0);
 
+                (void) rlimit_nofile_safe();
+
                 execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env);
                 execle("/bin/getent", "getent", database, key, NULL, &empty_env);
                 _exit(EXIT_FAILURE);
index 10d774dfcdfbd36908abfff40295adff5ae27703..2429915f40104af7e55dbe467a100d9ac8eb2ecb 100644 (file)
@@ -16,6 +16,7 @@
 #include "hashmap.h"
 #include "macro.h"
 #include "process-util.h"
+#include "rlimit-util.h"
 #include "serialize.h"
 #include "set.h"
 #include "signal-util.h"
@@ -50,6 +51,8 @@ static int do_spawn(const char *path, char *argv[], int stdout_fd, pid_t *pid) {
                                 _exit(EXIT_FAILURE);
                 }
 
+                (void) rlimit_nofile_safe();
+
                 if (!argv) {
                         _argv[0] = (char*) path;
                         _argv[1] = NULL;
index 88d9ef349e7ee00d213d35ed60204094ddea4afc..86a394e4f8a380601e02334dd6753055f5358f51 100644 (file)
@@ -19,6 +19,7 @@
 #include "macro.h"
 #include "pager.h"
 #include "process-util.h"
+#include "rlimit-util.h"
 #include "signal-util.h"
 #include "string-util.h"
 #include "strv.h"
index 87ae4eb5d76a748a43101a91f6b91bddbdb83da1..f3e1dff4994af1a62af7fe1fa5c62875d34dc998 100644 (file)
@@ -8302,6 +8302,7 @@ static int parse_argv(int argc, char *argv[]) {
                                 /* Hmm, so some other init system is running, we need to forward this request to
                                  * it. For now we simply guess that it is Upstart. */
 
+                                (void) rlimit_nofile_safe();
                                 execv(TELINIT, argv);
 
                                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
index 840d20beac53aaf09a229bc8948fce215376da02..7bfb692a5ac133131ca1b16b9373ae0675966189 100644 (file)
@@ -20,6 +20,7 @@
 #include "netlink-util.h"
 #include "path-util.h"
 #include "process-util.h"
+#include "rlimit-util.h"
 #include "signal-util.h"
 #include "stdio-util.h"
 #include "string-util.h"
@@ -654,6 +655,7 @@ int udev_event_spawn(struct udev_event *event,
                         _exit(EXIT_FAILURE);
 
                 (void) close_all_fds(NULL, 0);
+                (void) rlimit_nofile_safe();
 
                 execve(argv[0], argv, envp);
                 _exit(EXIT_FAILURE);