Merge pull request #32937 from steelman/github/drop-ambient-caps-executor

core: drop ambient capabilities in systemd-executor
This commit is contained in:
Luca Boccassi
2024-07-31 16:11:30 +02:00
committed by GitHub
5 changed files with 44 additions and 6 deletions
+1 -1
View File
@@ -5041,7 +5041,7 @@ int exec_invoke(
*
* The requested ambient capabilities are raised in the inheritable set if the second
* argument is true. */
if (!needs_ambient_hack) {
if (!needs_ambient_hack && capability_ambient_set != 0) {
r = capability_ambient_set_apply(capability_ambient_set, /* also_inherit= */ true);
if (r < 0) {
*exit_status = EXIT_CAPABILITIES;
+10
View File
@@ -467,6 +467,12 @@ int exec_spawn(
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
dual_timestamp start_timestamp;
/* Restore the original ambient capability set the manager was started with to pass it to
* sd-executor. */
r = capability_ambient_set_apply(unit->manager->original_ambient_set, /* also_inherit= */ false);
if (r < 0)
return log_unit_error_errno(unit, r, "Failed to apply the starting ambient set: %m");
/* Record the start timestamp before we fork so that it is guaranteed to be earlier than the
* handoff timestamp. */
dual_timestamp_now(&start_timestamp);
@@ -481,6 +487,10 @@ int exec_spawn(
environ,
cg_unified() > 0 ? subcgroup_path : NULL,
&pidref);
/* Drop the ambient set again, so no processes other than sd-executore spawned from the manager inherit it. */
(void) capability_ambient_set_apply(0, /* also_inherit= */ false);
if (r == -EUCLEAN && subcgroup_path)
return log_unit_error_errno(unit, r,
"Failed to spawn process into cgroup '%s', because the cgroup "
+6
View File
@@ -8,6 +8,7 @@
#include "alloc-util.h"
#include "argv-util.h"
#include "build.h"
#include "capability-util.h"
#include "exec-invoke.h"
#include "execute-serialize.h"
#include "execute.h"
@@ -206,6 +207,11 @@ static int run(int argc, char *argv[]) {
log_set_prohibit_ipc(false);
log_open();
/* Clear ambient capabilities, so services do not inherit them implicitly. Dropping them does
* not affect the permitted and effective sets which are important for the executor itself to
* operate. */
capability_ambient_set_apply(0, /* also_inherit= */ false);
/* This call would collect all passed fds and enable CLOEXEC. We'll unset it in exec_invoke (flag_fds)
* for fds that shall be passed to the child.
* The serialization fd is set to CLOEXEC in parse_argv, so it's also filtered. */
+24 -5
View File
@@ -1937,6 +1937,7 @@ static int do_reexecute(
FDSet *fds,
const char *switch_root_dir,
const char *switch_root_init,
uint64_t capability_ambient_set,
const char **ret_error_message) {
size_t i, args_size;
@@ -1998,6 +1999,10 @@ static int do_reexecute(
log_error_errno(r, "Failed to switch root, trying to continue: %m");
}
r = capability_ambient_set_apply(capability_ambient_set, /* also_inherit= */ false);
if (r < 0)
log_error_errno(r, "Failed to apply the starting ambient set, ignoring: %m.");
args_size = argc + 5;
args = newa(const char*, args_size);
@@ -2373,6 +2378,7 @@ static int initialize_runtime(
bool first_boot,
struct rlimit *saved_rlimit_nofile,
struct rlimit *saved_rlimit_memlock,
uint64_t *original_ambient_set,
const char **ret_error_message) {
int r;
@@ -2487,11 +2493,6 @@ static int initialize_runtime(
log_warning_errno(r, "Failed to copy os-release for propagation, ignoring: %m");
}
/* Clear ambient capabilities, so services do not inherit them implicitly. Dropping them does
* not affect the permitted and effective sets which are important for the manager itself to
* operate. */
(void) capability_ambient_set_apply(0, /* also_inherit= */ false);
break;
}
@@ -2499,6 +2500,19 @@ static int initialize_runtime(
assert_not_reached();
}
/* The two operations on the ambient set are meant for a user serssion manager. They do not affect
* system manager operation, because by default it starts with an empty ambient set.
*
* Preserve the ambient set for later use with sd-executor processes. */
r = capability_get_ambient(original_ambient_set);
if (r < 0)
log_error_errno(r, "Failed to save ambient capabilities, ignoring: %m.");
/* Clear ambient capabilities, so services do not inherit them implicitly. Dropping them does
* not affect the permitted and effective sets which are important for the manager itself to
* operate. */
(void) capability_ambient_set_apply(0, /* also_inherit= */ false);
if (arg_timer_slack_nsec != NSEC_INFINITY)
if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
log_warning_errno(errno, "Failed to adjust timer slack, ignoring: %m");
@@ -2995,6 +3009,7 @@ int main(int argc, char *argv[]) {
usec_t before_startup, after_startup;
static char systemd[] = "systemd";
const char *error_message = NULL;
uint64_t original_ambient_set;
int r, retval = EXIT_FAILURE;
Manager *m = NULL;
FDSet *fds = NULL;
@@ -3269,6 +3284,7 @@ int main(int argc, char *argv[]) {
first_boot,
&saved_rlimit_nofile,
&saved_rlimit_memlock,
&original_ambient_set,
&error_message);
if (r < 0)
goto finish;
@@ -3290,6 +3306,8 @@ int main(int argc, char *argv[]) {
m->timestamps[manager_timestamp_initrd_mangle(MANAGER_TIMESTAMP_SECURITY_START)] = security_start_timestamp;
m->timestamps[manager_timestamp_initrd_mangle(MANAGER_TIMESTAMP_SECURITY_FINISH)] = security_finish_timestamp;
m->original_ambient_set = original_ambient_set;
set_manager_defaults(m);
set_manager_settings(m);
manager_set_first_boot(m, first_boot);
@@ -3365,6 +3383,7 @@ finish:
fds,
switch_root_dir,
switch_root_init,
original_ambient_set,
&error_message); /* This only returns if reexecution failed */
arg_serialization = safe_fclose(arg_serialization);
+3
View File
@@ -511,6 +511,9 @@ struct Manager {
int executor_fd;
unsigned soft_reboots_count;
/* Original ambient capabilities when we were initialized */
uint64_t original_ambient_set;
};
static inline usec_t manager_default_timeout_abort_usec(Manager *m) {