[PATCH 05/14] kdbus: add connection, queue handling and message validation code

2015-03-09 Thread Greg Kroah-Hartman
From: Daniel Mack 

This patch adds code to create and destroy connections, to validate
incoming messages and to maintain the queue of messages that are
associated with a connection.

Note that connection and queue have a 1:1 relation, the code is only
split in two parts for cleaner separation and better readability.

Signed-off-by: Daniel Mack 
Signed-off-by: David Herrmann 
Signed-off-by: Djalal Harouni 
Signed-off-by: Greg Kroah-Hartman 
---
 ipc/kdbus/connection.c | 2215 
 ipc/kdbus/connection.h |  257 ++
 ipc/kdbus/item.c   |  339 
 ipc/kdbus/item.h   |   64 ++
 ipc/kdbus/message.c|  616 ++
 ipc/kdbus/message.h|  133 +++
 ipc/kdbus/queue.c  |  678 +++
 ipc/kdbus/queue.h  |   92 ++
 ipc/kdbus/reply.c  |  259 ++
 ipc/kdbus/reply.h  |   68 ++
 ipc/kdbus/util.h   |2 +-
 11 files changed, 4722 insertions(+), 1 deletion(-)
 create mode 100644 ipc/kdbus/connection.c
 create mode 100644 ipc/kdbus/connection.h
 create mode 100644 ipc/kdbus/item.c
 create mode 100644 ipc/kdbus/item.h
 create mode 100644 ipc/kdbus/message.c
 create mode 100644 ipc/kdbus/message.h
 create mode 100644 ipc/kdbus/queue.c
 create mode 100644 ipc/kdbus/queue.h
 create mode 100644 ipc/kdbus/reply.c
 create mode 100644 ipc/kdbus/reply.h

diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
new file mode 100644
index ..e554f1a71aa1
--- /dev/null
+++ b/ipc/kdbus/connection.c
@@ -0,0 +1,2215 @@
+/*
+ * Copyright (C) 2013-2015 Kay Sievers
+ * Copyright (C) 2013-2015 Greg Kroah-Hartman 
+ * Copyright (C) 2013-2015 Daniel Mack 
+ * Copyright (C) 2013-2015 David Herrmann 
+ * Copyright (C) 2013-2015 Linux Foundation
+ * Copyright (C) 2014-2015 Djalal Harouni 
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "bus.h"
+#include "connection.h"
+#include "endpoint.h"
+#include "handle.h"
+#include "match.h"
+#include "message.h"
+#include "metadata.h"
+#include "names.h"
+#include "domain.h"
+#include "item.h"
+#include "notify.h"
+#include "policy.h"
+#include "pool.h"
+#include "reply.h"
+#include "util.h"
+#include "queue.h"
+
+#define KDBUS_CONN_ACTIVE_BIAS (INT_MIN + 2)
+#define KDBUS_CONN_ACTIVE_NEW  (INT_MIN + 1)
+
+static struct kdbus_conn *kdbus_conn_new(struct kdbus_ep *ep, bool privileged,
+struct kdbus_cmd_hello *hello,
+const char *name,
+const struct kdbus_creds *creds,
+const struct kdbus_pids *pids,
+const char *seclabel,
+const char *conn_description)
+{
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+   static struct lock_class_key __key;
+#endif
+   struct kdbus_pool_slice *slice = NULL;
+   struct kdbus_bus *bus = ep->bus;
+   struct kdbus_conn *conn;
+   u64 attach_flags_send;
+   u64 attach_flags_recv;
+   u64 items_size = 0;
+   bool is_policy_holder;
+   bool is_activator;
+   bool is_monitor;
+   struct kvec kvec;
+   int ret;
+
+   struct {
+   u64 size;
+   u64 type;
+   struct kdbus_bloom_parameter bloom;
+   } bloom_item;
+
+   is_monitor = hello->flags & KDBUS_HELLO_MONITOR;
+   is_activator = hello->flags & KDBUS_HELLO_ACTIVATOR;
+   is_policy_holder = hello->flags & KDBUS_HELLO_POLICY_HOLDER;
+
+   if (!hello->pool_size || !IS_ALIGNED(hello->pool_size, PAGE_SIZE))
+   return ERR_PTR(-EINVAL);
+   if (is_monitor + is_activator + is_policy_holder > 1)
+   return ERR_PTR(-EINVAL);
+   if (name && !is_activator && !is_policy_holder)
+   return ERR_PTR(-EINVAL);
+   if (!name && (is_activator || is_policy_holder))
+   return ERR_PTR(-EINVAL);
+   if (name && !kdbus_name_is_valid(name, true))
+   return ERR_PTR(-EINVAL);
+   if (is_monitor && ep->user)
+   return ERR_PTR(-EOPNOTSUPP);
+   if (!privileged && (is_activator || is_policy_holder || is_monitor))
+   return ERR_PTR(-EPERM);
+   if ((creds || pids || seclabel) && !privileged)
+   return ERR_PTR(-EPERM);
+
+   ret = kdbus_sanitize_attach_flags(hello->attach_flags_send,
+ &attach_flags_send);
+   if (ret < 0)
+   return ERR_PTR(ret);
+
+   ret = kdbus_sanitize_attach_flags(hell

[PATCH 05/13] kdbus: add connection, queue handling and message validation code

2015-01-16 Thread Greg Kroah-Hartman
From: Daniel Mack 

This patch adds code to create and destroy connections, to validate
incoming messages and to maintain the queue of messages that are
associated with a connection.

Note that connection and queue have a 1:1 relation, the code is only
split in two parts for cleaner separation and better readability.

Signed-off-by: Daniel Mack 
Signed-off-by: David Herrmann 
Signed-off-by: Djalal Harouni 
Signed-off-by: Greg Kroah-Hartman 
---
 ipc/kdbus/connection.c | 2004 
 ipc/kdbus/connection.h |  262 +++
 ipc/kdbus/item.c   |  309 
 ipc/kdbus/item.h   |   57 ++
 ipc/kdbus/message.c|  598 +++
 ipc/kdbus/message.h|  133 
 ipc/kdbus/queue.c  |  505 
 ipc/kdbus/queue.h  |  108 +++
 ipc/kdbus/reply.c  |  262 +++
 ipc/kdbus/reply.h  |   68 ++
 ipc/kdbus/util.h   |2 +-
 11 files changed, 4307 insertions(+), 1 deletion(-)
 create mode 100644 ipc/kdbus/connection.c
 create mode 100644 ipc/kdbus/connection.h
 create mode 100644 ipc/kdbus/item.c
 create mode 100644 ipc/kdbus/item.h
 create mode 100644 ipc/kdbus/message.c
 create mode 100644 ipc/kdbus/message.h
 create mode 100644 ipc/kdbus/queue.c
 create mode 100644 ipc/kdbus/queue.h
 create mode 100644 ipc/kdbus/reply.c
 create mode 100644 ipc/kdbus/reply.h

diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
new file mode 100644
index ..75e2ea161a0e
--- /dev/null
+++ b/ipc/kdbus/connection.c
@@ -0,0 +1,2004 @@
+/*
+ * Copyright (C) 2013-2014 Kay Sievers
+ * Copyright (C) 2013-2014 Greg Kroah-Hartman 
+ * Copyright (C) 2013-2014 Daniel Mack 
+ * Copyright (C) 2013-2014 David Herrmann 
+ * Copyright (C) 2013-2014 Linux Foundation
+ * Copyright (C) 2014 Djalal Harouni 
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "bus.h"
+#include "connection.h"
+#include "endpoint.h"
+#include "match.h"
+#include "message.h"
+#include "metadata.h"
+#include "names.h"
+#include "domain.h"
+#include "item.h"
+#include "notify.h"
+#include "policy.h"
+#include "pool.h"
+#include "reply.h"
+#include "util.h"
+#include "queue.h"
+
+#define KDBUS_CONN_ACTIVE_BIAS (INT_MIN + 2)
+#define KDBUS_CONN_ACTIVE_NEW  (INT_MIN + 1)
+
+/*
+ * Check for maximum number of messages per individual user. This
+ * should prevent a single user from being able to fill the receiver's
+ * queue.
+ */
+static int kdbus_conn_queue_user_quota(const struct kdbus_conn *conn_src,
+  struct kdbus_conn *conn_dst,
+  struct kdbus_queue_entry *entry)
+{
+   struct kdbus_domain_user *user;
+
+   /*
+* When the kernel is the sender we do not do per user
+* accouting, instead we just count how many messages have
+* been queued and we check the quota limit when inserting
+* message into the receiver queue.
+*/
+   if (!conn_src)
+   return 0;
+
+   /*
+* Per-user accounting can be expensive if we have many different
+* users on the bus. Allow one set of messages to pass through
+* un-accounted. Only once we hit that limit, we start accounting.
+*/
+   if (conn_dst->queue.msg_count < KDBUS_CONN_MAX_MSGS_UNACCOUNTED)
+   return 0;
+
+   user = conn_src->user;
+
+   /* extend array to store the user message counters */
+   if (user->idr >= conn_dst->msg_users_max) {
+   unsigned int *users;
+   unsigned int i;
+
+   i = 8 + KDBUS_ALIGN8(user->idr);
+   users = krealloc(conn_dst->msg_users, i * sizeof(unsigned int),
+GFP_KERNEL | __GFP_ZERO);
+   if (!users)
+   return -ENOMEM;
+
+   conn_dst->msg_users = users;
+   conn_dst->msg_users_max = i;
+   }
+
+   if (conn_dst->msg_users[user->idr] >= KDBUS_CONN_MAX_MSGS_PER_USER)
+   return -ENOBUFS;
+
+   conn_dst->msg_users[user->idr]++;
+   entry->user = kdbus_domain_user_ref(user);
+   return 0;
+}
+
+/**
+ * kdbus_cmd_msg_recv() - receive a message from the queue
+ * @conn:  Connection to work on
+ * @recv:  The command as passed in by the ioctl
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int kdbus_cmd_msg_recv(struct kdbus_conn *conn,
+  struct kdbus_cmd_recv *recv)
+{
+   bool install = !(recv->flags & KDBUS_RECV_PEEK);
+   struct kdbus_queue_entry *entry

kdbus: add connection, queue handling and message validation code

2014-11-20 Thread Greg Kroah-Hartman
From: Daniel Mack 

This patch adds code to create and destroy connections, to validate
incoming messages and to maintain the queue of messages that are
associated with a connection.

Note that connection and queue have a 1:1 relation, the code is only
split in two parts for cleaner separation and better readability.

Signed-off-by: Daniel Mack 
Signed-off-by: David Herrmann 
Signed-off-by: Djalal Harouni 
Signed-off-by: Greg Kroah-Hartman 
---
 ipc/kdbus/connection.c | 1838 
 ipc/kdbus/connection.h |  188 +
 ipc/kdbus/item.c   |  258 +++
 ipc/kdbus/item.h   |   41 ++
 ipc/kdbus/message.c|  444 
 ipc/kdbus/message.h|   75 ++
 ipc/kdbus/queue.c  |  608 
 ipc/kdbus/queue.h  |   93 +++
 ipc/kdbus/util.h   |2 +-
 9 files changed, 3546 insertions(+), 1 deletion(-)
 create mode 100644 ipc/kdbus/connection.c
 create mode 100644 ipc/kdbus/connection.h
 create mode 100644 ipc/kdbus/item.c
 create mode 100644 ipc/kdbus/item.h
 create mode 100644 ipc/kdbus/message.c
 create mode 100644 ipc/kdbus/message.h
 create mode 100644 ipc/kdbus/queue.c
 create mode 100644 ipc/kdbus/queue.h

diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
new file mode 100644
index ..73d149eecc25
--- /dev/null
+++ b/ipc/kdbus/connection.c
@@ -0,0 +1,1838 @@
+/*
+ * Copyright (C) 2013-2014 Kay Sievers
+ * Copyright (C) 2013-2014 Greg Kroah-Hartman 
+ * Copyright (C) 2013-2014 Daniel Mack 
+ * Copyright (C) 2013-2014 David Herrmann 
+ * Copyright (C) 2013-2014 Linux Foundation
+ * Copyright (C) 2014 Djalal Harouni
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "bus.h"
+#include "connection.h"
+#include "endpoint.h"
+#include "match.h"
+#include "message.h"
+#include "metadata.h"
+#include "names.h"
+#include "domain.h"
+#include "item.h"
+#include "notify.h"
+#include "policy.h"
+#include "util.h"
+#include "queue.h"
+
+#define KDBUS_CONN_ACTIVE_BIAS (INT_MIN + 1)
+
+/**
+ * struct kdbus_conn_reply - an entry of kdbus_conn's list of replies
+ * @kref:  Ref-count of this object
+ * @entry: The entry of the connection's reply_list
+ * @reply_dst: The connection the reply will be sent to (method origin)
+ * @queue_entry:   The queue enty item that is prepared by the replying
+ * connection
+ * @deadline_ns:   The deadline of the reply, in nanoseconds
+ * @cookie:The cookie of the requesting message
+ * @name_id:   ID of the well-known name the original msg was sent to
+ * @sync:  The reply block is waiting for synchronous I/O
+ * @waiting:   The condition to synchronously wait for
+ * @interrupted:   The sync reply was left in an interrupted state
+ * @err:   The error code for the synchronous reply
+ */
+struct kdbus_conn_reply {
+   struct kref kref;
+   struct list_head entry;
+   struct kdbus_conn *reply_dst;
+   struct kdbus_queue_entry *queue_entry;
+   u64 deadline_ns;
+   u64 cookie;
+   u64 name_id;
+   bool sync:1;
+   bool waiting:1;
+   bool interrupted:1;
+   int err;
+};
+
+static struct kdbus_conn_reply *
+kdbus_conn_reply_new(struct kdbus_conn *reply_dst,
+const struct kdbus_msg *msg,
+struct kdbus_name_entry *name_entry)
+{
+   bool sync = msg->flags & KDBUS_MSG_FLAGS_SYNC_REPLY;
+   struct kdbus_conn_reply *r;
+   int ret = 0;
+
+   if (atomic_inc_return(&reply_dst->reply_count) >
+   KDBUS_CONN_MAX_REQUESTS_PENDING) {
+   ret = -EMLINK;
+   goto exit_dec_reply_count;
+   }
+
+   r = kzalloc(sizeof(*r), GFP_KERNEL);
+   if (!r) {
+   ret = -ENOMEM;
+   goto exit_dec_reply_count;
+   }
+
+   kref_init(&r->kref);
+   r->reply_dst = kdbus_conn_ref(reply_dst);
+   r->cookie = msg->cookie;
+   r->name_id = name_entry ? name_entry->name_id : 0;
+   r->deadline_ns = msg->timeout_ns;
+
+   if (sync) {
+   r->sync = true;
+   r->waiting = true;
+   }
+
+exit_dec_reply_count:
+   if (ret < 0) {
+   atomic_dec(&reply_dst->reply_count);
+   return ERR_PTR(ret);
+   }
+
+   return r;
+}
+
+static void __kdbus_conn_reply_free(struct kref *kref)
+{
+   struct kdbus_conn_reply *reply =
+   container_of(kref, struct kdbus_conn_reply, kref);
+
+   atomic_dec(&reply->reply_dst->reply_count);
+   kdbus_conn_unref(reply

Re: kdbus: add connection, queue handling and message validation code

2014-10-30 Thread Djalal Harouni
On Wed, Oct 29, 2014 at 08:55:58PM -0700, Andy Lutomirski wrote:
> On Wed, Oct 29, 2014 at 8:47 PM, Eric W. Biederman
>  wrote:
> > Greg Kroah-Hartman  writes:
> >
> >> From: Daniel Mack 
> >>
> >> This patch adds code to create and destroy connections, to validate
> >> incoming messages and to maintain the queue of messages that are
> >> associated with a connection.
> >>
> >> Note that connection and queue have a 1:1 relation, the code is only
> >> split in two parts for cleaner separation and better readability.
> >
> > You are not performing capability checks at open time.
> >
> > As such this API is suceptible to a host of file descriptor passing attacks.
> 
> To be fair, write(2) doesn't work on these fds, so the usual attacks
> don't work.  But who knows what absurd things kdbus clients will do
> with fd passing?
Yes, we use ioctl() so we are safe here! if there is a a suid process
that does perform arbitrary ioctl() on intrusted passed fds,
then we are already in truble given all the already available ioctl()
(not only kdbus, all available ioctl()... we blame the client), so yes
usual write()/read() do not work here.

But we do perform the creds check against the cred of connection
creation time, if you open the fd you do not have the connection,
you still need a KDBUS_CMD_HELLO ioctl() on the fd, and during that time
we store the creds, and we perform all the TALK, SEE and OWN against
those creds (uid/gid). It is like a second connect() call, unless you
perform the KDBUS_CMD_HELLO you are not connected, and after turning
your fd to a connection, a service can restrict its access (TALK, OWN
and SEE) policies, not all connected peers can TALK (send messages) to
a service.


-- 
Djalal Harouni
http://opendz.org
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: kdbus: add connection, queue handling and message validation code

2014-10-29 Thread Andy Lutomirski
On Wed, Oct 29, 2014 at 8:47 PM, Eric W. Biederman
 wrote:
> Greg Kroah-Hartman  writes:
>
>> From: Daniel Mack 
>>
>> This patch adds code to create and destroy connections, to validate
>> incoming messages and to maintain the queue of messages that are
>> associated with a connection.
>>
>> Note that connection and queue have a 1:1 relation, the code is only
>> split in two parts for cleaner separation and better readability.
>
> You are not performing capability checks at open time.
>
> As such this API is suceptible to a host of file descriptor passing attacks.

To be fair, write(2) doesn't work on these fds, so the usual attacks
don't work.  But who knows what absurd things kdbus clients will do
with fd passing?

--Andy

>
>> Signed-off-by: Daniel Mack 
>> Signed-off-by: Greg Kroah-Hartman 
>> ---
>
>> +/*
>> + * Check for maximum number of messages per individual user. This
>> + * should prevent a single user from being able to fill the receiver's
>> + * queue.
>> + */
>> +static int kdbus_conn_queue_user_quota(struct kdbus_conn *conn,
>> +const struct kdbus_conn *conn_src,
>> +struct kdbus_queue_entry *entry)
>> +{
>> + unsigned int user;
>> +
>> + if (!conn_src)
>> + return 0;
>> +
>> + if (ns_capable(&init_user_ns, CAP_IPC_OWNER))
>> + return 0;
>
>



-- 
Andy Lutomirski
AMA Capital Management, LLC
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


kdbus: add connection, queue handling and message validation code

2014-10-29 Thread Greg Kroah-Hartman
From: Daniel Mack 

This patch adds code to create and destroy connections, to validate
incoming messages and to maintain the queue of messages that are
associated with a connection.

Note that connection and queue have a 1:1 relation, the code is only
split in two parts for cleaner separation and better readability.

Signed-off-by: Daniel Mack 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/misc/kdbus/connection.c | 1751 +++
 drivers/misc/kdbus/connection.h |  177 
 drivers/misc/kdbus/item.c   |  256 ++
 drivers/misc/kdbus/item.h   |   40 +
 drivers/misc/kdbus/message.c|  420 ++
 drivers/misc/kdbus/message.h|   72 ++
 drivers/misc/kdbus/queue.c  |  602 ++
 drivers/misc/kdbus/queue.h  |   82 ++
 drivers/misc/kdbus/util.h   |2 +-
 9 files changed, 3401 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/kdbus/connection.c
 create mode 100644 drivers/misc/kdbus/connection.h
 create mode 100644 drivers/misc/kdbus/item.c
 create mode 100644 drivers/misc/kdbus/item.h
 create mode 100644 drivers/misc/kdbus/message.c
 create mode 100644 drivers/misc/kdbus/message.h
 create mode 100644 drivers/misc/kdbus/queue.c
 create mode 100644 drivers/misc/kdbus/queue.h

diff --git a/drivers/misc/kdbus/connection.c b/drivers/misc/kdbus/connection.c
new file mode 100644
index ..5b1f3ed51611
--- /dev/null
+++ b/drivers/misc/kdbus/connection.c
@@ -0,0 +1,1751 @@
+/*
+ * Copyright (C) 2013-2014 Kay Sievers
+ * Copyright (C) 2013-2014 Greg Kroah-Hartman 
+ * Copyright (C) 2013-2014 Daniel Mack 
+ * Copyright (C) 2013-2014 David Herrmann 
+ * Copyright (C) 2013-2014 Linux Foundation
+ * Copyright (C) 2014 Djalal Harouni
+ *
+ * kdbus is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "bus.h"
+#include "connection.h"
+#include "endpoint.h"
+#include "match.h"
+#include "message.h"
+#include "metadata.h"
+#include "names.h"
+#include "domain.h"
+#include "item.h"
+#include "notify.h"
+#include "policy.h"
+#include "util.h"
+#include "queue.h"
+
+struct kdbus_conn_reply;
+
+#define KDBUS_CONN_ACTIVE_BIAS (INT_MIN + 1)
+
+/**
+ * struct kdbus_conn_reply - an entry of kdbus_conn's list of replies
+ * @kref:  Ref-count of this object
+ * @entry: The entry of the connection's reply_list
+ * @reply_dst: The connection the reply will be sent to (method origin)
+ * @queue_entry:   The queue enty item that is prepared by the replying
+ * connection
+ * @deadline_ns:   The deadline of the reply, in nanoseconds
+ * @cookie:The cookie of the requesting message
+ * @name_id:   ID of the well-known name the original msg was sent to
+ * @sync:  The reply block is waiting for synchronous I/O
+ * @waiting:   The condition to synchronously wait for
+ * @interrupted:   The sync reply was left in an interrupted state
+ * @err:   The error code for the synchronous reply
+ */
+struct kdbus_conn_reply {
+   struct kref kref;
+   struct list_head entry;
+   struct kdbus_conn *reply_dst;
+   struct kdbus_queue_entry *queue_entry;
+   u64 deadline_ns;
+   u64 cookie;
+   u64 name_id;
+   bool sync:1;
+   bool waiting:1;
+   bool interrupted:1;
+   int err;
+};
+
+static int kdbus_conn_reply_new(struct kdbus_conn_reply **reply_wait,
+   struct kdbus_conn *reply_dst,
+   const struct kdbus_msg *msg,
+   struct kdbus_name_entry *name_entry)
+{
+   bool sync = msg->flags & KDBUS_MSG_FLAGS_SYNC_REPLY;
+   struct kdbus_conn_reply *r;
+   int ret = 0;
+
+   if (atomic_inc_return(&reply_dst->reply_count) >
+   KDBUS_CONN_MAX_REQUESTS_PENDING) {
+   ret = -EMLINK;
+   goto exit_dec_reply_count;
+   }
+
+   r = kzalloc(sizeof(*r), GFP_KERNEL);
+   if (!r) {
+   ret = -ENOMEM;
+   goto exit_dec_reply_count;
+   }
+
+   kref_init(&r->kref);
+   r->reply_dst = kdbus_conn_ref(reply_dst);
+   r->cookie = msg->cookie;
+   r->name_id = name_entry ? name_entry->name_id : 0;
+   r->deadline_ns = msg->timeout_ns;
+
+   if (sync) {
+   r->sync = true;
+   r->waiting = true;
+   }
+
+   *reply_wait = r;
+
+exit_dec_reply_count:
+   if (ret < 0)
+   atomic_dec(&reply_dst->reply_count);
+
+   return ret;
+}
+
+static void __kdbus_conn_reply_free(struct kref *kref)
+{
+