mirror of
https://github.com/systemd/systemd.git
synced 2024-10-29 21:55:36 +03:00
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.
This commit is contained in:
parent
3f444e94f5
commit
d0e67c69ba
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user