summaryrefslogtreecommitdiff
path: root/src/bus-proxyd/bus-proxyd.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2015-01-11 15:14:14 +0100
committerDavid Herrmann <dh.herrmann@gmail.com>2015-01-11 15:14:14 +0100
commitb5cfc2b953fca74bf4c42a4e9e38abe72cc26493 (patch)
treecde15657c775610aef1b50ad340663ad85af8cdc /src/bus-proxyd/bus-proxyd.c
parentfa188b9b242326731554dbf80f8e118285cc7676 (diff)
bus-proxy: fix receiver policy on dbus-1 to kdbus signals
If a dbus-1 client sends a broadcasted signal via the bus-proxy to kdbus, the bus-proxy has no idea who the receiver is. Classic dbus-daemon has bus-access and can perform policy checks for each receiver, but we cant. Instead, we know the kernel will perform receiver policy checks for broadcasts, so we can skip the policy check and just push it into the kernel. This fixes wpa_supplicant which has DENY rules on receive_type=signal for non-root. As we never know the target, we always DENY all broadcasts from wpa_supplicant. Note that will still perform receiver-policy checks for signals that we get from the kernel back to us. In those cases, we know the receiver (which is us).
Diffstat (limited to 'src/bus-proxyd/bus-proxyd.c')
-rw-r--r--src/bus-proxyd/bus-proxyd.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c
index 3cbbab718b..2b32865213 100644
--- a/src/bus-proxyd/bus-proxyd.c
+++ b/src/bus-proxyd/bus-proxyd.c
@@ -1148,7 +1148,17 @@ static int process_policy(sd_bus *from, sd_bus *to, sd_bus_message *m, Policy *p
/* Then check if the recipient can receive from our name */
if (granted) {
- if (set_isempty(owned_names)) {
+ if (sd_bus_message_is_signal(m, NULL, NULL)) {
+ /* If we forward a signal from dbus-1 to kdbus,
+ * we have no idea who the recipient is.
+ * Therefore, we cannot apply any dbus-1
+ * receiver policies that match on receiver
+ * credentials. We know sd-bus always sets
+ * KDBUS_MSG_SIGNAL, so the kernel applies
+ * receiver policies to the message. Therefore,
+ * skip policy checks in this case. */
+ return 0;
+ } else if (set_isempty(owned_names)) {
if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, NULL, m->path, m->interface, m->member))
return 0;
} else {