| From 8efdae75ddf035c8c04983820f8d8cf767cc17b1 Mon Sep 17 00:00:00 2001 |
| From: Jan Synacek <jsynacek@redhat.com> |
| Date: Fri, 31 Jan 2020 11:34:45 +0100 |
| Subject: [PATCH] sd-bus: introduce API for re-enqueuing incoming messages |
| |
| When authorizing via PolicyKit we want to process incoming method calls |
| twice: once to process and figure out that we need PK authentication, |
| and a second time after we aquired PK authentication to actually execute |
| the operation. With this new call sd_bus_enqueue_for_read() we have a |
| way to put an incoming message back into the read queue for this |
| purpose. |
| |
| This might have other uses too, for example debugging. |
| Related: CVE-2020-1712 |
| |
| src/libsystemd/libsystemd.sym | 1 + |
| src/libsystemd/sd-bus/sd-bus.c | 24 ++++++++++++++++++++++++ |
| src/systemd/sd-bus.h | 1 + |
| 3 files changed, 26 insertions(+) |
| |
| diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym |
| index 1eec17db50..e9972593a6 100644 |
| |
| |
| @@ -569,4 +569,5 @@ global: |
| sd_event_source_get_inotify_mask; |
| sd_event_source_set_destroy_callback; |
| sd_event_source_get_destroy_callback; |
| + sd_bus_enqueue_for_read; |
| } LIBSYSTEMD_238; |
| diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c |
| index e49d58137d..68ad6cbe89 100644 |
| |
| |
| @@ -4120,3 +4120,27 @@ _public_ int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret) { |
| *ret = bus->wqueue_size; |
| return 0; |
| } |
| + |
| +_public_ int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m) { |
| + int r; |
| + |
| + assert_return(bus, -EINVAL); |
| + assert_return(bus = bus_resolve(bus), -ENOPKG); |
| + assert_return(m, -EINVAL); |
| + assert_return(m->sealed, -EINVAL); |
| + assert_return(!bus_pid_changed(bus), -ECHILD); |
| + |
| + if (!BUS_IS_OPEN(bus->state)) |
| + return -ENOTCONN; |
| + |
| + /* Re-enqeue a message for reading. This is primarily useful for PolicyKit-style authentication, |
| + * where we want accept a message, then determine we need to interactively authenticate the user, and |
| + * when we have that process the message again. */ |
| + |
| + r = bus_rqueue_make_room(bus); |
| + if (r < 0) |
| + return r; |
| + |
| + bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(m, bus); |
| + return 0; |
| +} |
| diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h |
| index 54c4b1ca83..9ba757b13d 100644 |
| |
| |
| @@ -193,6 +193,7 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **r); |
| int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r); |
| int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec); |
| int sd_bus_flush(sd_bus *bus); |
| +int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m); |
| |
| sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus); |
| sd_bus_message* sd_bus_get_current_message(sd_bus *bus); |