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