kdbus.h: introduce KDBUS_MSG_SIGNAL
authorDaniel Mack <daniel@zonque.org>
Mon, 5 Jan 2015 12:22:48 +0000 (13:22 +0100)
committerDaniel Mack <daniel@zonque.org>
Mon, 5 Jan 2015 12:37:07 +0000 (13:37 +0100)
In order to allow directed (unicast) signals, we need to split the
handling logic and introduce KDBUS_MSG_SIGNAL as message flag.

For signals, no matter if unicast or broadcast, we apply the following
policy logic:

 * The _destination_ of the message must have a TALK permission to
   the _sender_

 * The _destination_ must have a bloom filter installed that matches
   the bloom filter attached to the message

Tests are tweaked to reflect the new implementation.

Signed-off-by: Daniel Mack <daniel@zonque.org>
kdbus.h
kdbus.txt
message.c
test/kdbus-util.c
test/test-fd.c
test/test-match.c

diff --git a/kdbus.h b/kdbus.h
index d124f21a36000d701d62bc4086a7a2625a312802..75af6dab491a4b2b88bf7284c507f37b30489b29 100644 (file)
--- a/kdbus.h
+++ b/kdbus.h
@@ -408,10 +408,12 @@ struct kdbus_item_list {
  *                             in cookie_reply
  * @KDBUS_MSG_NO_AUTO_START:   Do not start a service, if the addressed
  *                             name is not currently active
+ * @KDBUS_MSG_SIGNAL:          Treat this message as signal
  */
 enum kdbus_msg_flags {
        KDBUS_MSG_EXPECT_REPLY  = 1ULL << 0,
        KDBUS_MSG_NO_AUTO_START = 1ULL << 1,
+       KDBUS_MSG_SIGNAL        = 1ULL << 2,
 };
 
 /**
index 711ac10782f41648cf18c5c8c51223381d5449c1..c7a233eefeac648e758e91e72d2d64038377830d 100644 (file)
--- a/kdbus.txt
+++ b/kdbus.txt
@@ -1467,16 +1467,16 @@ struct kdbus_cmd_match {
 
 Bloom filters allow checking whether a given word is present in a dictionary.
 This allows connections to set up a mask for information it is interested in,
-and will be delivered broadcast messages that have a matching filter.
+and will be delivered signal messages that have a matching filter.
 
 For general information on bloom filters, see
 
   https://en.wikipedia.org/wiki/Bloom_filter
 
 The size of the bloom filter is defined per bus when it is created, in
-kdbus_bloom_parameter.size. All bloom filters attached to broadcast messages
-on the bus must match this size, and all bloom filter matches uploaded by
-connections must also match the size, or a multiple thereof (see below).
+kdbus_bloom_parameter.size. All bloom filters attached to signals on the bus
+must match this size, and all bloom filter matches uploaded by connections must
+also match the size, or a multiple thereof (see below).
 
 The calculation of the mask has to be done on the userspace side. The kernel
 just checks the bitmasks to decide whether or not to let the message pass. All
@@ -1486,11 +1486,11 @@ matches are expected to happen, and userspace must deal with that fact.
 
 Masks are entities that are always passed to the kernel as part of a match
 (with an item of type KDBUS_ITEM_BLOOM_MASK), and filters can be attached to
-broadcast messages (with an item of type KDBUS_ITEM_BLOOM_FILTER).
+signals, with an item of type KDBUS_ITEM_BLOOM_FILTER.
 
-For a broadcast to match, all set bits in the filter have to be set in the
-installed match mask as well. For example, consider a bus has a bloom size
-of 8 bytes, and the following mask/filter combinations:
+For a filter to match, all its bits have to be set in the match mask as well.
+For example, consider a bus has a bloom size of 8 bytes, and the following
+mask/filter combinations:
 
     filter  0x0101010101010101
     mask    0x0101010101010101
@@ -1511,11 +1511,10 @@ Uploaded matches may contain multiple masks, each of which in the size of the
 bloom size defined by the bus. Each block of a mask is called a 'generation',
 starting at index 0.
 
-At match time, when a broadcast message is about to be delivered, a bloom
-mask generation is passed, which denotes which of the bloom masks the filter
-should be matched against. This allows userspace to provide backward compatible
-masks at upload time, while older clients can still match against older
-versions of filters.
+At match time, when a signal is about to be delivered, a bloom mask generation
+is passed, which denotes which of the bloom masks the filter should be matched
+against. This allows userspace to provide backward compatible masks at upload
+time, while older clients can still match against older versions of filters.
 
 
 10.5 Removing a match
index c986b8bdd8e87282be42870aac180ff1d0408812..eba43034468c8e49d31c265d437e52cc9b118184 100644 (file)
--- a/message.c
+++ b/message.c
@@ -213,8 +213,13 @@ static int kdbus_msg_scan_items(struct kdbus_kmsg *kmsg,
        bool has_bloom = false;
        bool has_name = false;
        bool has_fds = false;
+       bool is_broadcast;
+       bool is_signal;
        u64 vec_size;
 
+       is_broadcast = (msg->dst_id == KDBUS_DST_ID_BROADCAST);
+       is_signal = !!(msg->flags & KDBUS_MSG_SIGNAL);
+
        /* count data payloads */
        n_vecs = 0;
        n_memfds = 0;
@@ -359,8 +364,8 @@ static int kdbus_msg_scan_items(struct kdbus_kmsg *kmsg,
                                return -EEXIST;
                        has_fds = true;
 
-                       /* do not allow to broadcast file descriptors */
-                       if (msg->dst_id == KDBUS_DST_ID_BROADCAST)
+                       /* Do not allow to broadcast file descriptors */
+                       if (is_broadcast)
                                return -ENOTUNIQ;
 
                        if (fds_count > KDBUS_MSG_MAX_FDS)
@@ -448,22 +453,25 @@ static int kdbus_msg_scan_items(struct kdbus_kmsg *kmsg,
        if (msg->dst_id == KDBUS_DST_ID_NAME && !has_name)
                return -EDESTADDRREQ;
 
-       if (msg->dst_id == KDBUS_DST_ID_BROADCAST) {
-               /* broadcasts can't take names */
+       if (is_broadcast) {
+               /* Broadcasts can't take names */
                if (has_name)
                        return -EBADMSG;
 
-               /* broadcast messages require a bloom filter */
-               if (!has_bloom)
+               /* All broadcasts have to be signals */
+               if (!is_signal)
                        return -EBADMSG;
 
-               /* timeouts are not allowed for broadcasts */
+               /* Timeouts are not allowed for broadcasts */
                if (msg->timeout_ns > 0)
                        return -ENOTUNIQ;
        }
 
-       /* bloom filters are for undirected messages only */
-       if (has_name && has_bloom)
+       /*
+        * Signal messages require a bloom filter, and bloom filters are
+        * only valid with signals.
+        */
+       if (is_signal ^ has_bloom)
                return -EBADMSG;
 
        return 0;
@@ -516,8 +524,9 @@ struct kdbus_kmsg *kdbus_kmsg_new_from_cmd(struct kdbus_conn *conn,
        ret = kdbus_check_and_write_flags(m->msg.flags, buf,
                                          offsetof(struct kdbus_cmd_send,
                                                   kernel_msg_flags),
-                                         KDBUS_MSG_EXPECT_REPLY |
-                                         KDBUS_MSG_NO_AUTO_START);
+                                         KDBUS_MSG_EXPECT_REPLY        |
+                                         KDBUS_MSG_NO_AUTO_START       |
+                                         KDBUS_MSG_SIGNAL);
        if (ret < 0)
                goto exit_free;
 
@@ -551,6 +560,12 @@ struct kdbus_kmsg *kdbus_kmsg_new_from_cmd(struct kdbus_conn *conn,
                        ret = -ENOTUNIQ;
                        goto exit_free;
                }
+
+               /* replies may not be expected for signals */
+               if (m->msg.flags & KDBUS_MSG_SIGNAL) {
+                       ret = -EINVAL;
+                       goto exit_free;
+               }
        } else {
                /*
                 * KDBUS_SEND_SYNC_REPLY is only valid together with
index 013b5ba80d0e52e9705a8c1763dbbc058865d907..fc612c0d96c849e56e4897384f8f28a929c787b9 100644 (file)
@@ -509,6 +509,9 @@ static int __kdbus_msg_send(const struct kdbus_conn *conn,
                return ret;
        }
 
+       if (dst_id == KDBUS_DST_ID_BROADCAST)
+               flags |= KDBUS_MSG_SIGNAL;
+
        memset(msg, 0, size);
        msg->flags = flags;
        msg->priority = priority;
index 4cd7e7daac8e251b74f79b8a7ff0263d20925147..261cfc8aee6bb28f0e2280383b1c7952831263c1 100644 (file)
@@ -110,6 +110,8 @@ static int send_memfds(struct kdbus_conn *conn, uint64_t dst_id,
                item->type = KDBUS_ITEM_BLOOM_FILTER;
                item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
                item = KDBUS_ITEM_NEXT(item);
+
+               msg->flags |= KDBUS_MSG_SIGNAL;
        }
 
        make_item_memfds(item, memfds_array, memfd_count);
@@ -152,6 +154,8 @@ static int send_fds(struct kdbus_conn *conn, uint64_t dst_id,
                item->type = KDBUS_ITEM_BLOOM_FILTER;
                item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
                item = KDBUS_ITEM_NEXT(item);
+
+               msg->flags |= KDBUS_MSG_SIGNAL;
        }
 
        make_item_fds(item, fd_array, fd_count);
index 6359b06ede8ba08bc3d1d3e049cc55d7546c8960..d40c3388500a130b0ca6530051b4384ea4d93677 100644 (file)
@@ -329,6 +329,7 @@ static int send_bloom_filter(const struct kdbus_conn *conn,
        msg->size = size;
        msg->src_id = conn->id;
        msg->dst_id = KDBUS_DST_ID_BROADCAST;
+       msg->flags = KDBUS_MSG_SIGNAL;
        msg->payload_type = KDBUS_PAYLOAD_DBUS;
        msg->cookie = cookie;