summaryrefslogtreecommitdiffstats
path: root/src/core/main.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-01-27 15:03:27 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-02-15 11:13:26 +0100
commit1e3eee8cf0e654e101a4208b4cee7ecec65671a7 (patch)
treebcbc408305ba20b13af9bc604058d9661c8fbe17 /src/core/main.c
parentmanager: do not ignore the return value from the main loop (diff)
downloadsystemd-1e3eee8cf0e654e101a4208b4cee7ecec65671a7.tar.xz
systemd-1e3eee8cf0e654e101a4208b4cee7ecec65671a7.zip
manager: if we are reexecuting, do not invoke any fallbacks
For https://bugzilla.redhat.com/show_bug.cgi?id=1986176: if we are trying to reexecute, and this fails for any reason, we shouldn't try to execute /sbin/init or /bin/sh. It is better to just freeze. If we freeze it is easier to diagnose what happened, but if we execute one of the fallbacks, we don't really know what will happen. In particular the new init might just return, causing the machine to shut down. Or we may successfully spawn /bin/sh, which could leave the machine open.
Diffstat (limited to 'src/core/main.c')
-rw-r--r--src/core/main.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/src/core/main.c b/src/core/main.c
index ea2b9b7a52..93cbf62769 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1824,7 +1824,8 @@ static void filter_args(
}
}
-static void do_reexecute(
+static int do_reexecute(
+ ManagerObjective objective,
int argc,
char* argv[],
const struct rlimit *saved_rlimit_nofile,
@@ -1838,6 +1839,7 @@ static void do_reexecute(
const char **args;
int r;
+ assert(IN_SET(objective, MANAGER_REEXECUTE, MANAGER_SWITCH_ROOT));
assert(argc >= 0);
assert(saved_rlimit_nofile);
assert(saved_rlimit_memlock);
@@ -1901,6 +1903,12 @@ static void do_reexecute(
args[0] = SYSTEMD_BINARY_PATH;
(void) execv(args[0], (char* const*) args);
+
+ if (objective == MANAGER_REEXECUTE) {
+ *ret_error_message = "Failed to execute our own binary";
+ return log_error_errno(errno, "Failed to execute our own binary %s: %m", args[0]);
+ }
+
log_debug_errno(errno, "Failed to execute our own binary %s, trying fallback: %m", args[0]);
}
@@ -1938,17 +1946,16 @@ static void do_reexecute(
ANSI_HIGHLIGHT_RED " !! " ANSI_NORMAL,
"Failed to execute /sbin/init");
+ *ret_error_message = "Failed to execute fallback shell";
if (r == -ENOENT) {
log_warning("No /sbin/init, trying fallback");
args[0] = "/bin/sh";
args[1] = NULL;
(void) execve(args[0], (char* const*) args, saved_env);
- log_error_errno(errno, "Failed to execute /bin/sh, giving up: %m");
+ return log_error_errno(errno, "Failed to execute /bin/sh, giving up: %m");
} else
- log_warning_errno(r, "Failed to execute /sbin/init, giving up: %m");
-
- *ret_error_message = "Failed to execute fallback shell";
+ return log_warning_errno(r, "Failed to execute /sbin/init, giving up: %m");
}
static int invoke_main_loop(
@@ -3045,13 +3052,14 @@ finish:
mac_selinux_finish();
if (IN_SET(r, MANAGER_REEXECUTE, MANAGER_SWITCH_ROOT))
- do_reexecute(argc, argv,
- &saved_rlimit_nofile,
- &saved_rlimit_memlock,
- fds,
- switch_root_dir,
- switch_root_init,
- &error_message); /* This only returns if reexecution failed */
+ r = do_reexecute(r,
+ argc, argv,
+ &saved_rlimit_nofile,
+ &saved_rlimit_memlock,
+ fds,
+ switch_root_dir,
+ switch_root_init,
+ &error_message); /* This only returns if reexecution failed */
arg_serialization = safe_fclose(arg_serialization);
fds = fdset_free(fds);