From: Lennart Poettering Date: Wed, 22 Feb 2023 12:05:07 +0000 (+0100) Subject: cap-list: add capability_set_to_string_negative() X-Git-Tag: v254-rc1~1183^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=66c1e440c70345751181f335210eaf8195e958d5;p=thirdparty%2Fsystemd.git cap-list: add capability_set_to_string_negative() --- diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c index b95b9b140ee..80d48c142e3 100644 --- a/src/basic/cap-list.c +++ b/src/basic/cap-list.c @@ -103,6 +103,37 @@ int capability_set_to_string(uint64_t set, char **ret) { return 0; } +int capability_set_to_string_negative(uint64_t set, char **ret) { + _cleanup_free_ char *a = NULL, *b = NULL; + int r; + + assert(ret); + + /* Format the specified capability mask both in positive way (i.e. just listing caps) and in negative + * way (i.e. listing only caps that are missing from the full set) and return the shorter version of + * the two. */ + + r = capability_set_to_string(set, &a); + if (r < 0) + return r; + + r = capability_set_to_string(~set & all_capabilities(), &b); + if (r < 0) + return r; + + if (strlen(a) <= 1 + strlen(b)) + *ret = TAKE_PTR(a); + else { + char *c = strjoin("~", b); + if (!c) + return -ENOMEM; + + *ret = c; + } + + return 0; +} + int capability_set_to_strv(uint64_t set, char ***ret) { _cleanup_strv_free_ char **l = NULL; int r; diff --git a/src/basic/cap-list.h b/src/basic/cap-list.h index fdf4366de0e..3028197b56a 100644 --- a/src/basic/cap-list.h +++ b/src/basic/cap-list.h @@ -16,5 +16,6 @@ int capability_from_name(const char *name); int capability_list_length(void); int capability_set_to_string(uint64_t set, char **ret); +int capability_set_to_string_negative(uint64_t set, char **ret); int capability_set_to_strv(uint64_t set, char ***ret); int capability_set_from_string(const char *s, uint64_t *ret); diff --git a/src/test/test-cap-list.c b/src/test/test-cap-list.c index 42503d294c6..a9cbf695b90 100644 --- a/src/test/test-cap-list.c +++ b/src/test/test-cap-list.c @@ -7,6 +7,7 @@ #include "cap-list.h" #include "capability-util.h" #include "parse-util.h" +#include "random-util.h" #include "string-util.h" #include "strv.h" #include "tests.h" @@ -151,4 +152,26 @@ TEST(capability_set_to_string) { test_capability_set_to_string_invalid(all_capabilities() + 1); } +TEST(capability_set_to_string_negative) { + + for (unsigned i = 0; i < 150; i++) { + _cleanup_free_ char *a = NULL, *b = NULL; + + uint64_t m = + random_u64() % (UINT64_C(1) << (cap_last_cap() + 1)); + + assert_se(capability_set_to_string(m, &a) >= 0); + assert_se(capability_set_to_string_negative(m, &b) >= 0); + + printf("%s (%zu) → ", a, strlen(a)); + + if (streq(a, b)) + printf("same\n"); + else + printf("%s (%zu)\n", b, strlen(b)); + + assert_se(strlen(b) <= strlen(a)); + } +} + DEFINE_TEST_MAIN(LOG_INFO);