1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-21 18:03:41 +03:00

manager: fix error handling after failure to set up child

exec_child() is supposed to set *exit_status when returning failure.
Unfortunately, we didn't do that in two cases. The result would be:
- a bogus error message "Failed at step SUCCESS spawning foo: …",
- a bogus success exit status.

Bugs introduced in 390902012c5177b6b01bc634b2e9c704073d9e7d and
ad21e542b20f0fb292d1958d3a759bf3403522c2.

The code is reworked to add some asserts and not set exit_status in the caller
so that it's clearer (also to the compiler) that it needs to be set.

(cherry picked from commit 5fa01ac0369f0f225ab1e1f90f6b7058cc4deaaf)
(cherry picked from commit 063d67fe3255128da75d0e8ccd5afeb5c07699ff)
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2023-08-10 10:59:55 +02:00 committed by Luca Boccassi
parent c03d5f1ddb
commit 33d1a10c6d

View File

@ -4399,6 +4399,7 @@ static int exec_child(
*exit_status = EXIT_SUCCESS;
return 0;
}
*exit_status = EXIT_CONFIRM;
return log_unit_error_errno(unit, SYNTHETIC_ERRNO(ECANCELED),
"Execution cancelled by the user");
@ -4569,14 +4570,18 @@ static int exec_child(
r = set_coredump_filter(context->coredump_filter);
if (ERRNO_IS_PRIVILEGE(r))
log_unit_debug_errno(unit, r, "Failed to adjust coredump_filter, ignoring: %m");
else if (r < 0)
else if (r < 0) {
*exit_status = EXIT_LIMITS;
return log_unit_error_errno(unit, r, "Failed to adjust coredump_filter: %m");
}
}
if (context->nice_set) {
r = setpriority_closest(context->nice);
if (r < 0)
if (r < 0) {
*exit_status = EXIT_NICE;
return log_unit_error_errno(unit, r, "Failed to set up process scheduling priority (nice level): %m");
}
}
if (context->cpu_sched_set) {
@ -4941,11 +4946,11 @@ static int exec_child(
LOG_UNIT_MESSAGE(unit, "Executable %s missing, skipping: %m",
command->path),
"EXECUTABLE=%s", command->path);
*exit_status = EXIT_SUCCESS;
return 0;
}
*exit_status = EXIT_EXEC;
return log_unit_struct_errno(unit, LOG_INFO, r,
"MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
LOG_UNIT_INVOCATION_ID(unit),
@ -5412,7 +5417,7 @@ int exec_spawn(Unit *unit,
return log_unit_error_errno(unit, errno, "Failed to fork: %m");
if (pid == 0) {
int exit_status = EXIT_SUCCESS;
int exit_status;
r = exec_child(unit,
command,
@ -5430,9 +5435,8 @@ int exec_spawn(Unit *unit,
&exit_status);
if (r < 0) {
const char *status =
exit_status_to_string(exit_status,
EXIT_STATUS_LIBC | EXIT_STATUS_SYSTEMD);
const char *status = ASSERT_PTR(
exit_status_to_string(exit_status, EXIT_STATUS_LIBC | EXIT_STATUS_SYSTEMD));
log_unit_struct_errno(unit, LOG_ERR, r,
"MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
@ -5440,7 +5444,8 @@ int exec_spawn(Unit *unit,
LOG_UNIT_MESSAGE(unit, "Failed at step %s spawning %s: %m",
status, command->path),
"EXECUTABLE=%s", command->path);
}
} else
assert(exit_status == EXIT_SUCCESS);
_exit(exit_status);
}