diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-02-20 16:21:25 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-02-20 16:49:45 +0100 |
commit | 3b3ebabfa6e6b25e0ec947875b90307078608139 (patch) | |
tree | 2d394cf6e41f9917e84bb3c2b48d78dae6de89ab | |
parent | 3fd5190b5e0f2ba08b12cb53e3c27fc1e54a4496 (diff) | |
download | systemd-3b3ebabfa6e6b25e0ec947875b90307078608139.tar.gz |
capability-util: add macro for largest cap we're willing to accept
Let's hide the hard to grasp 62 behind a name.
-rw-r--r-- | src/basic/cap-list.c | 6 | ||||
-rw-r--r-- | src/basic/capability-util.c | 16 | ||||
-rw-r--r-- | src/basic/capability-util.h | 4 |
3 files changed, 16 insertions, 10 deletions
diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c index 811adb0242..45a5b371e8 100644 --- a/src/basic/cap-list.c +++ b/src/basic/cap-list.c @@ -31,7 +31,7 @@ const char *capability_to_string(int id, char buf[static CAPABILITY_TO_STRING_MA if (id < 0) return NULL; - if (id >= 63) /* refuse caps >= 63 since we can't store them in a uint64_t mask anymore, and still retain UINT64_MAX as marker for "unset" */ + if (id > CAP_LIMIT) /* refuse caps > 62 since we can't store them in a uint64_t mask anymore, and still retain UINT64_MAX as marker for "unset" */ return NULL; p = capability_to_name(id); @@ -51,7 +51,7 @@ int capability_from_name(const char *name) { /* Try to parse numeric capability */ r = safe_atoi(name, &i); if (r >= 0) { - if (i < 0 || i >= 63) + if (i < 0 || i > CAP_LIMIT) return -EINVAL; return i; @@ -71,7 +71,7 @@ int capability_from_name(const char *name) { * highest supported capability. Hence with everyone agreeing on the same capabilities list, this function * will return one higher than cap_last_cap(). */ int capability_list_length(void) { - return (int) MIN(ELEMENTSOF(capability_names), 63U); + return MIN((int) ELEMENTSOF(capability_names), CAP_LIMIT + 1); } int capability_set_to_string(uint64_t set, char **ret) { diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c index 8cc75c06c8..5dd2f0a63c 100644 --- a/src/basic/capability-util.c +++ b/src/basic/capability-util.c @@ -47,11 +47,13 @@ unsigned cap_last_cap(void) { r = safe_atolu(content, &p); if (r >= 0) { - 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 = 62; + if (p > CAP_LIMIT) /* 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). We + * also want to use UINT64_MAX as marker for "unset". Hence let's + * hence protect ourselves against that and always cap at 62 for + * now. */ + p = CAP_LIMIT; saved = p; valid = true; @@ -60,7 +62,7 @@ unsigned cap_last_cap(void) { } /* fall back to syscall-probing for pre linux-3.2 */ - p = MIN((unsigned long) CAP_LAST_CAP, 62U); + p = (unsigned long) MIN(CAP_LAST_CAP, CAP_LIMIT); if (prctl(PR_CAPBSET_READ, p) < 0) { @@ -72,7 +74,7 @@ unsigned cap_last_cap(void) { } else { /* Hmm, look upwards, until we find one that doesn't work */ - for (; p < 62; p++) + for (; p < CAP_LIMIT; p++) if (prctl(PR_CAPBSET_READ, p+1) < 0) break; } diff --git a/src/basic/capability-util.h b/src/basic/capability-util.h index 48e8db35f6..07b13862c7 100644 --- a/src/basic/capability-util.h +++ b/src/basic/capability-util.h @@ -15,6 +15,10 @@ /* All possible capabilities bits on */ #define CAP_MASK_ALL UINT64_C(0x7fffffffffffffff) +/* The largest capability we can deal with, given we want to be able to store cap masks in uint64_t but still + * be able to use UINT64_MAX as indicator for "not set". The latter makes capability 63 unavailable. */ +#define CAP_LIMIT 62 + unsigned cap_last_cap(void); int have_effective_cap(int value); int capability_gain_cap_setpcap(cap_t *return_caps); |