]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bus-proxy: never apply policy when sending signals
authorDavid Herrmann <dh.herrmann@gmail.com>
Wed, 1 Jul 2015 16:31:18 +0000 (18:31 +0200)
committerKay Sievers <kay@vrfy.org>
Wed, 1 Jul 2015 16:32:51 +0000 (18:32 +0200)
Unlike dbus-daemon, the bus-proxy does not know the receiver of a
broadcast (as the kernel has exclusive access on the bus connections).
Hence, and "destination=" matches in dbus1 policies cannot be applied.

But kdbus does not place any restrictions on *SENDING* broadcasts, anyway.
The kernel never returns EPERM to KDBUS_CMD_SEND if KDBUS_MSG_SIGNAL is
set. Instead, receiver policies are checked. Hence, stop checking sender
policies for signals in bus-proxy and leave it up to the kernel.

This fixes some network-manager bus-proxy issues where NM uses weird
dst-based matches against interface-based matches. As we cannot perform
dst-based matches, our bus-proxy cannot properly implement this policy.

src/bus-proxyd/proxy.c

index 28ab1c97fcf0602a883ef689e7db2c13ffe83728..1dc55171e7b81b0a60f3fb2f89513e07ace3dce8 100644 (file)
@@ -494,7 +494,16 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m,
                 }
 
                 /* First check if we (the sender) can send to this name */
-                if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, destination_names, m->path, m->interface, m->member, true, &n)) {
+                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 policies that match on receiver
+                         * credentials. We know sd-bus always sets
+                         * KDBUS_MSG_SIGNAL, so the kernel applies policies to
+                         * the message. Therefore, skip policy checks in this
+                         * case. */
+                        return 0;
+                } else if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, destination_names, m->path, m->interface, m->member, true, &n)) {
                         if (n) {
                                 /* If we made a receiver decision, then remember which
                                  * name's policy we used, and to which unique ID it
@@ -512,19 +521,8 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m,
                                         return r;
                         }
 
-                        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 (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, owned_names, NULL, m->path, m->interface, m->member, true)) {
+                        if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, owned_names, NULL, m->path, m->interface, m->member, true))
                                 return 0;
-                        }
                 }
 
                 /* Return an error back to the caller */