diff --git a/src/core/execute.c b/src/core/execute.c index f493accf2e..4274d39285 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1077,26 +1077,42 @@ static int enforce_groups(gid_t gid, const gid_t *supplementary_gids, int ngids) return 0; } +static int set_securebits(int bits, int mask) { + int current, applied; + current = prctl(PR_GET_SECUREBITS); + if (current < 0) + return -errno; + /* Clear all securebits defined in mask and set bits */ + applied = (current & ~mask) | bits; + if (current == applied) + return 0; + if (prctl(PR_SET_SECUREBITS, applied) < 0) + return -errno; + return 1; +} + static int enforce_user(const ExecContext *context, uid_t uid) { assert(context); + int r; if (!uid_is_valid(uid)) return 0; /* Sets (but doesn't look up) the uid and make sure we keep the - * capabilities while doing so. */ + * capabilities while doing so. For setting secure bits the capability CAP_SETPCAP is + * required, so we also need keep-caps in this case. + */ - if (context->capability_ambient_set != 0) { + if (context->capability_ambient_set != 0 || context->secure_bits != 0) { /* First step: If we need to keep capabilities but * drop privileges we need to make sure we keep our * caps, while we drop privileges. */ if (uid != 0) { - int sb = context->secure_bits | 1<