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
This commit is contained in:
Anita Zhang
2019-06-20 21:46:36 +02:00
committed by Lennart Poettering
parent a5a4dfa1bc
commit f66ad46066
3 changed files with 55 additions and 1 deletions
+38
View File
@@ -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;
+5
View File
@@ -69,4 +69,9 @@ static inline bool capability_quintet_is_set(const CapabilityQuintet *q) {
q->ambient != (uint64_t) -1;
}
/* Mangles the specified caps quintet taking the current bounding set into account:
* drops all caps from all five sets if our bounding set doesn't allow them.
* Returns true if the quintet was modified. */
bool capability_quintet_mangle(CapabilityQuintet *q);
int capability_quintet_enforce(const CapabilityQuintet *q);