X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fexecute.c;h=4b0767aed3151946f63653bc973503fe744e0d75;hb=8fa6cbe1a9f3f3353224116772619a4d3eb26f88;hp=0a5914759f2fae63e510bf6db3a8894293660937;hpb=d35fbf6bdf4377f3a15b084ff812b3ee272e5347;p=elogind.git diff --git a/src/core/execute.c b/src/core/execute.c index 0a5914759..4b0767aed 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -83,6 +83,8 @@ #include "af-list.h" #include "mkdir.h" #include "apparmor-util.h" +#include "bus-kernel.h" +#include "label.h" #ifdef HAVE_SECCOMP #include "seccomp-util.h" @@ -938,7 +940,7 @@ static void rename_process_from_path(const char *path) { #ifdef HAVE_SECCOMP -static int apply_seccomp(ExecContext *c) { +static int apply_seccomp(const ExecContext *c) { uint32_t negative_action, action; scmp_filter_ctx *seccomp; Iterator i; @@ -987,7 +989,7 @@ finish: return r; } -static int apply_address_families(ExecContext *c) { +static int apply_address_families(const ExecContext *c) { scmp_filter_ctx *seccomp; Iterator i; int r; @@ -1236,7 +1238,7 @@ static int exec_child(ExecCommand *command, _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL; const char *username = NULL, *home = NULL, *shell = NULL; unsigned n_dont_close = 0; - int dont_close[n_fds + 3]; + int dont_close[n_fds + 4]; uid_t uid = (uid_t) -1; gid_t gid = (gid_t) -1; int i, err; @@ -1279,6 +1281,8 @@ static int exec_child(ExecCommand *command, memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds); n_dont_close += n_fds; } + if (params->bus_endpoint_fd >= 0) + dont_close[n_dont_close++] = params->bus_endpoint_fd; if (runtime) { if (runtime->netns_storage_socket[0] >= 0) dont_close[n_dont_close++] = runtime->netns_storage_socket[0]; @@ -1428,6 +1432,18 @@ static int exec_child(ExecCommand *command, } } +#ifdef ENABLE_KDBUS + if (params->bus_endpoint_fd >= 0 && context->bus_endpoint) { + uid_t ep_uid = (uid == (uid_t) -1) ? 0 : uid; + + err = bus_kernel_set_endpoint_policy(params->bus_endpoint_fd, ep_uid, context->bus_endpoint); + if (err < 0) { + *error = EXIT_BUS_ENDPOINT; + return err; + } + } +#endif + #ifdef HAVE_PAM if (params->cgroup_path && context->user && context->pam_name) { err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0644, uid, gid); @@ -1498,6 +1514,7 @@ static int exec_child(ExecCommand *command, !strv_isempty(context->inaccessible_dirs) || context->mount_flags != 0 || (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir)) || + params->bus_endpoint_path || context->private_devices || context->protect_system != PROTECT_SYSTEM_NO || context->protect_home != PROTECT_HOME_NO) { @@ -1523,11 +1540,15 @@ static int exec_child(ExecCommand *command, context->inaccessible_dirs, tmp, var, + params->bus_endpoint_path, context->private_devices, context->protect_home, context->protect_system, context->mount_flags); - if (err < 0) { + + if (err == -EPERM) + log_warning_unit(params->unit_id, "Failed to set up file system namespace due to lack of privileges. Execution sandbox will not be in effect: %s", strerror(-err)); + else if (err < 0) { *error = EXIT_NAMESPACE; return err; } @@ -1563,7 +1584,9 @@ static int exec_child(ExecCommand *command, /* We repeat the fd closing here, to make sure that * nothing is leaked from the PAM modules. Note that * we are more aggressive this time since socket_fd - * and the netns fds we don#t need anymore. */ + * and the netns fds we don't need anymore. The custom + * endpoint fd was needed to upload the policy and can + * now be closed as well. */ err = close_all_fds(fds, n_fds); if (err >= 0) err = shift_fds(fds, n_fds); @@ -1646,11 +1669,29 @@ static int exec_child(ExecCommand *command, #endif #ifdef HAVE_SELINUX - if (context->selinux_context && use_selinux()) { - err = setexeccon(context->selinux_context); - if (err < 0 && !context->selinux_context_ignore) { - *error = EXIT_SELINUX_CONTEXT; - return err; + if (use_selinux()) { + if (context->selinux_context) { + err = setexeccon(context->selinux_context); + if (err < 0 && !context->selinux_context_ignore) { + *error = EXIT_SELINUX_CONTEXT; + return err; + } + } + + if (params->selinux_context_net && socket_fd >= 0) { + _cleanup_free_ char *label = NULL; + + err = label_get_child_mls_label(socket_fd, command->path, &label); + if (err < 0) { + *error = EXIT_SELINUX_CONTEXT; + return err; + } + + err = setexeccon(label); + if (err < 0) { + *error = EXIT_SELINUX_CONTEXT; + return err; + } } } #endif @@ -1660,7 +1701,7 @@ static int exec_child(ExecCommand *command, err = aa_change_onexec(context->apparmor_profile); if (err < 0 && !context->apparmor_profile_ignore) { *error = EXIT_APPARMOR_PROFILE; - return err; + return -errno; } } #endif @@ -1908,6 +1949,9 @@ void exec_context_done(ExecContext *c) { strv_free(c->runtime_directory); c->runtime_directory = NULL; + + bus_endpoint_free(c->bus_endpoint); + c->bus_endpoint = NULL; } int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) { @@ -2525,6 +2569,29 @@ int exec_command_set(ExecCommand *c, const char *path, ...) { return 0; } +int exec_command_append(ExecCommand *c, const char *path, ...) { + _cleanup_strv_free_ char **l = NULL; + va_list ap; + int r; + + assert(c); + assert(path); + + va_start(ap, path); + l = strv_new_ap(path, ap); + va_end(ap); + + if (!l) + return -ENOMEM; + + r = strv_extend_strv(&c->argv, l); + if (r < 0) + return r; + + return 0; +} + + static int exec_runtime_allocate(ExecRuntime **rt) { if (*rt)