sd-bus: make credential acquisition more graceful

So far when asked for augmented bus credentials and the process was
already gone we'd fail fatally. Let's make this graceful instead, and
never allow augmenting fail due to PID having vanished — unless the
augmenting is the explicit and only purpose of the requested operation.

This should be safe as clients have to explicitly query the acquired
creds anyway and handle if they couldn't be acquired. Moreover we
already handle permission problems gracefully, thus clients must be
ready to deal with missing creds.

This is useful to make selinux authorization work for short-lived client
proceses. PReviously we'd augment creds to have more info to log about
(the selinux decision would not be based on augmented data however,
because that'd be unsafe), and would fail if we couldn't get it. Now,
we'll try to acquire the data, but if we cannot acquire it, we'll still
do the selinux check, except that logging will be more limited.
This commit is contained in:
Lennart Poettering 2020-12-14 13:16:39 +01:00
parent 79485fc27a
commit f8ecc2c00d
2 changed files with 15 additions and 7 deletions

View File

@ -713,7 +713,7 @@ _public_ int sd_bus_get_name_creds(
}
r = bus_creds_add_more(c, mask, pid, 0);
if (r < 0)
if (r < 0 && r != -ESRCH) /* Return the error, but ignore ESRCH which just means the process is already gone */
return r;
}
@ -788,7 +788,7 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r
}
r = bus_creds_add_more(c, mask, pid, 0);
if (r < 0)
if (r < 0 && r != -ESRCH) /* If the process vanished, then don't complain, just return what we got */
return r;
*ret = TAKE_PTR(c);

View File

@ -603,8 +603,9 @@ _public_ int sd_bus_set_property(
return r;
}
_public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **creds) {
_public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **ret) {
sd_bus_creds *c;
int r;
assert_return(call, -EINVAL);
assert_return(call->sealed, -EPERM);
@ -618,7 +619,7 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
/* All data we need? */
if (c && (mask & ~c->mask) == 0) {
*creds = sd_bus_creds_ref(c);
*ret = sd_bus_creds_ref(c);
return 0;
}
@ -629,15 +630,22 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
if (call->sender)
/* There's a sender, but the creds are missing. */
return sd_bus_get_name_creds(call->bus, call->sender, mask, creds);
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, creds);
return sd_bus_get_owner_creds(call->bus, mask, ret);
}
return bus_creds_extend_by_pid(c, mask, creds);
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;
}
return r;
}
_public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) {