]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: tighten rules on sd_bus_query_sender_creds() a bit
authorLennart Poettering <lennart@poettering.net>
Fri, 26 Jan 2024 17:01:25 +0000 (18:01 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 29 Jan 2024 13:42:37 +0000 (14:42 +0100)
Let's always derive credentials from a bus name or a conneciton fd if we
can, because they pin things.

Let's not go via PID really, because it's always racy to do so.

Note that this doesn't change much, since we wouldn't use such augmented
data for auth anyway (because it will be masked in the
sd_bus_creds.augmented mask as untrusted). But still, let's prefer
trusted data over untrusted data.

src/libsystemd/sd-bus/bus-convenience.c

index 989e577de57e216c45692f35b0adedaa0ab0fc23..14d8073bc9026a643b1c9a4e5ec7d9b402dd4ed4 100644 (file)
@@ -640,8 +640,8 @@ _public_ int sd_bus_set_property(
 }
 
 _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **ret) {
+        uint64_t missing;
         sd_bus_creds *c;
-        int r;
 
         assert_return(call, -EINVAL);
         assert_return(call->sealed, -EPERM);
@@ -653,36 +653,22 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
                 return -ENOTCONN;
 
         c = sd_bus_message_get_creds(call);
-
-        /* All data we need? */
-        if (c && (mask & ~SD_BUS_CREDS_AUGMENT & ~c->mask) == 0) {
+        if (c)
+                missing = mask & ~SD_BUS_CREDS_AUGMENT & ~c->mask;
+        else
+                missing = mask & ~SD_BUS_CREDS_AUGMENT;
+        if (missing == 0) { /* All data we need? */
                 *ret = sd_bus_creds_ref(c);
                 return 0;
         }
 
-        /* No data passed? Or not enough data passed to retrieve the missing bits? */
-        if (!c || !(c->mask & SD_BUS_CREDS_PID)) {
-                /* We couldn't read anything from the call, let's try
-                 * to get it from the sender or peer. */
-
-                if (call->sender)
-                        /* There's a sender, but the creds are missing. */
-                        return sd_bus_get_name_creds(call->bus, call->sender, mask, ret);
-                else
-                        /* There's no sender. For direct connections
-                         * the credentials of the AF_UNIX peer matter,
-                         * which may be queried via sd_bus_get_owner_creds(). */
-                        return sd_bus_get_owner_creds(call->bus, mask, ret);
-        }
-
-        r = bus_creds_extend_by_pid(c, mask, ret);
-        if (r == -ESRCH) {
-                /* Process doesn't exist anymore? propagate the few things we have */
-                *ret = sd_bus_creds_ref(c);
-                return 0;
-        }
+        /* There's a sender, use that */
+        if (call->sender && call->bus->bus_client)
+                return sd_bus_get_name_creds(call->bus, call->sender, mask, ret);
 
-        return r;
+        /* There's no sender. For direct connections the credentials of the AF_UNIX peer matter, which may be
+         * queried via sd_bus_get_owner_creds(). */
+        return sd_bus_get_owner_creds(call->bus, mask, ret);
 }
 
 _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) {