mirror of
https://github.com/systemd/systemd.git
synced 2025-01-30 01:47:42 +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) {
|
static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
|
||||||
struct bus_body_part *part;
|
struct bus_body_part *part;
|
||||||
struct kdbus_item *d;
|
struct kdbus_item *d;
|
||||||
|
const char *destination;
|
||||||
bool well_known;
|
bool well_known;
|
||||||
uint64_t unique;
|
uint64_t unique;
|
||||||
size_t sz, dl;
|
size_t sz, dl;
|
||||||
@ -219,8 +220,10 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
|
|||||||
if (m->kdbus)
|
if (m->kdbus)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (m->destination) {
|
destination = m->destination ?: m->destination_ptr;
|
||||||
r = bus_kernel_parse_unique_name(m->destination, &unique);
|
|
||||||
|
if (destination) {
|
||||||
|
r = bus_kernel_parse_unique_name(destination, &unique);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
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 */
|
/* Add in well-known destination header */
|
||||||
if (well_known) {
|
if (well_known) {
|
||||||
dl = strlen(m->destination);
|
dl = strlen(destination);
|
||||||
sz += ALIGN8(offsetof(struct kdbus_item, str) + dl + 1);
|
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->kdbus->flags =
|
||||||
((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
|
((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->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
|
||||||
m->kdbus->dst_id =
|
|
||||||
well_known ? 0 :
|
if (well_known) {
|
||||||
m->destination ? unique : KDBUS_DST_ID_BROADCAST;
|
/* 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->payload_type = KDBUS_PAYLOAD_DBUS;
|
||||||
m->kdbus->cookie = (uint64_t) m->header->serial;
|
m->kdbus->cookie = (uint64_t) m->header->serial;
|
||||||
m->kdbus->priority = m->priority;
|
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;
|
d = m->kdbus->items;
|
||||||
|
|
||||||
if (well_known)
|
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));
|
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;
|
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
|
/* Try to send a memfd, if the part is
|
||||||
* sealed and this is not a broadcast. Since we can only */
|
* 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)
|
if (m->iovec != m->iovec_fixed)
|
||||||
free(m->iovec);
|
free(m->iovec);
|
||||||
|
|
||||||
|
if (m->destination_ptr) {
|
||||||
|
free(m->destination_ptr);
|
||||||
|
m->destination_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
message_reset_containers(m);
|
message_reset_containers(m);
|
||||||
free(m->root_container.signature);
|
free(m->root_container.signature);
|
||||||
free(m->root_container.offsets);
|
free(m->root_container.offsets);
|
||||||
|
@ -100,6 +100,7 @@ struct sd_bus_message {
|
|||||||
usec_t realtime;
|
usec_t realtime;
|
||||||
uint64_t seqnum;
|
uint64_t seqnum;
|
||||||
int64_t priority;
|
int64_t priority;
|
||||||
|
uint64_t verify_destination_id;
|
||||||
|
|
||||||
bool sealed:1;
|
bool sealed:1;
|
||||||
bool dont_send:1;
|
bool dont_send:1;
|
||||||
@ -143,6 +144,7 @@ struct sd_bus_message {
|
|||||||
|
|
||||||
char sender_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1];
|
char sender_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1];
|
||||||
char destination_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];
|
size_t header_offsets[_BUS_MESSAGE_HEADER_MAX];
|
||||||
unsigned n_header_offsets;
|
unsigned n_header_offsets;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user