Skip to content

Commit

Permalink
linux: ignore unknown capabilities
Browse files Browse the repository at this point in the history
opencontainers/runtime-spec#1094 introduced a
change where unknown capabilities must be ignored.  The runtime MUST
log a warning instead of failing with an error.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
  • Loading branch information
giuseppe committed Mar 29, 2021
1 parent 496e81b commit 78aeac9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 24 deletions.
33 changes: 10 additions & 23 deletions src/libcrun/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -2387,15 +2387,18 @@ set_required_caps (struct all_caps_s *caps, uid_t uid, gid_t gid, int no_new_pri
}

static int
read_caps (unsigned long caps[2], char **values, size_t len, libcrun_error_t *err)
read_caps (unsigned long caps[2], char **values, size_t len)
{
#ifdef HAVE_CAP
size_t i;
for (i = 0; i < len; i++)
{
cap_value_t cap;
if (cap_from_name (values[i], &cap) < 0)
return crun_make_error (err, 0, "unknown cap: `%s`", values[i]);
{
libcrun_warning ("unknown cap: `%s`", values[i]);
continue;
}
if (cap < 32)
caps[0] |= CAP_TO_MASK_0 (cap);
else
Expand Down Expand Up @@ -2429,32 +2432,16 @@ int
libcrun_set_caps (runtime_spec_schema_config_schema_process_capabilities *capabilities, uid_t uid, gid_t gid,
int no_new_privileges, libcrun_error_t *err)
{
int ret;
struct all_caps_s caps = {};

if (capabilities)
{
ret = read_caps (caps.effective, capabilities->effective, capabilities->effective_len, err);
if (ret < 0)
return ret;

ret = read_caps (caps.inheritable, capabilities->inheritable, capabilities->inheritable_len, err);
if (ret < 0)
return ret;

ret = read_caps (caps.ambient, capabilities->ambient, capabilities->ambient_len, err);
if (ret < 0)
return ret;

ret = read_caps (caps.bounding, capabilities->bounding, capabilities->bounding_len, err);
if (ret < 0)
return ret;

ret = read_caps (caps.permitted, capabilities->permitted, capabilities->permitted_len, err);
if (ret < 0)
return ret;
read_caps (caps.effective, capabilities->effective, capabilities->effective_len);
read_caps (caps.inheritable, capabilities->inheritable, capabilities->inheritable_len);
read_caps (caps.ambient, capabilities->ambient, capabilities->ambient_len);
read_caps (caps.bounding, capabilities->bounding, capabilities->bounding_len);
read_caps (caps.permitted, capabilities->permitted, capabilities->permitted_len);
}

return set_required_caps (&caps, uid, gid, no_new_privileges, err);
}

Expand Down
19 changes: 18 additions & 1 deletion tests/test_capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@ def test_some_caps():
return -1
return 0

def test_unknown_caps():
conf = base_config()
conf['process']['args'] = ['/init', 'cat', '/proc/self/status']
add_all_namespaces(conf)
conf['process']['capabilities'] = {}
# unknown caps must be ignored
for i in ['bounding', 'effective', 'inheritable', 'permitted', 'ambient']:
conf['process']['capabilities'][i] = ['CAP_UNKNOWN', 'UNKNOWN_CAP']
out, _ = run_and_get_output(conf)
proc_status = parse_proc_status(out)

for i in ['CapInh', 'CapPrm', 'CapEff', 'CapBnd', 'CapAmb']:
if proc_status[i] != "0000000000000000":
return -1
return 0

def test_new_privs():
conf = base_config()
conf['process']['args'] = ['/init', 'cat', '/proc/self/status']
Expand Down Expand Up @@ -136,7 +152,8 @@ def test_some_caps_permitted_non_root():
"some-caps-bounding-non-root" : test_some_caps_bounding_non_root,
"some-caps-inheritable-non-root" : test_some_caps_inheritable_non_root,
"some-caps-ambient-non-root" : test_some_caps_ambient_non_root,
"some-caps-permitted-non-root" : test_some_caps_permitted_non_root
"some-caps-permitted-non-root" : test_some_caps_permitted_non_root,
"unknown-caps" : test_unknown_caps,
}

if __name__ == "__main__":
Expand Down

0 comments on commit 78aeac9

Please sign in to comment.