4bff0a
From 401f1fdc309175d3920c0fe168e52c601474c000 Mon Sep 17 00:00:00 2001
4bff0a
From: Lennart Poettering <lennart@poettering.net>
4bff0a
Date: Wed, 10 Oct 2018 11:07:54 +0200
4bff0a
Subject: [PATCH] capability: introduce CAP_TO_MASK_CORRECTED() macro replacing
4bff0a
 CAP_TO_MASK()
4bff0a
4bff0a
linux/capability.h's CAP_TO_MASK potentially shifts a signed int "1"
4bff0a
(i.e. 32bit wide) left by 31 which means it becomes negative. That's
4bff0a
just weird, and ubsan complains about it. Let's introduce our own macro
4bff0a
CAP_TO_MASK_CORRECTED which doesn't fall into this trap, and make use of
4bff0a
it.
4bff0a
4bff0a
Fixes: #10347
4bff0a
(cherry picked from commit 5f00c5684f96c93a22840f7241ee444b9a632b1e)
4bff0a
4bff0a
Resolves: #1683319
4bff0a
---
4bff0a
 src/basic/capability-util.h       | 4 ++++
4bff0a
 src/libsystemd/sd-bus/bus-creds.c | 2 +-
4bff0a
 2 files changed, 5 insertions(+), 1 deletion(-)
4bff0a
4bff0a
diff --git a/src/basic/capability-util.h b/src/basic/capability-util.h
4bff0a
index 4a4a86093a..59591d4b52 100644
4bff0a
--- a/src/basic/capability-util.h
4bff0a
+++ b/src/basic/capability-util.h
4bff0a
@@ -39,3 +39,7 @@ static inline bool cap_test_all(uint64_t caps) {
4bff0a
 }
4bff0a
 
4bff0a
 bool ambient_capabilities_supported(void);
4bff0a
+
4bff0a
+/* Identical to linux/capability.h's CAP_TO_MASK(), but uses an unsigned 1U instead of a signed 1 for shifting left, in
4bff0a
+ * order to avoid complaints about shifting a signed int left by 31 bits, which would make it negative. */
4bff0a
+#define CAP_TO_MASK_CORRECTED(x) (1U << ((x) & 31U))
4bff0a
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
4bff0a
index aae9fcd58b..b180a033b8 100644
4bff0a
--- a/src/libsystemd/sd-bus/bus-creds.c
4bff0a
+++ b/src/libsystemd/sd-bus/bus-creds.c
4bff0a
@@ -663,7 +663,7 @@ static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
4bff0a
 
4bff0a
         sz = DIV_ROUND_UP(cap_last_cap(), 32U);
4bff0a
 
4bff0a
-        return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
4bff0a
+        return !!(c->capability[offset * sz + CAP_TO_INDEX((uint32_t) capability)] & CAP_TO_MASK_CORRECTED((uint32_t) capability));
4bff0a
 }
4bff0a
 
4bff0a
 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {