From: Lennart Poettering Date: Thu, 27 Nov 2014 00:19:50 +0000 (+0100) Subject: sd-bus: be stricter with mismatches between dbus1 and kdbus message headers X-Git-Tag: v218~295 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=7fa934b0d35492b300b79848f4822ffc40eee21f sd-bus: be stricter with mismatches between dbus1 and kdbus message headers --- diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index 651ca4726..ef157d69f 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -268,23 +268,22 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { ((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); - if (well_known) { + 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 { + 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; - if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) { + if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) m->kdbus->cookie_reply = m->reply_cookie; - } else { + else { struct timespec now; assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0); @@ -699,6 +698,30 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { if (r < 0) goto fail; + /* Refuse messages if kdbus and dbus1 cookie doesn't match up */ + if ((uint64_t) m->header->serial != k->cookie) { + r = -EBADMSG; + goto fail; + } + + /* Refuse messages where the reply flag doesn't match up */ + if (!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) != !!(k->flags & KDBUS_MSG_FLAGS_EXPECT_REPLY)) { + r = -EBADMSG; + goto fail; + } + + /* Refuse reply messages where the reply cookie doesn't match up */ + if ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) && m->reply_cookie != k->cookie_reply) { + r = -EBADMSG; + goto fail; + } + + /* Refuse messages where the autostart flag doesn't match up */ + if (!(m->header->flags & BUS_MESSAGE_NO_AUTO_START) != !(k->flags & KDBUS_MSG_FLAGS_NO_AUTO_START)) { + r = -EBADMSG; + goto fail; + } + /* Override information from the user header with data from the kernel */ if (k->src_id == KDBUS_SRC_ID_KERNEL) m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus"; diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index 9bc05c203..a4939b47c 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -5170,6 +5170,10 @@ int bus_message_parse_fields(sd_bus_message *m) { case SD_BUS_MESSAGE_SIGNAL: if (!m->path || !m->interface || !m->member) return -EBADMSG; + + if (m->reply_cookie != 0) + return -EBADMSG; + break; case SD_BUS_MESSAGE_METHOD_CALL: @@ -5177,6 +5181,9 @@ int bus_message_parse_fields(sd_bus_message *m) { if (!m->path || !m->member) return -EBADMSG; + if (m->reply_cookie != 0) + return -EBADMSG; + break; case SD_BUS_MESSAGE_METHOD_RETURN: