diff options
author | Tobias Kaufmann <Tobias.KA.Kaufmann@bmw.de> | 2020-08-31 12:50:25 +0200 |
---|---|---|
committer | Tobias Kaufmann <Tobias.KA.Kaufmann@bmw.de> | 2020-09-01 10:53:26 +0200 |
commit | 57d4d284c95a3dfdb9a4e3f74978623cbb3f918a (patch) | |
tree | 9b158ed21db148d12b1a0c84da890362444bb05f /src/basic/capability-util.c | |
parent | Merge pull request #16885 from keszybz/rework-cache-timestamps (diff) | |
download | systemd-57d4d284c95a3dfdb9a4e3f74978623cbb3f918a.tar.xz systemd-57d4d284c95a3dfdb9a4e3f74978623cbb3f918a.zip |
capability-util: add new function for raising setpcap
Up to now the capability CAP_SETPCAP was raised implicitly in the
function capability_bounding_set_drop.
This functionality is moved into a new function
(capability_gain_cap_setpcap).
The new function optionally provides the capability set as it was
before raisining CAP_SETPCAP.
Diffstat (limited to 'src/basic/capability-util.c')
-rw-r--r-- | src/basic/capability-util.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c index 5a4d020f52..ae269e8a8a 100644 --- a/src/basic/capability-util.c +++ b/src/basic/capability-util.c @@ -161,28 +161,21 @@ int capability_ambient_set_apply(uint64_t set, bool also_inherit) { return 0; } -int capability_bounding_set_drop(uint64_t keep, bool right_now) { - _cleanup_cap_free_ cap_t before_cap = NULL, after_cap = NULL; +int capability_gain_cap_setpcap(cap_t *ret_before_caps) { + _cleanup_cap_free_ cap_t caps = NULL; cap_flag_value_t fv; - int r; - - /* If we are run as PID 1 we will lack CAP_SETPCAP by default - * in the effective set (yes, the kernel drops that when - * executing init!), so get it back temporarily so that we can - * call PR_CAPBSET_DROP. */ - - before_cap = cap_get_proc(); - if (!before_cap) + caps = cap_get_proc(); + if (!caps) return -errno; - if (cap_get_flag(before_cap, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0) + if (cap_get_flag(caps, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0) return -errno; if (fv != CAP_SET) { _cleanup_cap_free_ cap_t temp_cap = NULL; static const cap_value_t v = CAP_SETPCAP; - temp_cap = cap_dup(before_cap); + temp_cap = cap_dup(caps); if (!temp_cap) return -errno; @@ -193,8 +186,27 @@ int capability_bounding_set_drop(uint64_t keep, bool right_now) { log_debug_errno(errno, "Can't acquire effective CAP_SETPCAP bit, ignoring: %m"); /* If we didn't manage to acquire the CAP_SETPCAP bit, we continue anyway, after all this just means - * we'll fail later, when we actually intend to drop some capabilities. */ + * we'll fail later, when we actually intend to drop some capabilities or try to set securebits. */ } + if (ret_before_caps) + /* Return the capabilities as they have been before setting CAP_SETPCAP */ + *ret_before_caps = TAKE_PTR(caps); + + return 0; +} + +int capability_bounding_set_drop(uint64_t keep, bool right_now) { + _cleanup_cap_free_ cap_t before_cap = NULL, after_cap = NULL; + int r; + + /* If we are run as PID 1 we will lack CAP_SETPCAP by default + * in the effective set (yes, the kernel drops that when + * executing init!), so get it back temporarily so that we can + * call PR_CAPBSET_DROP. */ + + r = capability_gain_cap_setpcap(&before_cap); + if (r < 0) + return r; after_cap = cap_dup(before_cap); if (!after_cap) |