.private_dev = needs_sandboxing && context->private_devices,
.private_network = needs_sandboxing && exec_needs_network_namespace(context),
.private_ipc = needs_sandboxing && exec_needs_ipc_namespace(context),
- .private_pids = needs_sandboxing && exec_needs_pid_namespace(context) ? context->private_pids : PRIVATE_PIDS_NO,
+ .private_pids = needs_sandboxing && exec_needs_pid_namespace(context, params) ? context->private_pids : PRIVATE_PIDS_NO,
.private_tmp = needs_sandboxing ? context->private_tmp : PRIVATE_TMP_NO,
.private_var_tmp = needs_sandboxing ? context->private_var_tmp : PRIVATE_TMP_NO,
LOG_EXEC_INVOCATION_ID(params));
}
-static bool exec_context_needs_cap_sys_admin(const ExecContext *context) {
+static bool exec_needs_cap_sys_admin(const ExecContext *context, const ExecParameters *params) {
assert(context);
return context->private_users != PRIVATE_USERS_NO ||
!strv_isempty(context->extension_directories) ||
context->protect_system != PROTECT_SYSTEM_NO ||
context->protect_home != PROTECT_HOME_NO ||
- exec_needs_pid_namespace(context) ||
+ exec_needs_pid_namespace(context, params) ||
context->protect_kernel_tunables ||
context->protect_kernel_modules ||
context->protect_kernel_logs ||
/* If we need unprivileged private users, we've already unshared a user namespace by the time we call
* setup_delegated_namespaces() for the first time so let's make sure we do all other namespace
* unsharing in the first call to setup_delegated_namespaces() by returning false here. */
- if (!have_cap_sys_admin && exec_context_needs_cap_sys_admin(context))
+ if (!have_cap_sys_admin && exec_needs_cap_sys_admin(context, params))
return false;
if (context->delegate_namespaces == NAMESPACE_FLAGS_INITIAL)
/* Unshare a new PID namespace before setting up mounts to ensure /proc/ is mounted with only processes in PID namespace visible.
* Note PrivatePIDs=yes implies MountAPIVFS=yes so we'll always ensure procfs is remounted. */
- if (needs_sandboxing && exec_needs_pid_namespace(context) &&
+ if (needs_sandboxing && exec_needs_pid_namespace(context, params) &&
exec_namespace_is_delegated(context, params, have_cap_sys_admin, CLONE_NEWPID) == delegate) {
if (params->pidref_transport_fd < 0) {
*reterr_exit_status = EXIT_NAMESPACE;
}
}
- if (needs_sandboxing && !have_cap_sys_admin && exec_context_needs_cap_sys_admin(context)) {
+ if (needs_sandboxing && !have_cap_sys_admin && exec_needs_cap_sys_admin(context, params)) {
/* If we're unprivileged, set up the user namespace first to enable use of the other namespaces.
* Users with CAP_SYS_ADMIN can set up user namespaces last because they will be able to
* set up all of the other namespaces (i.e. network, mount, UTS) without a user namespace. */
return IN_SET(exec_get_protect_control_groups(context), PROTECT_CONTROL_GROUPS_YES, PROTECT_CONTROL_GROUPS_STRICT);
}
-bool exec_needs_pid_namespace(const ExecContext *context) {
+bool exec_needs_pid_namespace(const ExecContext *context, const ExecParameters *params) {
assert(context);
+ /* PID namespaces don't really make sense for control processes so let's not use them for those. */
+ if (params && FLAGS_SET(params->flags, EXEC_IS_CONTROL))
+ return false;
+
return context->private_pids != PRIVATE_PIDS_NO && namespace_type_supported(NAMESPACE_PID);
}
context->protect_proc != PROTECT_PROC_DEFAULT ||
context->proc_subset != PROC_SUBSET_ALL ||
exec_needs_ipc_namespace(context) ||
- exec_needs_pid_namespace(context))
+ exec_needs_pid_namespace(context, params))
return true;
if (context->root_directory) {
bool exec_needs_mount_namespace(const ExecContext *context, const ExecParameters *params, const ExecRuntime *runtime);
bool exec_needs_network_namespace(const ExecContext *context);
bool exec_needs_ipc_namespace(const ExecContext *context);
-bool exec_needs_pid_namespace(const ExecContext *context);
+bool exec_needs_pid_namespace(const ExecContext *context, const ExecParameters *params);
ProtectControlGroups exec_get_protect_control_groups(const ExecContext *context);
bool exec_needs_cgroup_namespace(const ExecContext *context);
if (s->type == SERVICE_DBUS && !s->bus_name)
return log_unit_error_errno(UNIT(s), SYNTHETIC_ERRNO(ENOEXEC), "Service is of type D-Bus but no D-Bus service name has been specified. Refusing.");
- if (s->type == SERVICE_FORKING && exec_needs_pid_namespace(&s->exec_context))
+ if (s->type == SERVICE_FORKING && exec_needs_pid_namespace(&s->exec_context, /* params= */ NULL))
return log_unit_error_errno(UNIT(s), SYNTHETIC_ERRNO(ENOEXEC), "Service of Type=forking does not support PrivatePIDs=yes. Refusing.");
if (s->usb_function_descriptors && !s->usb_function_strings)
exec_needs_mount_namespace(ec, /* params = */ NULL, /* runtime = */ NULL))
return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOEXEC), "WorkingDirectory= may not be below /proc/, /sys/ or /dev/ when using mount namespacing. Refusing.");
- if (exec_needs_pid_namespace(ec) && !UNIT_VTABLE(u)->notify_pidref)
+ if (exec_needs_pid_namespace(ec, /* params= */ NULL) && !UNIT_VTABLE(u)->notify_pidref)
return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOEXEC), "PrivatePIDs= setting is only supported for service units. Refusing.");
const KillContext *kc = unit_get_kill_context(u);