]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
capability-util: add macro for largest cap we're willing to accept
authorLennart Poettering <lennart@poettering.net>
Mon, 20 Feb 2023 15:21:25 +0000 (16:21 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 20 Feb 2023 15:49:45 +0000 (16:49 +0100)
Let's hide the hard to grasp 62 behind a name.

src/basic/cap-list.c
src/basic/capability-util.c
src/basic/capability-util.h

index 811adb02421f2d16278768d6b2ab30d566c97db7..45a5b371e84677895c4c1fee66300f0b431ef922 100644 (file)
@@ -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) {
index 8cc75c06c8751bf49b86994011ce45e834776d5c..5dd2f0a63c1393cad054c9127d852555d6414f34 100644 (file)
@@ -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;
         }
index 48e8db35f689047cc6140e4e378af2cb0193c4ce..07b13862c7941af01d0e2c3a2d57b72eaa291d87 100644 (file)
 /* 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);