summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2015-07-04 12:14:45 +0200
committerDavid Herrmann <dh.herrmann@gmail.com>2015-07-04 12:23:39 +0200
commit0a069ce62de904ae9cbaf23d026ac380b02e50e4 (patch)
tree05477c4a95d55ec86d5e631f5d23db01a126b6a5
parent1d44f7584a713ab24e1ead541a8c85e176b99fd2 (diff)
core: harden cgroups-agent forwarding
On dbus1, we receive systemd1.Agent signals via the private socket, hence it's trusted. However, on kdbus we receive it on the system bus. We must make sure it's sent by UID=0, otherwise unprivileged users can fake it. Furthermore, never forward broadcasts we sent ourself. This might happen on kdbus, as we forward the message on the same bus we received it on, thus ending up in an endless loop.
-rw-r--r--src/core/dbus.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 86886e6d2c..6679ebadf1 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -69,13 +69,37 @@ int bus_send_queued_message(Manager *m) {
}
static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+ const char *cgroup, *me;
Manager *m = userdata;
- const char *cgroup;
+ uid_t sender_uid;
+ sd_bus *bus;
int r;
assert(message);
assert(m);
+ /* ignore recursive events sent by us on the system/user bus */
+ bus = sd_bus_message_get_bus(message);
+ if (!sd_bus_is_server(bus)) {
+ r = sd_bus_get_unique_name(bus, &me);
+ if (r < 0)
+ return r;
+
+ if (streq_ptr(sd_bus_message_get_sender(message), me))
+ return 0;
+ }
+
+ /* only accept org.freedesktop.systemd1.Agent from UID=0 */
+ r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_creds_get_euid(creds, &sender_uid);
+ if (r < 0 || sender_uid != 0)
+ return 0;
+
+ /* parse 'cgroup-empty' notification */
r = sd_bus_message_read(message, "s", &cgroup);
if (r < 0) {
bus_log_parse_error(r);