From 595225af7a4f663788d26b8720e994fed71f9410 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 26 Nov 2018 16:06:26 +0100 Subject: [PATCH] tree-wide: invoke rlimit_nofile_safe() before various exec{v,ve,l}() invocations 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. --- src/basic/process-util.c | 2 ++ src/core/main.c | 2 ++ src/core/shutdown.c | 3 +++ src/fsck/fsck.c | 3 +++ src/import/pull-common.c | 3 +++ src/journal-remote/journal-remote-main.c | 2 ++ src/libsystemd/sd-bus/bus-socket.c | 3 +++ src/nspawn/nspawn-setuid.c | 3 +++ src/shared/exec-util.c | 3 +++ src/shared/pager.c | 1 + src/systemctl/systemctl.c | 1 + src/udev/udev-event.c | 2 ++ 12 files changed, 28 insertions(+) diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 5cf4e37f242..e69566c8a42 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -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++) diff --git a/src/core/main.c b/src/core/main.c index 6d03b066847..839dc062ff7 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -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; diff --git a/src/core/shutdown.c b/src/core/shutdown.c index eae7295acb2..368a92dd38e 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -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) { diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 995cf92ef12..7fc4a283ce8 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -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); } diff --git a/src/import/pull-common.c b/src/import/pull-common.c index a90693c802b..acfe3809695 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -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 diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c index c46e0acdd36..b82d4b4a1b6 100644 --- a/src/journal-remote/journal-remote-main.c +++ b/src/journal-remote/journal-remote-main.c @@ -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); diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index f7485211ac6..ed185131b83 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -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 { diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c index e865d5b2a82..86fd9deec0f 100644 --- a/src/nspawn/nspawn-setuid.c +++ b/src/nspawn/nspawn-setuid.c @@ -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); diff --git a/src/shared/exec-util.c b/src/shared/exec-util.c index 10d774dfcdf..2429915f401 100644 --- a/src/shared/exec-util.c +++ b/src/shared/exec-util.c @@ -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; diff --git a/src/shared/pager.c b/src/shared/pager.c index 88d9ef349e7..86a394e4f8a 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -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" diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 87ae4eb5d76..f3e1dff4994 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -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), diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 840d20beac5..7bfb692a5ac 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -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); -- 2.39.2