From: Lennart Poettering Date: Mon, 20 Feb 2023 11:26:46 +0000 (+0100) Subject: cap-list: refuse parsing numeric capability 63 X-Git-Tag: v254-rc1~1228^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d0e67c69ba7fa9984a2d96caa8ad4b7762ed3160;p=thirdparty%2Fsystemd.git cap-list: refuse parsing numeric capability 63 We refuse it otherwise currently, simply because we cannot store it in a uint64_t caps mask value anymore while retaining the ability to use UINT64_MAX as "unset" marker. The check actually was in place already, just one off. --- diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c index 0af37b94ee9..bcf7e597c2d 100644 --- a/src/basic/cap-list.c +++ b/src/basic/cap-list.c @@ -35,10 +35,10 @@ int capability_from_name(const char *name) { /* Try to parse numeric capability */ r = safe_atoi(name, &i); if (r >= 0) { - if (i >= 0 && i < 64) - return i; - else + if (i < 0 || i >= 63) return -EINVAL; + + return i; } /* Try to parse string capability */ diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c index 5ab110d3417..13aa6fee438 100644 --- a/src/basic/capability-util.c +++ b/src/basic/capability-util.c @@ -47,11 +47,11 @@ unsigned cap_last_cap(void) { r = safe_atolu(content, &p); if (r >= 0) { - if (p > 63) /* Safety for the future: if one day the kernel learns more than 64 caps, + if (p > 62) /* Safety for the future: if one day the kernel learns more than 64 caps, * then we are in trouble (since we, as much userspace and kernel space * store capability masks in uint64_t types). Let's hence protect * ourselves against that and always cap at 63 for now. */ - p = 63; + p = 62; saved = p; valid = true; @@ -60,7 +60,7 @@ unsigned cap_last_cap(void) { } /* fall back to syscall-probing for pre linux-3.2 */ - p = MIN((unsigned long) CAP_LAST_CAP, 63U); + p = MIN((unsigned long) CAP_LAST_CAP, 62U); if (prctl(PR_CAPBSET_READ, p) < 0) { @@ -72,7 +72,7 @@ unsigned cap_last_cap(void) { } else { /* Hmm, look upwards, until we find one that doesn't work */ - for (; p < 63; p++) + for (; p < 62; p++) if (prctl(PR_CAPBSET_READ, p+1) < 0) break; } diff --git a/src/test/test-cap-list.c b/src/test/test-cap-list.c index cc5f3a0c35d..517641a019a 100644 --- a/src/test/test-cap-list.c +++ b/src/test/test-cap-list.c @@ -29,7 +29,8 @@ TEST(cap_list) { assert_se(capability_from_name("cAp_aUdIt_rEAd") == CAP_AUDIT_READ); assert_se(capability_from_name("0") == 0); assert_se(capability_from_name("15") == 15); - assert_se(capability_from_name("63") == 63); + assert_se(capability_from_name("62") == 62); + assert_se(capability_from_name("63") == -EINVAL); assert_se(capability_from_name("64") == -EINVAL); assert_se(capability_from_name("-1") == -EINVAL); @@ -117,9 +118,9 @@ static void test_capability_set_to_string_invalid(uint64_t invalid_cap_set) { TEST(capability_set_to_string) { test_capability_set_to_string_invalid(0); - /* once the kernel supports 63 caps, there are no 'invalid' numbers + /* once the kernel supports 62 caps, there are no 'invalid' numbers * for us to test with */ - if (cap_last_cap() < 63) + if (cap_last_cap() < 62) test_capability_set_to_string_invalid(all_capabilities() + 1); }