summaryrefslogtreecommitdiff
path: root/src/basic/capability-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2019-03-08 17:31:12 +0100
committerLennart Poettering <lennart@poettering.net>2019-03-15 15:33:09 +0100
commit5211445eaea69b5826417c7e754b65bd652cdfaa (patch)
tree622ce1126f15aff090aa501c632e106cfd480280 /src/basic/capability-util.c
parent248dd9417161e4a468cc6f21ad8d410a674f73fa (diff)
downloadsystemd-5211445eaea69b5826417c7e754b65bd652cdfaa.tar.gz
capability: let's protect against the kernel eventually doing more than 64 caps
Everyone will be in trouble then (as quite widely caps are store in 64bit fields). But let's protect ourselves at least to the point that we ignore all higher caps for now.
Diffstat (limited to 'src/basic/capability-util.c')
-rw-r--r--src/basic/capability-util.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c
index e700edf260..45fadb9faa 100644
--- a/src/basic/capability-util.c
+++ b/src/basic/capability-util.c
@@ -47,6 +47,13 @@ unsigned long cap_last_cap(void) {
if (r >= 0) {
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,
+ * 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;
+
saved = p;
valid = true;
return p;
@@ -58,17 +65,15 @@ unsigned long cap_last_cap(void) {
if (prctl(PR_CAPBSET_READ, p) < 0) {
- /* Hmm, look downwards, until we find one that
- * works */
+ /* Hmm, look downwards, until we find one that works */
for (p--; p > 0; p --)
if (prctl(PR_CAPBSET_READ, p) >= 0)
break;
} else {
- /* Hmm, look upwards, until we find one that doesn't
- * work */
- for (;; p++)
+ /* Hmm, look upwards, until we find one that doesn't work */
+ for (; p < 63; p++)
if (prctl(PR_CAPBSET_READ, p+1) < 0)
break;
}