diff options
author | Jan Synacek <jsynacek@redhat.com> | 2020-01-31 11:34:45 +0100 |
---|---|---|
committer | Lukas Nykryn <lnykryn@redhat.com> | 2020-02-03 11:05:28 +0100 |
commit | f16b5124274f35c475cb70fa936567877a4b74f9 (patch) | |
tree | bb729465c930400052a3551336505451fcfd9d28 | |
parent | 02d55f8f5bfd38ed2958c7e55707cadb058071be (diff) | |
download | systemd-f16b5124274f35c475cb70fa936567877a4b74f9.tar.gz |
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
-rw-r--r-- | src/libsystemd/libsystemd.sym | 1 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/sd-bus.c | 24 | ||||
-rw-r--r-- | src/systemd/sd-bus.h | 1 |
3 files changed, 26 insertions, 0 deletions
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 1eec17db50..e9972593a6 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -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 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -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 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -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); |