From 0e06a03165bdec49c79d12043e690d8f3a672812 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 1 Nov 2019 11:26:05 +0100 Subject: pid1: rework environment block copy logic This reworks the logic introduced in a5cede8c24fddda9b73f142e09b18b49adde1b9c (#13693). First of all, let's move this out of util.c, since only PID 1 really needs this, and there's no real need to have it in util.c. Then, fix freeing of the variable. It previously relied on STATIC_DESTRUCTOR_REGISTER() which however relies on static_destruct() to be called explicitly. Currently only the main-func.h macros do that, and PID 1 does not. (It might be worth investigating whether to do that, but it's not trivial.) Hence the freeing wasn't applied. Finally, an OOM check was missing, add it in. --- src/basic/util.c | 8 -------- src/basic/util.h | 3 --- src/core/main.c | 26 +++++++++++++++++++++++--- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/basic/util.c b/src/basic/util.c index b02471c483..f74ed95a60 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -38,7 +38,6 @@ #include "set.h" #include "signal-util.h" #include "stat-util.h" -#include "static-destruct.h" #include "string-util.h" #include "strv.h" #include "time-util.h" @@ -49,11 +48,8 @@ int saved_argc = 0; char **saved_argv = NULL; -char **saved_env = NULL; static int saved_in_initrd = -1; -STATIC_DESTRUCTOR_REGISTER(saved_env, strv_freep); - bool kexec_loaded(void) { _cleanup_free_ char *s = NULL; @@ -301,7 +297,3 @@ void disable_coredumps(void) { if (r < 0) log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m"); } - -void save_env(void) { - saved_env = strv_copy(environ); -} diff --git a/src/basic/util.h b/src/basic/util.h index 15444b2e5c..6fc7480fcb 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -13,9 +13,6 @@ static inline void save_argc_argv(int argc, char **argv) { saved_argv = argv; } -extern char **saved_env; -void save_env(void); - bool kexec_loaded(void); int prot_from_flags(int flags) _const_; diff --git a/src/core/main.c b/src/core/main.c index 7c814f3237..3545fde71d 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -146,6 +146,9 @@ static OOMPolicy arg_default_oom_policy; static CPUSet arg_cpu_affinity; static NUMAPolicy arg_numa_policy; +/* A copy of the original environment block */ +static char **saved_env = NULL; + static int parse_configuration(const struct rlimit *saved_rlimit_nofile, const struct rlimit *saved_rlimit_memlock); @@ -2353,6 +2356,17 @@ static bool early_skip_setup_check(int argc, char *argv[]) { return found_deserialize; /* When we are deserializing, then we are reexecuting, hence avoid the extensive setup */ } +static int save_env(void) { + char **l; + + l = strv_copy(environ); + if (!l) + return -ENOMEM; + + strv_free_and_replace(saved_env, l); + return 0; +} + int main(int argc, char *argv[]) { dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL, userspace_timestamp = DUAL_TIMESTAMP_NULL, kernel_timestamp = DUAL_TIMESTAMP_NULL, @@ -2391,9 +2405,13 @@ int main(int argc, char *argv[]) { /* Save the original command line */ save_argc_argv(argc, argv); - /* Save the original environment as we might need to restore it if we're requested to - * execute another system manager later. */ - save_env(); + /* Save the original environment as we might need to restore it if we're requested to execute another + * system manager later. */ + r = save_env(); + if (r < 0) { + error_message = "Failed to copy environment block"; + goto finish; + } /* Make sure that if the user says "syslog" we actually log to the journal. */ log_set_upgrade_syslog_to_journal(true); @@ -2681,6 +2699,8 @@ finish: arg_serialization = safe_fclose(arg_serialization); fds = fdset_free(fds); + saved_env = strv_free(saved_env); + #if HAVE_VALGRIND_VALGRIND_H /* If we are PID 1 and running under valgrind, then let's exit * here explicitly. valgrind will only generate nice output on -- cgit v1.2.1 From dfaf16ebed8b5be645c645623f1593db5f5d0ba0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 1 Nov 2019 11:31:20 +0100 Subject: static-destruct: add missing closing '(' in comment --- src/basic/static-destruct.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/basic/static-destruct.h b/src/basic/static-destruct.h index 443c0e8ebb..8fbc07c587 100644 --- a/src/basic/static-destruct.h +++ b/src/basic/static-destruct.h @@ -40,8 +40,8 @@ typedef struct StaticDestructor { extern const struct StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT[]; extern const struct StaticDestructor _weak_ __stop_SYSTEMD_STATIC_DESTRUCT[]; -/* The function to destroy everything. (Note that this must be static inline, as it's key that it remains in the same - * linking unit as the variables we want to destroy. */ +/* The function to destroy everything. (Note that this must be static inline, as it's key that it remains in + * the same linking unit as the variables we want to destroy.) */ static inline void static_destruct(void) { const StaticDestructor *d; -- cgit v1.2.1