mirror of
https://github.com/systemd/systemd.git
synced 2025-01-14 23:24:38 +03:00
sd-bus: add sd_bus_message.verify_destination_id and .destination_ptr
kdbus learned to accept both a numerical destination ID as well as a well-known-name. In that case, kdbus makes sure that the numerical ID is in fact the owner of the provided name and fails otherwise. This allows for race-free assertion of a bus name owner while sending a message, which is a requirement for bus-proxyd. Add two new fields to sd_bus_message, and set the numerical ID to verify_destination_id if bus_message_setup_kmsg() is called for a message with a well-known name. Also, set the destination's name in the kdbus item to .destination_ptr if it is non-NULL. Normal users should not touch these fields, and they're not publicy accessible.
This commit is contained in:
parent
7e27f3121e
commit
022fb8558e
@ -204,6 +204,7 @@ static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter
|
||||
static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
|
||||
struct bus_body_part *part;
|
||||
struct kdbus_item *d;
|
||||
const char *destination;
|
||||
bool well_known;
|
||||
uint64_t unique;
|
||||
size_t sz, dl;
|
||||
@ -219,8 +220,10 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
|
||||
if (m->kdbus)
|
||||
return 0;
|
||||
|
||||
if (m->destination) {
|
||||
r = bus_kernel_parse_unique_name(m->destination, &unique);
|
||||
destination = m->destination ?: m->destination_ptr;
|
||||
|
||||
if (destination) {
|
||||
r = bus_kernel_parse_unique_name(destination, &unique);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -244,7 +247,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
|
||||
|
||||
/* Add in well-known destination header */
|
||||
if (well_known) {
|
||||
dl = strlen(m->destination);
|
||||
dl = strlen(destination);
|
||||
sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
|
||||
}
|
||||
|
||||
@ -264,9 +267,17 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
|
||||
m->kdbus->flags =
|
||||
((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
|
||||
((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
|
||||
m->kdbus->dst_id =
|
||||
well_known ? 0 :
|
||||
m->destination ? unique : KDBUS_DST_ID_BROADCAST;
|
||||
|
||||
if (well_known) {
|
||||
/* verify_destination_id will usually be 0, which makes the kernel driver only look
|
||||
* at the provided well-known name. Otherwise, the kernel will make sure the provided
|
||||
* destination id matches the owner of the provided weel-known-name, and fail if they
|
||||
* differ. Currently, this is only needed for bus-proxyd. */
|
||||
m->kdbus->dst_id = m->verify_destination_id;
|
||||
} else {
|
||||
m->kdbus->dst_id = destination ? unique : KDBUS_DST_ID_BROADCAST;
|
||||
}
|
||||
|
||||
m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
|
||||
m->kdbus->cookie = (uint64_t) m->header->serial;
|
||||
m->kdbus->priority = m->priority;
|
||||
@ -284,7 +295,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
|
||||
d = m->kdbus->items;
|
||||
|
||||
if (well_known)
|
||||
append_destination(&d, m->destination, dl);
|
||||
append_destination(&d, destination, dl);
|
||||
|
||||
append_payload_vec(&d, m->header, BUS_MESSAGE_BODY_BEGIN(m));
|
||||
|
||||
@ -299,7 +310,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part->memfd >= 0 && part->sealed && m->destination) {
|
||||
if (part->memfd >= 0 && part->sealed && destination) {
|
||||
/* Try to send a memfd, if the part is
|
||||
* sealed and this is not a broadcast. Since we can only */
|
||||
|
||||
|
@ -148,6 +148,11 @@ static void message_free(sd_bus_message *m) {
|
||||
if (m->iovec != m->iovec_fixed)
|
||||
free(m->iovec);
|
||||
|
||||
if (m->destination_ptr) {
|
||||
free(m->destination_ptr);
|
||||
m->destination_ptr = NULL;
|
||||
}
|
||||
|
||||
message_reset_containers(m);
|
||||
free(m->root_container.signature);
|
||||
free(m->root_container.offsets);
|
||||
|
@ -100,6 +100,7 @@ struct sd_bus_message {
|
||||
usec_t realtime;
|
||||
uint64_t seqnum;
|
||||
int64_t priority;
|
||||
uint64_t verify_destination_id;
|
||||
|
||||
bool sealed:1;
|
||||
bool dont_send:1;
|
||||
@ -143,6 +144,7 @@ struct sd_bus_message {
|
||||
|
||||
char sender_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1];
|
||||
char destination_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1];
|
||||
char *destination_ptr;
|
||||
|
||||
size_t header_offsets[_BUS_MESSAGE_HEADER_MAX];
|
||||
unsigned n_header_offsets;
|
||||
|
Loading…
x
Reference in New Issue
Block a user