summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-02-20 16:21:25 +0100
committerLennart Poettering <lennart@poettering.net>2023-02-20 16:49:45 +0100
commit3b3ebabfa6e6b25e0ec947875b90307078608139 (patch)
tree2d394cf6e41f9917e84bb3c2b48d78dae6de89ab /src
parent3fd5190b5e0f2ba08b12cb53e3c27fc1e54a4496 (diff)
downloadsystemd-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.
Diffstat (limited to 'src')
-rw-r--r--src/basic/cap-list.c6
-rw-r--r--src/basic/capability-util.c16
-rw-r--r--src/basic/capability-util.h4
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);