From e43d089eee596218c966b0d80fc8fdbd09abb9a4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 25 Dec 2013 04:14:05 +0100 Subject: [PATCH] update cookie and cookie_reply logic --- connection.c | 27 +++++++++++++++------------ kdbus.h | 24 +++++++++++++----------- message.c | 9 ++++++++- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/connection.c b/connection.c index f249010..8e6866b 100644 --- a/connection.c +++ b/connection.c @@ -80,7 +80,7 @@ struct kdbus_conn_queue { * @entry: The list_head entry of the connection's reply_from_list * @conn: The counterpart connection that is expected to answer * @deadline_ns: The deadline of the reply, in nanoseconds - * @cookie: The expected reply cookie + * @cookie: The cookie of the requesting message */ struct kdbus_conn_reply_entry { struct list_head entry; @@ -724,25 +724,28 @@ int kdbus_conn_kmsg_send(struct kdbus_ep *ep, if (conn_src) { bool allowed = false; - struct kdbus_conn_reply_entry *reply; + struct kdbus_conn_reply_entry *r; /* * Walk the list of connection we expect a reply from. * If there's any matching entry, allow the message to * be sent, and remove the entry. */ - mutex_lock(&conn_dst->lock); - list_for_each_entry(reply, &conn_dst->reply_list, entry) { - if (reply->conn != conn_src) - continue; - if (reply->cookie != msg->cookie) - continue; + if (msg->cookie_reply > 0) { + mutex_lock(&conn_dst->lock); + list_for_each_entry(r, &conn_dst->reply_list, entry) { + if (r->conn != conn_src) + continue; - kdbus_conn_reply_entry_free(reply); - allowed = true; - break; + if (r->cookie != msg->cookie_reply) + continue; + + kdbus_conn_reply_entry_free(r); + allowed = true; + break; + } + mutex_unlock(&conn_dst->lock); } - mutex_unlock(&conn_dst->lock); /* ... otherwise, ask the policy DB for permission */ if (!allowed && ep->policy_db) { diff --git a/kdbus.h b/kdbus.h index 6991b7f..71bf86d 100644 --- a/kdbus.h +++ b/kdbus.h @@ -313,9 +313,11 @@ struct kdbus_item { /** * enum kdbus_msg_flags - type of message - * @KDBUS_MSG_FLAGS_EXPECT_REPLY: Expect a reply message, used for method - * calls. The cookie identifies the - * message and the respective reply + * @KDBUS_MSG_FLAGS_EXPECT_REPLY: Expect a reply message, used for + * method calls. The userspace-supplied + * cookie identifies the message and the + * respective reply carries the cookie + * in cookie_reply * @KDBUS_MSG_FLAGS_NO_AUTO_START: Do not start a service, if the addressed * name is not currently active */ @@ -327,7 +329,7 @@ enum kdbus_msg_flags { /** * enum kdbus_payload_type - type of payload carried by message * @KDBUS_PAYLOAD_KERNEL: Kernel-generated simple message - * @KDBUS_PAYLOAD_DBUS: D-Bus marshalling + * @KDBUS_PAYLOAD_DBUS: D-Bus marshalling */ enum kdbus_payload_type { KDBUS_PAYLOAD_KERNEL, @@ -341,9 +343,11 @@ enum kdbus_payload_type { * @dst_id: 64-bit ID of the destination connection * @src_id: 64-bit ID of the source connection * @payload_type: Payload type (KDBUS_PAYLOAD_*) - * @cookie: Userspace-supplied cookie - * @cookie_reply: For kernel-generated messages, this is the cookie - * the message is a reply to + * @cookie: Userspace-supplied cookie, for the connection + * to identify its messages + * @cookie_reply: A reply to the message with the same cookie. The + * reply itself has its own cookie, @cookie_reply + * corresponds to the cookie of the request message * @timeout_ns: For non-kernel-generated messages, this denotes the * message timeout in nanoseconds. A message has to be * received with KDBUS_CMD_MSG_RECV by the destination @@ -365,10 +369,8 @@ struct kdbus_msg { __u64 src_id; __u64 payload_type; __u64 cookie; - union { - __u64 cookie_reply; - __u64 timeout_ns; - }; + __u64 cookie_reply; + __u64 timeout_ns; struct kdbus_item items[0]; } __attribute__((aligned(8))); diff --git a/message.c b/message.c index 2a17d28..f6d3bc6 100644 --- a/message.c +++ b/message.c @@ -269,13 +269,20 @@ int kdbus_kmsg_new_from_user(struct kdbus_conn *conn, goto exit_free; } - /* check validity and gather some values for processing */ + /* requests for replies need a timeout */ if (m->msg.flags & KDBUS_MSG_FLAGS_EXPECT_REPLY && m->msg.timeout_ns == 0) { ret = -EINVAL; goto exit_free; } + /* replies cannot request a reply themselves */ + if (m->msg.flags & KDBUS_MSG_FLAGS_EXPECT_REPLY && + m->msg.cookie_reply > 0) { + ret = -EINVAL; + goto exit_free; + } + ret = kdbus_msg_scan_items(conn, m); if (ret < 0) goto exit_free; -- 2.34.1