chiark / gitweb /
sd-bus: when augmenting creds, remember which ones were augmented
authorLennart Poettering <lennart@poettering.net>
Mon, 20 Apr 2015 22:58:08 +0000 (00:58 +0200)
committerSven Eden <yamakuzure@gmx.net>
Tue, 14 Mar 2017 07:07:11 +0000 (08:07 +0100)
Also, when we do permissions checks using creds, verify that we don't do
so based on augmented creds, as extra safety check.

src/libelogind/libelogind.sym.m4
src/libelogind/sd-bus/bus-convenience.c
src/libelogind/sd-bus/bus-creds.c
src/libelogind/sd-bus/bus-creds.h
src/libelogind/sd-bus/bus-util.c
src/systemd/sd-bus.h

index 81f1122697eaa2374586a5b5a7d29fb9ae8179b7..1b50486cfaf3f4e355edcef6e51a88c6b855ce4a 100644 (file)
@@ -322,6 +322,7 @@ global:
         sd_bus_creds_ref;
         sd_bus_creds_unref;
         sd_bus_creds_get_mask;
+        sd_bus_creds_get_augmented_mask;
         sd_bus_creds_get_uid;
         sd_bus_creds_get_gid;
         sd_bus_creds_get_pid;
index 71ce757f702bcefc03772141ed8bee5b0e25c764..28bc8d28181b1df349ca6659eb216d659b8d534f 100644 (file)
@@ -499,10 +499,18 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability)
                 return -ENOTCONN;
 
         if (capability >= 0) {
+
                 r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
                 if (r < 0)
                         return r;
 
+                /* We cannot use augmented caps for authorization,
+                 * since then data is acquired raceful from
+                 * /proc. This can never actually happen, but let's
+                 * better be safe than sorry, and do an extra check
+                 * here. */
+                assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EFFECTIVE_CAPS) == 0, -EPERM);
+
                 /* Note that not even on kdbus we might have the caps
                  * field, due to faked identities, or namespace
                  * translation issues. */
@@ -523,6 +531,13 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability)
         if (our_uid != 0 || !know_caps || capability < 0) {
                 uid_t sender_uid;
 
+                /* We cannot use augmented uid/euid for authorization,
+                 * since then data is acquired raceful from
+                 * /proc. This can never actually happen, but let's
+                 * better be safe than sorry, and do an extra check
+                 * here. */
+                assert_return((sd_bus_creds_get_augmented_mask(creds) & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID)) == 0, -EPERM);
+
                 /* Try to use the EUID, if we have it. */
                 r = sd_bus_creds_get_euid(creds, &sender_uid);
                 if (r < 0)
index 0f13d66508fe0771f0178ef86d3f87640d904e81..f86bd27ffc66ec28649cded930de8a1d34543086 100644 (file)
@@ -130,6 +130,12 @@ _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
         return c->mask;
 }
 
+_public_ uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c) {
+        assert_return(c, 0);
+
+        return c->augmented;
+}
+
 sd_bus_creds* bus_creds_new(void) {
         sd_bus_creds *c;
 
@@ -663,25 +669,25 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
         if (!(mask & SD_BUS_CREDS_AUGMENT))
                 return 0;
 
-        missing = mask & ~c->mask;
-        if (missing == 0)
-                return 0;
-
         /* Try to retrieve PID from creds if it wasn't passed to us */
         if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
                 pid = c->pid;
 
-        if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
-                tid = c->pid;
-
         /* Without pid we cannot do much... */
         if (pid <= 0)
                 return 0;
 
-        if (pid > 0) {
-                c->pid = pid;
-                c->mask |= SD_BUS_CREDS_PID;
-        }
+        /* Try to retrieve TID from creds if it wasn't passed to us */
+        if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
+                tid = c->tid;
+
+        /* Calculate what we shall and can add */
+        missing = mask & ~(c->mask|SD_BUS_CREDS_PID|SD_BUS_CREDS_TID|SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_DESCRIPTION|SD_BUS_CREDS_AUGMENT);
+        if (missing == 0)
+                return 0;
+
+        c->pid = pid;
+        c->mask |= SD_BUS_CREDS_PID;
 
         if (tid > 0) {
                 c->tid = tid;
@@ -939,6 +945,8 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                         c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
         }
 
+        c->augmented = missing & c->mask;
+
         return 0;
 }
 
@@ -1113,11 +1121,11 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->mask |= SD_BUS_CREDS_DESCRIPTION;
         }
 
+        n->augmented = c->augmented & n->mask;
+
         /* Get more data */
 
-        r = bus_creds_add_more(n, mask,
-                               c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
-                               c->mask & SD_BUS_CREDS_TID ? c->tid : 0);
+        r = bus_creds_add_more(n, mask, 0, 0);
         if (r < 0)
                 return r;
 
index 5430e535f00f2b8a74770773de608ddd02e1ef94..74062a583de0f6cc6d922eba4ee2aff641f7a62b 100644 (file)
@@ -28,7 +28,9 @@
 struct sd_bus_creds {
         bool allocated;
         unsigned n_ref;
+
         uint64_t mask;
+        uint64_t augmented;
 
         uid_t uid;
         uid_t euid;
index 5bd7885e49cfe8d5fe61fb7d2d719b22a31e7ca4..a84d3381cbe91652516830ac06e9127fac223ad7 100644 (file)
@@ -206,6 +206,9 @@ static int check_good_user(sd_bus_message *m, uid_t good_user) {
         if (r < 0)
                 return r;
 
+        /* Don't trust augmented credentials for authorization */
+        assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM);
+
         r = sd_bus_creds_get_euid(creds, &sender_uid);
         if (r < 0)
                 return r;
index f6262a3ccf5439fa9c5098eb7ff556d0cb2bbad2..f24cc08bd836310e56671fc8cac213f61a29aa9d 100644 (file)
@@ -329,6 +329,7 @@ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t creds_mask
 sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c);
 sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c);
 uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c);
+uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c);
 
 int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid);
 int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid);