From: Lennart Poettering Date: Fri, 26 Jan 2024 17:01:25 +0000 (+0100) Subject: sd-bus: tighten rules on sd_bus_query_sender_creds() a bit X-Git-Tag: v256-rc1~1021^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=75e00d5e32fa517b25289cbac806db7d88c50c8c;p=thirdparty%2Fsystemd.git sd-bus: tighten rules on sd_bus_query_sender_creds() a bit 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. --- diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c index 989e577de57..14d8073bc90 100644 --- a/src/libsystemd/sd-bus/bus-convenience.c +++ b/src/libsystemd/sd-bus/bus-convenience.c @@ -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) {