X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=execute.c;h=dd36038c4a98a743c084851084ad3def50d2bc39;hb=24e61ac49db6add10ffa448f42202245fb883b96;hp=bdb0f921794ddb612f821861a0087e15aa3474d7;hpb=81a2b7ceda7100fbc0dd8ce423b9599e03656851;p=elogind.git diff --git a/execute.c b/execute.c index bdb0f9217..dd36038c4 100644 --- a/execute.c +++ b/execute.c @@ -42,6 +42,7 @@ #include "log.h" #include "ioprio.h" #include "securebits.h" +#include "cgroup.h" static int close_fds(int except[], unsigned n_except) { DIR *d; @@ -461,9 +462,13 @@ static int enforce_user(const ExecContext *context, uid_t uid) { /* First step: If we need to keep capabilities but * drop privileges we need to make sure we keep our * caps, whiel we drop priviliges. */ - if (uid != 0) - if (prctl(PR_SET_SECUREBITS, context->secure_bits|SECURE_KEEP_CAPS) < 0) - return -errno; + if (uid != 0) { + int sb = context->secure_bits|SECURE_KEEP_CAPS; + + if (prctl(PR_GET_SECUREBITS) != sb) + if (prctl(PR_SET_SECUREBITS, sb) < 0) + return -errno; + } /* Second step: set the capabilites. This will reduce * the capabilities to the minimum we need. */ @@ -504,9 +509,11 @@ int exec_spawn(const ExecCommand *command, int *fds, unsigned n_fds, bool apply_permissions, bool apply_chroot, + CGroupBonding *cgroup_bondings, pid_t *ret) { pid_t pid; + int r; assert(command); assert(context); @@ -515,11 +522,15 @@ int exec_spawn(const ExecCommand *command, log_debug("About to execute %s", command->path); + if (cgroup_bondings) + if ((r = cgroup_bonding_realize_list(cgroup_bondings))) + return r; + if ((pid = fork()) < 0) return -errno; if (pid == 0) { - int i, r; + int i; sigset_t ss; const char *username = NULL, *home = NULL; uid_t uid = (uid_t) -1; @@ -552,6 +563,12 @@ int exec_spawn(const ExecCommand *command, goto fail; } + if (cgroup_bondings) + if ((r = cgroup_bonding_install_list(cgroup_bondings, 0)) < 0) { + r = EXIT_CGROUP; + goto fail; + } + if (context->oom_adjust_set) { char t[16]; @@ -671,10 +688,15 @@ int exec_spawn(const ExecCommand *command, goto fail; } - if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) { - r = EXIT_SECUREBITS; - goto fail; - } + /* PR_GET_SECUREBITS is not priviliged, while + * PR_SET_SECUREBITS is. So to suppress + * potential EPERMs we'll try not to call + * PR_SET_SECUREBITS unless necessary. */ + if (prctl(PR_GET_SECUREBITS) != context->secure_bits) + if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) { + r = EXIT_SECUREBITS; + goto fail; + } if (context->capabilities) if (cap_set_proc(context->capabilities) < 0) {