From: Ivan Kruglov Date: Thu, 9 Oct 2025 13:42:35 +0000 (-0700) Subject: basic: secure_bits_to_strv() X-Git-Tag: v259-rc1~306^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3de607b48bca60d546e22d6aafb8354f93ce451e;p=thirdparty%2Fsystemd.git basic: secure_bits_to_strv() --- diff --git a/src/shared/securebits-util.c b/src/shared/securebits-util.c index 92c7415337e..783953aa604 100644 --- a/src/shared/securebits-util.c +++ b/src/shared/securebits-util.c @@ -6,30 +6,71 @@ #include "extract-word.h" #include "securebits-util.h" #include "string-util.h" +#include "strv.h" -int secure_bits_to_string_alloc(int i, char **s) { - _cleanup_free_ char *str = NULL; - size_t len; +static inline const char* secure_bit_to_string(int i) { + /* match a single bit */ + + switch (i) { + case SECURE_KEEP_CAPS: + return "keep-caps"; + case SECURE_KEEP_CAPS_LOCKED: + return "keep-caps-locked"; + case SECURE_NO_SETUID_FIXUP: + return "no-setuid-fixup"; + case SECURE_NO_SETUID_FIXUP_LOCKED: + return "no-setuid-fixup-locked"; + case SECURE_NOROOT: + return "noroot"; + case SECURE_NOROOT_LOCKED: + return "noroot-locked"; + default: + assert_not_reached(); + } +} + +int secure_bits_to_string_alloc(int i, char **ret) { + _cleanup_strv_free_ char **sv = NULL; + _cleanup_free_ char *joined = NULL; int r; - assert(s); + assert(ret); - r = asprintf(&str, "%s%s%s%s%s%s", - (i & (1 << SECURE_KEEP_CAPS)) ? "keep-caps " : "", - (i & (1 << SECURE_KEEP_CAPS_LOCKED)) ? "keep-caps-locked " : "", - (i & (1 << SECURE_NO_SETUID_FIXUP)) ? "no-setuid-fixup " : "", - (i & (1 << SECURE_NO_SETUID_FIXUP_LOCKED)) ? "no-setuid-fixup-locked " : "", - (i & (1 << SECURE_NOROOT)) ? "noroot " : "", - (i & (1 << SECURE_NOROOT_LOCKED)) ? "noroot-locked " : ""); + r = secure_bits_to_strv(i, &sv); if (r < 0) + return r; + + joined = strv_join(sv, " "); + if (!joined) return -ENOMEM; - len = strlen(str); - if (len != 0) - str[len - 1] = '\0'; + *ret = TAKE_PTR(joined); + return 0; +} + +int secure_bits_to_strv(int i, char ***ret) { + _cleanup_strv_free_ char **sv = NULL; + static const int bits[] = { + SECURE_KEEP_CAPS, + SECURE_KEEP_CAPS_LOCKED, + SECURE_NO_SETUID_FIXUP, + SECURE_NO_SETUID_FIXUP_LOCKED, + SECURE_NOROOT, + SECURE_NOROOT_LOCKED, + }; + int r; - *s = TAKE_PTR(str); + assert(ret); + + FOREACH_ELEMENT(bit, bits) { + if (i & (1 << *bit)) { + r = strv_extend(&sv, secure_bit_to_string(*bit)); + if (r < 0) + return r; + } + } + *ret = TAKE_PTR(sv); return 0; } diff --git a/src/shared/securebits-util.h b/src/shared/securebits-util.h index 19b836b4e7b..553b717a576 100644 --- a/src/shared/securebits-util.h +++ b/src/shared/securebits-util.h @@ -5,7 +5,8 @@ #include "forward.h" -int secure_bits_to_string_alloc(int i, char **s); +int secure_bits_to_strv(int i, char ***ret); +int secure_bits_to_string_alloc(int i, char **ret); int secure_bits_from_string(const char *s); static inline bool secure_bits_is_valid(int i) { diff --git a/src/test/test-secure-bits.c b/src/test/test-secure-bits.c index 37771d0ce87..d217876e2c0 100644 --- a/src/test/test-secure-bits.c +++ b/src/test/test-secure-bits.c @@ -15,20 +15,27 @@ static const char * const string_bits[] = { }; TEST(secure_bits_basic) { - _cleanup_free_ char *joined = NULL, *str = NULL; + _cleanup_free_ char *joined = NULL, *str = NULL, *joined_ssv = NULL; + _cleanup_strv_free_ char **ssv = NULL; int r; /* Check if converting each bit from string and back to string yields * the same value */ STRV_FOREACH(bit, string_bits) { _cleanup_free_ char *s = NULL; + _cleanup_strv_free_ char **sv = NULL; r = secure_bits_from_string(*bit); assert_se(r > 0); assert_se(secure_bits_is_valid(r)); + assert_se(secure_bits_to_string_alloc(r, &s) >= 0); printf("%s = 0x%x = %s\n", *bit, (unsigned)r, s); ASSERT_STREQ(*bit, s); + + ASSERT_OK(secure_bits_to_strv(r, &sv)); + ASSERT_EQ(strv_length(sv), (size_t) 1); + ASSERT_STREQ(*bit, sv[0]); } /* Ditto, but with all bits at once */ @@ -41,7 +48,12 @@ TEST(secure_bits_basic) { printf("%s = 0x%x = %s\n", joined, (unsigned)r, str); ASSERT_STREQ(joined, str); + ASSERT_OK(secure_bits_to_strv(r, &ssv)); + joined_ssv = strv_join(ssv, " "); + ASSERT_STREQ(joined, joined_ssv); + str = mfree(str); + ssv = strv_free(ssv); /* Empty string */ assert_se(secure_bits_from_string("") == 0); @@ -51,8 +63,10 @@ TEST(secure_bits_basic) { assert_se(secure_bits_from_string("foo bar baz") == 0); /* Empty secure bits */ - assert_se(secure_bits_to_string_alloc(0, &str) >= 0); - assert_se(isempty(str)); + ASSERT_OK(secure_bits_to_string_alloc(0, &str)); + ASSERT_TRUE(isempty(str)); + ASSERT_OK(secure_bits_to_strv(0, &ssv)); + ASSERT_TRUE(strv_isempty(ssv)); str = mfree(str);