From: Yu Watanabe Date: Mon, 7 Aug 2017 14:25:11 +0000 (+0900) Subject: cap-list: add capability_set_{from_string,to_string_alloc}() X-Git-Tag: v235~248^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dd1f5bd0aa584c5e5e10fddc735155c3501eb21e;p=thirdparty%2Fsystemd.git cap-list: add capability_set_{from_string,to_string_alloc}() --- diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c index d68cc78d05e..124641f940b 100644 --- a/src/basic/cap-list.c +++ b/src/basic/cap-list.c @@ -20,7 +20,10 @@ #include #include +#include "alloc-util.h" +#include "capability-util.h" #include "cap-list.h" +#include "extract-word.h" #include "macro.h" #include "missing.h" #include "parse-util.h" @@ -64,3 +67,65 @@ int capability_from_name(const char *name) { int capability_list_length(void) { return (int) ELEMENTSOF(capability_names); } + +int capability_set_to_string_alloc(uint64_t set, char **s) { + _cleanup_free_ char *str = NULL; + unsigned long i; + size_t allocated = 0, n = 0; + + assert(s); + + for (i = 0; i < cap_last_cap(); i++) + if (set & (UINT64_C(1) << i)) { + const char *p; + size_t add; + + p = capability_to_name(i); + if (!p) + return -EINVAL; + + add = strlen(p); + + if (!GREEDY_REALLOC0(str, allocated, n + add + 2)) + return -ENOMEM; + + strcpy(mempcpy(str + n, p, add), " "); + n += add + 1; + } + + if (n != 0) + str[n - 1] = '\0'; + + *s = str; + str = NULL; + + return 0; +} + +int capability_set_from_string(const char *s, uint64_t *set) { + uint64_t val = 0; + const char *p; + + assert(set); + + for (p = s;;) { + _cleanup_free_ char *word = NULL; + int r; + + r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); + if (r == -ENOMEM) + return r; + if (r <= 0) + break; + + r = capability_from_name(word); + if (r < 0) + continue; + + val |= ((uint64_t) UINT64_C(1)) << (uint64_t) r; + } + + *set = val; + + return 0; +} diff --git a/src/basic/cap-list.h b/src/basic/cap-list.h index c1f6b94ad32..f9f6b70d80a 100644 --- a/src/basic/cap-list.h +++ b/src/basic/cap-list.h @@ -22,3 +22,6 @@ const char *capability_to_name(int id); int capability_from_name(const char *name); int capability_list_length(void); + +int capability_set_to_string_alloc(uint64_t set, char **s); +int capability_set_from_string(const char *s, uint64_t *set); diff --git a/src/core/execute.c b/src/core/execute.c index 3b10fa13657..ca179426d68 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -3610,25 +3610,19 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { (c->secure_bits & 1<capability_bounding_set != CAP_ALL) { - unsigned long l; - fprintf(f, "%sCapabilityBoundingSet:", prefix); + _cleanup_free_ char *str = NULL; - for (l = 0; l <= cap_last_cap(); l++) - if (c->capability_bounding_set & (UINT64_C(1) << l)) - fprintf(f, " %s", strna(capability_to_name(l))); - - fputs("\n", f); + r = capability_set_to_string_alloc(c->capability_bounding_set, &str); + if (r >= 0) + fprintf(f, "%sCapabilityBoundingSet: %s\n", prefix, str); } if (c->capability_ambient_set != 0) { - unsigned long l; - fprintf(f, "%sAmbientCapabilities:", prefix); + _cleanup_free_ char *str = NULL; - for (l = 0; l <= cap_last_cap(); l++) - if (c->capability_ambient_set & (UINT64_C(1) << l)) - fprintf(f, " %s", strna(capability_to_name(l))); - - fputs("\n", f); + r = capability_set_to_string_alloc(c->capability_ambient_set, &str); + if (r >= 0) + fprintf(f, "%sAmbientCapabilities: %s\n", prefix, str); } if (c->user) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index ac946561dc2..63144c4efce 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1157,7 +1157,7 @@ int config_parse_capability_set( uint64_t *capability_set = data; uint64_t sum = 0, initial = 0; bool invert = false; - const char *p; + int r; assert(filename); assert(lvalue); @@ -1173,28 +1173,12 @@ int config_parse_capability_set( initial = CAP_ALL; /* initialized to all bits on */ /* else "AmbientCapabilities" initialized to all bits off */ - p = rvalue; - for (;;) { - _cleanup_free_ char *word = NULL; - int cap, r; - - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); - if (r == 0) - break; - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse word, ignoring: %s", rvalue); - break; - } - - cap = capability_from_name(word); - if (cap < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse capability in bounding/ambient set, ignoring: %s", word); - continue; - } - - sum |= ((uint64_t) UINT64_C(1)) << (uint64_t) cap; + r = capability_set_from_string(rvalue, &sum); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse word: %s", rvalue); + return 0; } sum = invert ? ~sum : sum;