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);
/* 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;
* 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) {
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;
}
/* 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) {
} 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;
}
/* 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);