minijail: Allow setting a cap_from_text(3)-compliant string to -c
This change allows callers of minijail0 use a human-friendly string as
argument to the -c flag. This avoids having to add comments explaining
what the cryptic hex constant means.
Bug: None
Test: # ./minijail0 -T static --ambient \
-c 'cap_dac_read_search,cap_dac_override+e' -- \
/bin/grep Cap /proc/self/status
CapInh: 0000000000000006
CapPrm: 0000000000000006
CapEff: 0000000000000006
CapBnd: 0000000000000006
CapAmb: 0000000000000006
Test: # ./minijail0 -T static -- /bin/grep Cap /proc/self/status
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
Change-Id: I2e352178ab479859d999d936bbc7eb3ed6f370ff
diff --git a/minijail0_cli.c b/minijail0_cli.c
index a1ee82b..ea66d7c 100644
--- a/minijail0_cli.c
+++ b/minijail0_cli.c
@@ -82,13 +82,37 @@
static void use_caps(struct minijail *j, const char *arg)
{
- uint64_t caps;
- char *end = NULL;
- caps = strtoull(arg, &end, 16);
- if (*end) {
- fprintf(stderr, "Invalid cap set: '%s'\n", arg);
- exit(1);
+ uint64_t caps = 0;
+ cap_t parsed_caps = cap_from_text(arg);
+
+ if (parsed_caps != NULL) {
+ unsigned int i;
+ const uint64_t one = 1;
+ cap_flag_value_t cap_value;
+ unsigned int last_valid_cap = get_last_valid_cap();
+
+ for (i = 0; i <= last_valid_cap; ++i) {
+ if (cap_get_flag(parsed_caps, i, CAP_EFFECTIVE,
+ &cap_value)) {
+ fprintf(stderr,
+ "Could not get the value of "
+ "the %d-th capability: %m\n",
+ i);
+ exit(1);
+ }
+ if (cap_value == CAP_SET)
+ caps |= (one << i);
+ }
+ cap_free(parsed_caps);
+ } else {
+ char *end = NULL;
+ caps = strtoull(arg, &end, 16);
+ if (*end) {
+ fprintf(stderr, "Invalid cap set: '%s'\n", arg);
+ exit(1);
+ }
}
+
minijail_use_caps(j, caps);
}