diff options
author | Anita Zhang <the.anitazha@gmail.com> | 2019-06-03 16:25:43 -0700 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2019-06-20 21:46:36 +0200 |
commit | f66ad46066a9911192f0b49eb06dae7dafc0c983 (patch) | |
tree | 12f50d541691c9ee7e9e92e23e53d9966d4ad94b /src/basic/capability-util.c | |
parent | a5a4dfa1bc0078c858c250cbe6e97c0c04bf90f8 (diff) | |
download | systemd-f66ad46066a9911192f0b49eb06dae7dafc0c983.tar.gz |
nspawn: don't hard fail when setting capabilities
The OCI changes in #9762 broke a use case in which we use nspawn from
inside a container that has dropped capabilities from the bounding set
that nspawn expected to retain. In an attempt to keep OCI compliance
and support our use case, I made hard failing on setting capabilities
not in the bounding set optional (hard fail if using OCI and log only
if using nspawn cmdline).
Fixes #12539
Diffstat (limited to 'src/basic/capability-util.c')
-rw-r--r-- | src/basic/capability-util.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c index e3ed14f806..d62bb62de4 100644 --- a/src/basic/capability-util.c +++ b/src/basic/capability-util.c @@ -10,6 +10,7 @@ #include "alloc-util.h" #include "capability-util.h" +#include "cap-list.h" #include "fileio.h" #include "log.h" #include "macro.h" @@ -364,6 +365,43 @@ bool ambient_capabilities_supported(void) { return cache; } +bool capability_quintet_mangle(CapabilityQuintet *q) { + unsigned long i; + uint64_t combined, drop = 0; + bool ambient_supported; + + assert(q); + + combined = q->effective | q->bounding | q->inheritable | q->permitted; + + ambient_supported = q->ambient != (uint64_t) -1; + if (ambient_supported) + combined |= q->ambient; + + for (i = 0; i <= cap_last_cap(); i++) { + unsigned long bit = UINT64_C(1) << i; + if (!FLAGS_SET(combined, bit)) + continue; + + if (prctl(PR_CAPBSET_READ, i) > 0) + continue; + + drop |= bit; + + log_debug("Not in the current bounding set: %s", capability_to_name(i)); + } + + q->effective &= ~drop; + q->bounding &= ~drop; + q->inheritable &= ~drop; + q->permitted &= ~drop; + + if (ambient_supported) + q->ambient &= ~drop; + + return drop != 0; /* Let the caller know we changed something */ +} + int capability_quintet_enforce(const CapabilityQuintet *q) { _cleanup_cap_free_ cap_t c = NULL, modified = NULL; int r; |