commit:     45ecdfc0d977755e3f15ba10a6b4fdb93581357b
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 27 19:50:31 2015 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Jun 27 19:50:31 2015 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=45ecdfc0

Update kdbus patch, rename for clarity

 0000_README                                        |    2 +-
 ...kdbus-4.1-rc1.patch => 5015_kdbus-6-27-15.patch | 1765 ++++++--------------
 2 files changed, 504 insertions(+), 1263 deletions(-)

diff --git a/0000_README b/0000_README
index d33ec2f..dd82b40 100644
--- a/0000_README
+++ b/0000_README
@@ -83,6 +83,6 @@ Patch:  
5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch
 From:   https://github.com/graysky2/kernel_gcc_patch/
 Desc:   Kernel patch enables gcc >= v4.9 optimizations for additional CPUs.
 
-Patch:  5015_kdbus-4.1-rc1.patch
+Patch:  5015_kdbus-6-27-15.patch
 From:   https://lkml.org
 Desc:   Kernel-level IPC implementation

diff --git a/5015_kdbus-4.1-rc1.patch b/5015_kdbus-6-27-15.patch
similarity index 96%
rename from 5015_kdbus-4.1-rc1.patch
rename to 5015_kdbus-6-27-15.patch
index a5169bd..bc17abe 100644
--- a/5015_kdbus-4.1-rc1.patch
+++ b/5015_kdbus-6-27-15.patch
@@ -1,15 +1,15 @@
 diff --git a/Documentation/Makefile b/Documentation/Makefile
-index 6883a1b..5e3fde6 100644
+index bc05482..e2127a7 100644
 --- a/Documentation/Makefile
 +++ b/Documentation/Makefile
 @@ -1,4 +1,4 @@
- subdir-y := accounting arm auxdisplay blackfin connector \
+ subdir-y := accounting auxdisplay blackfin connector \
 -      filesystems filesystems ia64 laptops mic misc-devices \
 +      filesystems filesystems ia64 kdbus laptops mic misc-devices \
        networking pcmcia prctl ptp spi timers vDSO video4linux \
        watchdog
 diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
-index 8136e1f..54e091e 100644
+index 51f4221..ec7c81b 100644
 --- a/Documentation/ioctl/ioctl-number.txt
 +++ b/Documentation/ioctl/ioctl-number.txt
 @@ -292,6 +292,7 @@ Code  Seq#(hex)    Include File            Comments
@@ -2262,7 +2262,7 @@ index 0000000..8c2a90e
 +</refentry>
 diff --git a/Documentation/kdbus/kdbus.item.xml 
b/Documentation/kdbus/kdbus.item.xml
 new file mode 100644
-index 0000000..09f8b90
+index 0000000..ee09dfa
 --- /dev/null
 +++ b/Documentation/kdbus/kdbus.item.xml
 @@ -0,0 +1,839 @@
@@ -2337,13 +2337,13 @@ index 0000000..09f8b90
 +#define KDBUS_ALIGN8(val) (((val) + 7) & ~7)
 +
 +#define KDBUS_ITEM_NEXT(item) \
-+    (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size))
++    (typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
 +
 +#define KDBUS_ITEM_FOREACH(item, head, first)                      \
-+    for (item = (head)->first;                                     \
++    for ((item) = (head)->first;                                   \
 +         ((uint8_t *)(item) < (uint8_t *)(head) + (head)->size) && \
 +          ((uint8_t *)(item) >= (uint8_t *)(head));                \
-+         item = KDBUS_ITEM_NEXT(item))
++         (item) = KDBUS_ITEM_NEXT(item))
 +      ]]></programlisting>
 +    </refsect2>
 +  </refsect1>
@@ -7450,10 +7450,10 @@ index 0000000..52565ea
 +      </template>
 +</stylesheet>
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 6239a30..e924246 100644
+index d8afd29..02f7668 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -5503,6 +5503,19 @@ S:      Maintained
+@@ -5585,6 +5585,19 @@ S:      Maintained
  F:    Documentation/kbuild/kconfig-language.txt
  F:    scripts/kconfig/
  
@@ -7474,10 +7474,10 @@ index 6239a30..e924246 100644
  M:    Vivek Goyal <[email protected]>
  M:    Haren Myneni <[email protected]>
 diff --git a/Makefile b/Makefile
-index 1100ff3..08c9818 100644
+index f5c8983..a1c8d57 100644
 --- a/Makefile
 +++ b/Makefile
-@@ -1350,6 +1350,7 @@ $(help-board-dirs): help-%:
+@@ -1343,6 +1343,7 @@ $(help-board-dirs): help-%:
  %docs: scripts_basic FORCE
        $(Q)$(MAKE) $(build)=scripts build_docproc
        $(Q)$(MAKE) $(build)=Documentation/DocBook $@
@@ -7486,10 +7486,10 @@ index 1100ff3..08c9818 100644
  else # KBUILD_EXTMOD
  
 diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
-index 68ceb97..ddc413e 100644
+index 1a0006a..4842a98 100644
 --- a/include/uapi/linux/Kbuild
 +++ b/include/uapi/linux/Kbuild
-@@ -214,6 +214,7 @@ header-y += ixjuser.h
+@@ -215,6 +215,7 @@ header-y += ixjuser.h
  header-y += jffs2.h
  header-y += joystick.h
  header-y += kcmp.h
@@ -8483,10 +8483,10 @@ index 0000000..00a6e14
 +
 +#endif /* _UAPI_KDBUS_H_ */
 diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h
-index 7d664ea..1cf05c0 100644
+index 7b1425a..ce2ac5a 100644
 --- a/include/uapi/linux/magic.h
 +++ b/include/uapi/linux/magic.h
-@@ -74,4 +74,6 @@
+@@ -76,4 +76,6 @@
  #define BTRFS_TEST_MAGIC      0x73727279
  #define NSFS_MAGIC            0x6e736673
  
@@ -8494,7 +8494,7 @@ index 7d664ea..1cf05c0 100644
 +
  #endif /* __LINUX_MAGIC_H__ */
 diff --git a/init/Kconfig b/init/Kconfig
-index f5dbc6d..6bda631 100644
+index dc24dec..9388071 100644
 --- a/init/Kconfig
 +++ b/init/Kconfig
 @@ -261,6 +261,19 @@ config POSIX_MQUEUE_SYSCTL
@@ -8557,10 +8557,10 @@ index 0000000..7ee9271
 +obj-$(CONFIG_KDBUS) += kdbus.o
 diff --git a/ipc/kdbus/bus.c b/ipc/kdbus/bus.c
 new file mode 100644
-index 0000000..9d0679e
+index 0000000..bbdf0f2
 --- /dev/null
 +++ b/ipc/kdbus/bus.c
-@@ -0,0 +1,560 @@
+@@ -0,0 +1,542 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -8848,8 +8848,6 @@ index 0000000..9d0679e
 +                      continue;
 +
 +              if (conn_src) {
-+                      u64 attach_flags;
-+
 +                      /*
 +                       * Anyone can send broadcasts, as they have no
 +                       * destination. But a receiver needs TALK access to
@@ -8858,19 +8856,12 @@ index 0000000..9d0679e
 +                      if (!kdbus_conn_policy_talk(conn_dst, NULL, conn_src))
 +                              continue;
 +
-+                      attach_flags = kdbus_meta_calc_attach_flags(conn_src,
-+                                                                  conn_dst);
-+
-+                      /*
-+                       * Keep sending messages even if we cannot acquire the
-+                       * requested metadata. It's up to the receiver to drop
-+                       * messages that lack expected metadata.
-+                       */
-+                      if (!conn_src->faked_meta)
-+                              kdbus_meta_proc_collect(kmsg->proc_meta,
-+                                                      attach_flags);
-+                      kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, conn_src,
-+                                              attach_flags);
++                      ret = kdbus_kmsg_collect_metadata(kmsg, conn_src,
++                                                        conn_dst);
++                      if (ret < 0) {
++                              kdbus_conn_lost_message(conn_dst);
++                              continue;
++                      }
 +              } else {
 +                      /*
 +                       * Check if there is a policy db that prevents the
@@ -8916,22 +8907,13 @@ index 0000000..9d0679e
 +
 +      down_read(&bus->conn_rwlock);
 +      list_for_each_entry(conn_dst, &bus->monitors_list, monitor_entry) {
-+              /*
-+               * Collect metadata requested by the destination connection.
-+               * Ignore errors, as receivers need to check metadata
-+               * availability, anyway. So it's still better to send messages
-+               * that lack data, than to skip it entirely.
-+               */
 +              if (conn_src) {
-+                      u64 attach_flags;
-+
-+                      attach_flags = kdbus_meta_calc_attach_flags(conn_src,
-+                                                                  conn_dst);
-+                      if (!conn_src->faked_meta)
-+                              kdbus_meta_proc_collect(kmsg->proc_meta,
-+                                                      attach_flags);
-+                      kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, conn_src,
-+                                              attach_flags);
++                      ret = kdbus_kmsg_collect_metadata(kmsg, conn_src,
++                                                        conn_dst);
++                      if (ret < 0) {
++                              kdbus_conn_lost_message(conn_dst);
++                              continue;
++                      }
 +              }
 +
 +              ret = kdbus_conn_entry_insert(conn_src, conn_dst, kmsg, NULL);
@@ -8946,7 +8928,7 @@ index 0000000..9d0679e
 + * @domain:           domain to operate on
 + * @argp:             command payload
 + *
-+ * Return: Newly created bus on success, ERR_PTR on failure.
++ * Return: NULL or newly created bus on success, ERR_PTR on failure.
 + */
 +struct kdbus_bus *kdbus_cmd_bus_make(struct kdbus_domain *domain,
 +                                   void __user *argp)
@@ -9040,7 +9022,7 @@ index 0000000..9d0679e
 + * @conn:             connection to operate on
 + * @argp:             command payload
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_bus_creator_info(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -9230,10 +9212,10 @@ index 0000000..5bea5ef
 +#endif
 diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
 new file mode 100644
-index 0000000..ab476fa
+index 0000000..9993753
 --- /dev/null
 +++ b/ipc/kdbus/connection.c
-@@ -0,0 +1,2214 @@
+@@ -0,0 +1,2178 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -9668,7 +9650,7 @@ index 0000000..ab476fa
 +       * directly, and won't cause any notifications.
 +       */
 +      if (!kdbus_conn_is_monitor(conn)) {
-+              ret = kdbus_notify_id_change(conn->ep->bus, KDBUS_ITEM_ID_ADD,
++              ret = kdbus_notify_id_change(bus, KDBUS_ITEM_ID_ADD,
 +                                           conn->id, conn->flags);
 +              if (ret < 0)
 +                      goto exit_disconnect;
@@ -9795,17 +9777,16 @@ index 0000000..ab476fa
 +      hash_for_each(bus->conn_hash, i, c, hentry) {
 +              mutex_lock(&c->lock);
 +              list_for_each_entry_safe(r, r_tmp, &c->reply_list, entry) {
-+                      if (r->reply_src == conn) {
-+                              if (r->sync) {
-+                                      kdbus_sync_reply_wakeup(r, -EPIPE);
-+                                      kdbus_reply_unlink(r);
-+                                      continue;
-+                              }
++                      if (r->reply_src != conn)
++                              continue;
 +
++                      if (r->sync)
++                              kdbus_sync_reply_wakeup(r, -EPIPE);
++                      else
 +                              /* send a 'connection dead' notification */
 +                              kdbus_notify_reply_dead(bus, c->id, r->cookie);
-+                              kdbus_reply_unlink(r);
-+                      }
++
++                      kdbus_reply_unlink(r);
 +              }
 +              mutex_unlock(&c->lock);
 +      }
@@ -9989,7 +9970,7 @@ index 0000000..ab476fa
 + *
 + * kdbus is reliable. That means, we try hard to never lose messages. However,
 + * memory is limited, so we cannot rely on transmissions to never fail.
-+ * Therefore, we use quota-limits to let callers know if there unicast message
++ * Therefore, we use quota-limits to let callers know if their unicast message
 + * cannot be transmitted to a peer. This works fine for unicasts, but for
 + * broadcasts we cannot make the caller handle the transmission failure.
 + * Instead, we must let the destination know that it couldn't receive a
@@ -10011,8 +9992,6 @@ index 0000000..ab476fa
 +                    const struct kdbus_kmsg *kmsg,
 +                    struct kdbus_user *user)
 +{
-+      struct kdbus_queue_entry *entry;
-+
 +      /* The remote connection was disconnected */
 +      if (!kdbus_conn_active(conn_dst))
 +              return ERR_PTR(-ECONNRESET);
@@ -10029,11 +10008,7 @@ index 0000000..ab476fa
 +          kmsg->res && kmsg->res->fds_count > 0)
 +              return ERR_PTR(-ECOMM);
 +
-+      entry = kdbus_queue_entry_new(conn_dst, kmsg, user);
-+      if (IS_ERR(entry))
-+              return entry;
-+
-+      return entry;
++      return kdbus_queue_entry_new(conn_dst, kmsg, user);
 +}
 +
 +/*
@@ -10334,7 +10309,6 @@ index 0000000..ab476fa
 +      struct kdbus_reply *reply, *wake = NULL;
 +      struct kdbus_conn *dst = NULL;
 +      struct kdbus_bus *bus = src->ep->bus;
-+      u64 attach;
 +      int ret;
 +
 +      if (WARN_ON(kmsg->msg.dst_id == KDBUS_DST_ID_BROADCAST) ||
@@ -10367,15 +10341,7 @@ index 0000000..ab476fa
 +
 +      /* attach metadata */
 +
-+      attach = kdbus_meta_calc_attach_flags(src, dst);
-+
-+      if (!src->faked_meta) {
-+              ret = kdbus_meta_proc_collect(kmsg->proc_meta, attach);
-+              if (ret < 0)
-+                      goto exit;
-+      }
-+
-+      ret = kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, src, attach);
++      ret = kdbus_kmsg_collect_metadata(kmsg, src, dst);
 +      if (ret < 0)
 +              goto exit;
 +
@@ -10403,7 +10369,6 @@ index 0000000..ab476fa
 +      struct kdbus_reply *wait = NULL;
 +      struct kdbus_conn *dst = NULL;
 +      struct kdbus_bus *bus = src->ep->bus;
-+      u64 attach;
 +      int ret;
 +
 +      if (WARN_ON(kmsg->msg.dst_id == KDBUS_DST_ID_BROADCAST) ||
@@ -10454,15 +10419,7 @@ index 0000000..ab476fa
 +
 +      /* attach metadata */
 +
-+      attach = kdbus_meta_calc_attach_flags(src, dst);
-+
-+      if (!src->faked_meta) {
-+              ret = kdbus_meta_proc_collect(kmsg->proc_meta, attach);
-+              if (ret < 0)
-+                      goto exit;
-+      }
-+
-+      ret = kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, src, attach);
++      ret = kdbus_kmsg_collect_metadata(kmsg, src, dst);
 +      if (ret < 0)
 +              goto exit;
 +
@@ -10493,7 +10450,6 @@ index 0000000..ab476fa
 +      struct kdbus_conn *dst = NULL;
 +      struct kdbus_bus *bus = src->ep->bus;
 +      bool is_signal = (kmsg->msg.flags & KDBUS_MSG_SIGNAL);
-+      u64 attach;
 +      int ret = 0;
 +
 +      if (WARN_ON(kmsg->msg.dst_id == KDBUS_DST_ID_BROADCAST) ||
@@ -10532,16 +10488,8 @@ index 0000000..ab476fa
 +
 +      /* attach metadata */
 +
-+      attach = kdbus_meta_calc_attach_flags(src, dst);
-+
-+      if (!src->faked_meta) {
-+              ret = kdbus_meta_proc_collect(kmsg->proc_meta, attach);
-+              if (ret < 0 && !is_signal)
-+                      goto exit;
-+      }
-+
-+      ret = kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, src, attach);
-+      if (ret < 0 && !is_signal)
++      ret = kdbus_kmsg_collect_metadata(kmsg, src, dst);
++      if (ret < 0)
 +              goto exit;
 +
 +      /* send message */
@@ -10824,10 +10772,8 @@ index 0000000..ab476fa
 +       *     to a peer if, and only if, that peer can see the name this
 +       *     notification is for.
 +       *
-+       * KDBUS_ITEM_ID_{ADD,REMOVE}: As new peers cannot have names, and all
-+       *     names are dropped before a peer is removed, those notifications
-+       *     cannot be seen on custom endpoints. Thus, we only pass them
-+       *     through on default endpoints.
++       * KDBUS_ITEM_ID_{ADD,REMOVE}: Notifications for ID changes are
++       *     broadcast to everyone, to allow tracking peers.
 +       */
 +
 +      switch (kmsg->notify_type) {
@@ -10839,7 +10785,7 @@ index 0000000..ab476fa
 +
 +      case KDBUS_ITEM_ID_ADD:
 +      case KDBUS_ITEM_ID_REMOVE:
-+              return !conn->ep->user;
++              return true;
 +
 +      default:
 +              WARN(1, "Invalid type for notification broadcast: %llu\n",
@@ -10854,7 +10800,7 @@ index 0000000..ab476fa
 + * @privileged:               Whether the caller is privileged
 + * @argp:             Command payload
 + *
-+ * Return: Newly created connection on success, ERR_PTR on failure.
++ * Return: NULL or newly created connection on success, ERR_PTR on failure.
 + */
 +struct kdbus_conn *kdbus_cmd_hello(struct kdbus_ep *ep, bool privileged,
 +                                 void __user *argp)
@@ -10941,7 +10887,7 @@ index 0000000..ab476fa
 + *
 + * The caller must not hold any active reference to @conn or this will 
deadlock.
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_byebye_unlocked(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -10973,7 +10919,7 @@ index 0000000..ab476fa
 + * @conn:             connection to operate on
 + * @argp:             command payload
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_conn_info(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -11103,7 +11049,7 @@ index 0000000..ab476fa
 + * @conn:             connection to operate on
 + * @argp:             command payload
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_update(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -11200,7 +11146,7 @@ index 0000000..ab476fa
 + * @f:                        file this command was called on
 + * @argp:             command payload
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_send(struct kdbus_conn *conn, struct file *f, void __user *argp)
 +{
@@ -11296,7 +11242,7 @@ index 0000000..ab476fa
 + * @conn:             connection to operate on
 + * @argp:             command payload
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_recv(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -11419,7 +11365,7 @@ index 0000000..ab476fa
 + * @conn:             connection to operate on
 + * @argp:             command payload
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_free(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -12098,7 +12044,7 @@ index 0000000..447a2bd
 +#endif
 diff --git a/ipc/kdbus/endpoint.c b/ipc/kdbus/endpoint.c
 new file mode 100644
-index 0000000..174d274
+index 0000000..9a95a5e
 --- /dev/null
 +++ b/ipc/kdbus/endpoint.c
 @@ -0,0 +1,275 @@
@@ -12292,7 +12238,7 @@ index 0000000..174d274
 + * @bus:              bus to operate on
 + * @argp:             command payload
 + *
-+ * Return: Newly created endpoint on success, ERR_PTR on failure.
++ * Return: NULL or newly created endpoint on success, ERR_PTR on failure.
 + */
 +struct kdbus_ep *kdbus_cmd_ep_make(struct kdbus_bus *bus, void __user *argp)
 +{
@@ -12351,7 +12297,7 @@ index 0000000..174d274
 + * @ep:                       endpoint to operate on
 + * @argp:             command payload
 + *
-+ * Return: Newly created endpoint on success, ERR_PTR on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_ep_update(struct kdbus_ep *ep, void __user *argp)
 +{
@@ -13002,10 +12948,10 @@ index 0000000..62f7d6a
 +#endif
 diff --git a/ipc/kdbus/handle.c b/ipc/kdbus/handle.c
 new file mode 100644
-index 0000000..f72dbe5
+index 0000000..0752799
 --- /dev/null
 +++ b/ipc/kdbus/handle.c
-@@ -0,0 +1,617 @@
+@@ -0,0 +1,702 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -13026,6 +12972,7 @@ index 0000000..f72dbe5
 +#include <linux/init.h>
 +#include <linux/kdev_t.h>
 +#include <linux/module.h>
++#include <linux/mutex.h>
 +#include <linux/poll.h>
 +#include <linux/rwsem.h>
 +#include <linux/sched.h>
@@ -13079,10 +13026,6 @@ index 0000000..f72dbe5
 +      if (!KDBUS_ITEMS_END(item, args->items, args->items_size))
 +              return -EINVAL;
 +
-+      for (i = 0; i < args->argc; ++i)
-+              if (args->argv[i].mandatory && !args->argv[i].item)
-+                      return -EINVAL;
-+
 +      return 0;
 +}
 +
@@ -13157,11 +13100,32 @@ index 0000000..f72dbe5
 +int __kdbus_args_parse(struct kdbus_args *args, void __user *argp,
 +                     size_t type_size, size_t items_offset, void **out)
 +{
-+      int ret;
++      u64 user_size;
++      int ret, i;
++
++      ret = kdbus_copy_from_user(&user_size, argp, sizeof(user_size));
++      if (ret < 0)
++              return ret;
++
++      if (user_size < type_size)
++              return -EINVAL;
++      if (user_size > KDBUS_CMD_MAX_SIZE)
++              return -EMSGSIZE;
++
++      if (user_size <= sizeof(args->cmd_buf)) {
++              if (copy_from_user(args->cmd_buf, argp, user_size))
++                      return -EFAULT;
++              args->cmd = (void*)args->cmd_buf;
++      } else {
++              args->cmd = memdup_user(argp, user_size);
++              if (IS_ERR(args->cmd))
++                      return PTR_ERR(args->cmd);
++      }
 +
-+      args->cmd = kdbus_memdup_user(argp, type_size, KDBUS_CMD_MAX_SIZE);
-+      if (IS_ERR(args->cmd))
-+              return PTR_ERR(args->cmd);
++      if (args->cmd->size != user_size) {
++              ret = -EINVAL;
++              goto error;
++      }
 +
 +      args->cmd->return_flags = 0;
 +      args->user = argp;
@@ -13181,6 +13145,15 @@ index 0000000..f72dbe5
 +      if (ret < 0)
 +              goto error;
 +
++      /* mandatory items must be given (but not on negotiation) */
++      if (!(args->cmd->flags & KDBUS_FLAG_NEGOTIATE)) {
++              for (i = 0; i < args->argc; ++i)
++                      if (args->argv[i].mandatory && !args->argv[i].item) {
++                              ret = -EINVAL;
++                              goto error;
++                      }
++      }
++
 +      *out = args->cmd;
 +      return !!(args->cmd->flags & KDBUS_FLAG_NEGOTIATE);
 +
@@ -13209,7 +13182,8 @@ index 0000000..f72dbe5
 +              if (put_user(args->cmd->return_flags,
 +                           &args->user->return_flags))
 +                      ret = -EFAULT;
-+              kfree(args->cmd);
++              if (args->cmd != (void*)args->cmd_buf)
++                      kfree(args->cmd);
 +              args->cmd = NULL;
 +      }
 +
@@ -13232,7 +13206,7 @@ index 0000000..f72dbe5
 +
 +/**
 + * struct kdbus_handle - handle to the kdbus system
-+ * @rwlock:           handle lock
++ * @lock:             handle lock
 + * @type:             type of this handle (KDBUS_HANDLE_*)
 + * @bus_owner:                bus this handle owns
 + * @ep_owner:         endpoint this handle owns
@@ -13240,7 +13214,7 @@ index 0000000..f72dbe5
 + * @privileged:               Flag to mark a handle as privileged
 + */
 +struct kdbus_handle {
-+      struct rw_semaphore rwlock;
++      struct mutex lock;
 +
 +      enum kdbus_handle_type type;
 +      union {
@@ -13268,7 +13242,7 @@ index 0000000..f72dbe5
 +              goto exit;
 +      }
 +
-+      init_rwsem(&handle->rwlock);
++      mutex_init(&handle->lock);
 +      handle->type = KDBUS_HANDLE_NONE;
 +
 +      if (node->type == KDBUS_NODE_ENDPOINT) {
@@ -13358,8 +13332,8 @@ index 0000000..f72dbe5
 +                      break;
 +              }
 +
-+              handle->type = KDBUS_HANDLE_BUS_OWNER;
 +              handle->bus_owner = bus;
++              ret = KDBUS_HANDLE_BUS_OWNER;
 +              break;
 +      }
 +
@@ -13399,8 +13373,8 @@ index 0000000..f72dbe5
 +                      break;
 +              }
 +
-+              handle->type = KDBUS_HANDLE_EP_OWNER;
 +              handle->ep_owner = ep;
++              ret = KDBUS_HANDLE_EP_OWNER;
 +              break;
 +
 +      case KDBUS_CMD_HELLO:
@@ -13410,8 +13384,8 @@ index 0000000..f72dbe5
 +                      break;
 +              }
 +
-+              handle->type = KDBUS_HANDLE_CONNECTED;
 +              handle->conn = conn;
++              ret = KDBUS_HANDLE_CONNECTED;
 +              break;
 +
 +      default:
@@ -13525,19 +13499,41 @@ index 0000000..f72dbe5
 +      case KDBUS_CMD_BUS_MAKE:
 +      case KDBUS_CMD_ENDPOINT_MAKE:
 +      case KDBUS_CMD_HELLO:
-+              /* bail out early if already typed */
-+              if (handle->type != KDBUS_HANDLE_NONE)
-+                      break;
-+
-+              down_write(&handle->rwlock);
++              mutex_lock(&handle->lock);
 +              if (handle->type == KDBUS_HANDLE_NONE) {
 +                      if (node->type == KDBUS_NODE_CONTROL)
 +                              ret = kdbus_handle_ioctl_control(file, cmd,
 +                                                               argp);
 +                      else if (node->type == KDBUS_NODE_ENDPOINT)
 +                              ret = kdbus_handle_ioctl_ep(file, cmd, argp);
++
++                      if (ret > 0) {
++                              /*
++                               * The data given via open() is not sufficient
++                               * to setup a kdbus handle. Hence, we require
++                               * the user to perform a setup ioctl. This setup
++                               * can only be performed once and defines the
++                               * type of the handle. The different setup
++                               * ioctls are locked against each other so they
++                               * cannot race. Once the handle type is set,
++                               * the type-dependent ioctls are enabled. To
++                               * improve performance, we don't lock those via
++                               * handle->lock. Instead, we issue a
++                               * write-barrier before performing the
++                               * type-change, which pairs with smp_rmb() in
++                               * all handlers that access the type field. This
++                               * guarantees the handle is fully setup, if
++                               * handle->type is set. If handle->type is
++                               * unset, you must not make any assumptions
++                               * without taking handle->lock.
++                               * Note that handle->type is only set once. It
++                               * will never change afterwards.
++                               */
++                              smp_wmb();
++                              handle->type = ret;
++                      }
 +              }
-+              up_write(&handle->rwlock);
++              mutex_unlock(&handle->lock);
 +              break;
 +
 +      case KDBUS_CMD_ENDPOINT_UPDATE:
@@ -13552,14 +13548,30 @@ index 0000000..f72dbe5
 +      case KDBUS_CMD_MATCH_REMOVE:
 +      case KDBUS_CMD_SEND:
 +      case KDBUS_CMD_RECV:
-+      case KDBUS_CMD_FREE:
-+              down_read(&handle->rwlock);
-+              if (handle->type == KDBUS_HANDLE_EP_OWNER)
++      case KDBUS_CMD_FREE: {
++              enum kdbus_handle_type type;
++
++              /*
++               * This read-barrier pairs with smp_wmb() of the handle setup.
++               * it guarantees the handle is fully written, in case the
++               * type has been set. It allows us to access the handle without
++               * taking handle->lock, given the guarantee that the type is
++               * only ever set once, and stays constant afterwards.
++               * Furthermore, the handle object itself is not modified in any
++               * way after the type is set. That is, the type-field is the
++               * last field that is written on any handle. If it has not been
++               * set, we must not access the handle here.
++               */
++              type = handle->type;
++              smp_rmb();
++
++              if (type == KDBUS_HANDLE_EP_OWNER)
 +                      ret = kdbus_handle_ioctl_ep_owner(file, cmd, argp);
-+              else if (handle->type == KDBUS_HANDLE_CONNECTED)
++              else if (type == KDBUS_HANDLE_CONNECTED)
 +                      ret = kdbus_handle_ioctl_connected(file, cmd, argp);
-+              up_read(&handle->rwlock);
++
 +              break;
++      }
 +      default:
 +              ret = -ENOTTY;
 +              break;
@@ -13572,42 +13584,61 @@ index 0000000..f72dbe5
 +                                    struct poll_table_struct *wait)
 +{
 +      struct kdbus_handle *handle = file->private_data;
++      enum kdbus_handle_type type;
 +      unsigned int mask = POLLOUT | POLLWRNORM;
-+      int ret;
 +
-+      /* Only a connected endpoint can read/write data */
-+      down_read(&handle->rwlock);
-+      if (handle->type != KDBUS_HANDLE_CONNECTED) {
-+              up_read(&handle->rwlock);
-+              return POLLERR | POLLHUP;
-+      }
-+      up_read(&handle->rwlock);
++      /*
++       * This pairs with smp_wmb() during handle setup. It guarantees that
++       * _iff_ the handle type is set, handle->conn is valid. Furthermore,
++       * _iff_ the type is set, the handle object is constant and never
++       * changed again. If it's not set, we must not access the handle but
++       * bail out. We also must assume no setup has taken place, yet.
++       */
++      type = handle->type;
++      smp_rmb();
 +
-+      ret = kdbus_conn_acquire(handle->conn);
-+      if (ret < 0)
++      /* Only a connected endpoint can read/write data */
++      if (type != KDBUS_HANDLE_CONNECTED)
 +              return POLLERR | POLLHUP;
 +
 +      poll_wait(file, &handle->conn->wait, wait);
 +
++      /*
++       * Verify the connection hasn't been deactivated _after_ adding the
++       * wait-queue. This guarantees, that if the connection is deactivated
++       * after we checked it, the waitqueue is signaled and we're called
++       * again.
++       */
++      if (!kdbus_conn_active(handle->conn))
++              return POLLERR | POLLHUP;
++
 +      if (!list_empty(&handle->conn->queue.msg_list) ||
 +          atomic_read(&handle->conn->lost_count) > 0)
 +              mask |= POLLIN | POLLRDNORM;
 +
-+      kdbus_conn_release(handle->conn);
-+
 +      return mask;
 +}
 +
 +static int kdbus_handle_mmap(struct file *file, struct vm_area_struct *vma)
 +{
 +      struct kdbus_handle *handle = file->private_data;
++      enum kdbus_handle_type type;
 +      int ret = -EBADFD;
 +
-+      if (down_read_trylock(&handle->rwlock)) {
-+              if (handle->type == KDBUS_HANDLE_CONNECTED)
-+                      ret = kdbus_pool_mmap(handle->conn->pool, vma);
-+              up_read(&handle->rwlock);
-+      }
++      /*
++       * This pairs with smp_wmb() during handle setup. It guarantees that
++       * _iff_ the handle type is set, handle->conn is valid. Furthermore,
++       * _iff_ the type is set, the handle object is constant and never
++       * changed again. If it's not set, we must not access the handle but
++       * bail out. We also must assume no setup has taken place, yet.
++       */
++      type = handle->type;
++      smp_rmb();
++
++      /* Only connected handles have a pool we can map */
++      if (type == KDBUS_HANDLE_CONNECTED)
++              ret = kdbus_pool_mmap(handle->conn->pool, vma);
++
 +      return ret;
 +}
 +
@@ -13625,10 +13656,10 @@ index 0000000..f72dbe5
 +};
 diff --git a/ipc/kdbus/handle.h b/ipc/kdbus/handle.h
 new file mode 100644
-index 0000000..93a372d
+index 0000000..13c59d9
 --- /dev/null
 +++ b/ipc/kdbus/handle.h
-@@ -0,0 +1,85 @@
+@@ -0,0 +1,90 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -13676,6 +13707,7 @@ index 0000000..93a372d
 + * @argv:             array of items this command supports
 + * @user:             set by parser to user-space location of current command
 + * @cmd:              set by parser to kernel copy of command payload
++ * @cmd_buf:          512 bytes inline buf to avoid kmalloc() on small cmds
 + * @items:            points to item array in @cmd
 + * @items_size:               size of @items in bytes
 + *
@@ -13683,6 +13715,9 @@ index 0000000..93a372d
 + * The ioctl handler has to pre-fill the flags and allowed items before 
passing
 + * the object to kdbus_args_parse(). The parser will copy the command payload
 + * into kernel-space and verify the correctness of the data.
++ *
++ * We use a 512 bytes buffer for small command payloads, to be allocated on
++ * stack on syscall entrance.
 + */
 +struct kdbus_args {
 +      u64 allowed_flags;
@@ -13691,6 +13726,7 @@ index 0000000..93a372d
 +
 +      struct kdbus_cmd __user *user;
 +      struct kdbus_cmd *cmd;
++      u8 cmd_buf[512];
 +
 +      struct kdbus_item *items;
 +      size_t items_size;
@@ -13716,10 +13752,10 @@ index 0000000..93a372d
 +#endif
 diff --git a/ipc/kdbus/item.c b/ipc/kdbus/item.c
 new file mode 100644
-index 0000000..745ad54
+index 0000000..1ee72c2
 --- /dev/null
 +++ b/ipc/kdbus/item.c
-@@ -0,0 +1,339 @@
+@@ -0,0 +1,333 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -13818,12 +13854,6 @@ index 0000000..745ad54
 +              break;
 +
 +      case KDBUS_ITEM_PAYLOAD_VEC:
-+              if (payload_size != sizeof(struct kdbus_vec))
-+                      return -EINVAL;
-+              if (item->vec.size == 0 || item->vec.size > SIZE_MAX)
-+                      return -EINVAL;
-+              break;
-+
 +      case KDBUS_ITEM_PAYLOAD_OFF:
 +              if (payload_size != sizeof(struct kdbus_vec))
 +                      return -EINVAL;
@@ -14061,7 +14091,7 @@ index 0000000..745ad54
 +}
 diff --git a/ipc/kdbus/item.h b/ipc/kdbus/item.h
 new file mode 100644
-index 0000000..eeefd8b
+index 0000000..bca63b4
 --- /dev/null
 +++ b/ipc/kdbus/item.h
 @@ -0,0 +1,64 @@
@@ -14088,17 +14118,17 @@ index 0000000..eeefd8b
 +#include "util.h"
 +
 +/* generic access and iterators over a stream of items */
-+#define KDBUS_ITEM_NEXT(_i) (typeof(_i))(((u8 *)_i) + 
KDBUS_ALIGN8((_i)->size))
-+#define KDBUS_ITEMS_SIZE(_h, _is) ((_h)->size - offsetof(typeof(*_h), _is))
++#define KDBUS_ITEM_NEXT(_i) (typeof(_i))((u8 *)(_i) + 
KDBUS_ALIGN8((_i)->size))
++#define KDBUS_ITEMS_SIZE(_h, _is) ((_h)->size - offsetof(typeof(*(_h)), _is))
 +#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
 +#define KDBUS_ITEM_SIZE(_s) KDBUS_ALIGN8(KDBUS_ITEM_HEADER_SIZE + (_s))
 +#define KDBUS_ITEM_PAYLOAD_SIZE(_i) ((_i)->size - KDBUS_ITEM_HEADER_SIZE)
 +
 +#define KDBUS_ITEMS_FOREACH(_i, _is, _s)                              \
-+      for (_i = _is;                                                  \
++      for ((_i) = (_is);                                              \
 +           ((u8 *)(_i) < (u8 *)(_is) + (_s)) &&                       \
 +             ((u8 *)(_i) >= (u8 *)(_is));                             \
-+           _i = KDBUS_ITEM_NEXT(_i))
++           (_i) = KDBUS_ITEM_NEXT(_i))
 +
 +#define KDBUS_ITEM_VALID(_i, _is, _s)                                 \
 +      ((_i)->size >= KDBUS_ITEM_HEADER_SIZE &&                        \
@@ -14107,7 +14137,7 @@ index 0000000..eeefd8b
 +       (u8 *)(_i) >= (u8 *)(_is))
 +
 +#define KDBUS_ITEMS_END(_i, _is, _s)                                  \
-+      ((u8 *)_i == ((u8 *)(_is) + KDBUS_ALIGN8(_s)))
++      ((u8 *)(_i) == ((u8 *)(_is) + KDBUS_ALIGN8(_s)))
 +
 +/**
 + * struct kdbus_item_header - Describes the fix part of an item
@@ -14201,10 +14231,10 @@ index 0000000..6450f58
 +#endif
 diff --git a/ipc/kdbus/main.c b/ipc/kdbus/main.c
 new file mode 100644
-index 0000000..785f529
+index 0000000..1ad4dc8
 --- /dev/null
 +++ b/ipc/kdbus/main.c
-@@ -0,0 +1,125 @@
+@@ -0,0 +1,114 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -14222,7 +14252,6 @@ index 0000000..785f529
 +#include <linux/fs.h>
 +#include <linux/init.h>
 +#include <linux/module.h>
-+#include <linux/moduleparam.h>
 +
 +#include "util.h"
 +#include "fs.h"
@@ -14286,17 +14315,6 @@ index 0000000..785f529
 +/* kdbus mount-point /sys/fs/kdbus */
 +static struct kobject *kdbus_dir;
 +
-+/* global module option to apply a mask to exported metadata */
-+unsigned long long kdbus_meta_attach_mask = KDBUS_ATTACH_TIMESTAMP |
-+                                          KDBUS_ATTACH_CREDS |
-+                                          KDBUS_ATTACH_PIDS |
-+                                          KDBUS_ATTACH_AUXGROUPS |
-+                                          KDBUS_ATTACH_NAMES |
-+                                          KDBUS_ATTACH_SECLABEL |
-+                                          KDBUS_ATTACH_CONN_DESCRIPTION;
-+MODULE_PARM_DESC(attach_flags_mask, "Attach-flags mask for exported 
metadata");
-+module_param_named(attach_flags_mask, kdbus_meta_attach_mask, ullong, 0644);
-+
 +static int __init kdbus_init(void)
 +{
 +      int ret;
@@ -14323,6 +14341,7 @@ index 0000000..785f529
 +{
 +      kdbus_fs_exit();
 +      kobject_put(kdbus_dir);
++      ida_destroy(&kdbus_node_ida);
 +}
 +
 +module_init(kdbus_init);
@@ -14332,7 +14351,7 @@ index 0000000..785f529
 +MODULE_ALIAS_FS(KBUILD_MODNAME "fs");
 diff --git a/ipc/kdbus/match.c b/ipc/kdbus/match.c
 new file mode 100644
-index 0000000..30cec1c
+index 0000000..cc083b4
 --- /dev/null
 +++ b/ipc/kdbus/match.c
 @@ -0,0 +1,559 @@
@@ -14706,7 +14725,7 @@ index 0000000..30cec1c
 + * are used to match messages from userspace, while the others apply to
 + * kernel-generated notifications.
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_match_add(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -14866,7 +14885,7 @@ index 0000000..30cec1c
 + * @conn:             connection to operate on
 + * @argp:             command payload
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_match_remove(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -14938,10 +14957,10 @@ index 0000000..ea42929
 +#endif
 diff --git a/ipc/kdbus/message.c b/ipc/kdbus/message.c
 new file mode 100644
-index 0000000..8096075
+index 0000000..066e816
 --- /dev/null
 +++ b/ipc/kdbus/message.c
-@@ -0,0 +1,616 @@
+@@ -0,0 +1,640 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -15558,12 +15577,36 @@ index 0000000..8096075
 +      kdbus_kmsg_free(m);
 +      return ERR_PTR(ret);
 +}
++
++/**
++ * kdbus_kmsg_collect_metadata() - collect metadata
++ * @kmsg:     message to collect metadata on
++ * @src:      source connection of message
++ * @dst:      destination connection of message
++ *
++ * Return: 0 on success, negative error code on failure.
++ */
++int kdbus_kmsg_collect_metadata(struct kdbus_kmsg *kmsg, struct kdbus_conn 
*src,
++                              struct kdbus_conn *dst)
++{
++      u64 attach;
++      int ret;
++
++      attach = kdbus_meta_calc_attach_flags(src, dst);
++      if (!src->faked_meta) {
++              ret = kdbus_meta_proc_collect(kmsg->proc_meta, attach);
++              if (ret < 0)
++                      return ret;
++      }
++
++      return kdbus_meta_conn_collect(kmsg->conn_meta, kmsg, src, attach);
++}
 diff --git a/ipc/kdbus/message.h b/ipc/kdbus/message.h
 new file mode 100644
-index 0000000..af47758
+index 0000000..cdaa65c
 --- /dev/null
 +++ b/ipc/kdbus/message.h
-@@ -0,0 +1,133 @@
+@@ -0,0 +1,135 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -15695,14 +15738,16 @@ index 0000000..af47758
 +struct kdbus_kmsg *kdbus_kmsg_new_from_cmd(struct kdbus_conn *conn,
 +                                         struct kdbus_cmd_send *cmd_send);
 +void kdbus_kmsg_free(struct kdbus_kmsg *kmsg);
++int kdbus_kmsg_collect_metadata(struct kdbus_kmsg *kmsg, struct kdbus_conn 
*src,
++                              struct kdbus_conn *dst);
 +
 +#endif
 diff --git a/ipc/kdbus/metadata.c b/ipc/kdbus/metadata.c
 new file mode 100644
-index 0000000..3adc6c2
+index 0000000..c36b9cc
 --- /dev/null
 +++ b/ipc/kdbus/metadata.c
-@@ -0,0 +1,1159 @@
+@@ -0,0 +1,1184 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -15734,7 +15779,6 @@ index 0000000..3adc6c2
 +#include <linux/uidgid.h>
 +#include <linux/uio.h>
 +#include <linux/user_namespace.h>
-+#include <linux/version.h>
 +
 +#include "bus.h"
 +#include "connection.h"
@@ -15769,8 +15813,7 @@ index 0000000..3adc6c2
 + * @root_path:                Root-FS path
 + * @cmdline:          Command-line
 + * @cgroup:           Full cgroup path
-+ * @caps:             Capabilities
-+ * @caps_namespace:   User-namespace of @caps
++ * @cred:             Credentials
 + * @seclabel:         Seclabel
 + * @audit_loginuid:   Audit login-UID
 + * @audit_sessionid:  Audit session-ID
@@ -15810,14 +15853,7 @@ index 0000000..3adc6c2
 +      char *cgroup;
 +
 +      /* KDBUS_ITEM_CAPS */
-+      struct caps {
-+              /* binary compatible to kdbus_caps */
-+              u32 last_cap;
-+              struct {
-+                      u32 caps[_KERNEL_CAPABILITY_U32S];
-+              } set[4];
-+      } caps;
-+      struct user_namespace *caps_namespace;
++      const struct cred *cred;
 +
 +      /* KDBUS_ITEM_SECLABEL */
 +      char *seclabel;
@@ -15855,6 +15891,14 @@ index 0000000..3adc6c2
 +      char *conn_description;
 +};
 +
++/* fixed size equivalent of "kdbus_caps" */
++struct kdbus_meta_caps {
++      u32 last_cap;
++      struct {
++              u32 caps[_KERNEL_CAPABILITY_U32S];
++      } set[4];
++};
++
 +/**
 + * kdbus_meta_proc_new() - Create process metadata object
 + *
@@ -15881,7 +15925,8 @@ index 0000000..3adc6c2
 +
 +      path_put(&mp->exe_path);
 +      path_put(&mp->root_path);
-+      put_user_ns(mp->caps_namespace);
++      if (mp->cred)
++              put_cred(mp->cred);
 +      put_pid(mp->ppid);
 +      put_pid(mp->tgid);
 +      put_pid(mp->pid);
@@ -15951,25 +15996,23 @@ index 0000000..3adc6c2
 +
 +static int kdbus_meta_proc_collect_auxgroups(struct kdbus_meta_proc *mp)
 +{
-+      struct group_info *info;
++      const struct group_info *info;
 +      size_t i;
 +
-+      info = get_current_groups();
++      /* no need to lock/ref, current creds cannot change */
++      info = current_cred()->group_info;
 +
 +      if (info->ngroups > 0) {
 +              mp->auxgrps = kmalloc_array(info->ngroups, sizeof(kgid_t),
 +                                          GFP_KERNEL);
-+              if (!mp->auxgrps) {
-+                      put_group_info(info);
++              if (!mp->auxgrps)
 +                      return -ENOMEM;
-+              }
 +
 +              for (i = 0; i < info->ngroups; i++)
 +                      mp->auxgrps[i] = GROUP_AT(info, i);
 +      }
 +
 +      mp->n_auxgrps = info->ngroups;
-+      put_group_info(info);
 +      mp->valid |= KDBUS_ATTACH_AUXGROUPS;
 +
 +      return 0;
@@ -15989,42 +16032,29 @@ index 0000000..3adc6c2
 +
 +static void kdbus_meta_proc_collect_exe(struct kdbus_meta_proc *mp)
 +{
-+      struct mm_struct *mm;
++      struct file *exe_file;
 +
-+      mm = get_task_mm(current);
-+      if (!mm)
-+              return;
-+
-+      down_read(&mm->mmap_sem);
-+      if (mm->exe_file) {
-+              mp->exe_path = mm->exe_file->f_path;
++      rcu_read_lock();
++      exe_file = rcu_dereference(current->mm->exe_file);
++      if (exe_file) {
++              mp->exe_path = exe_file->f_path;
 +              path_get(&mp->exe_path);
 +              get_fs_root(current->fs, &mp->root_path);
 +              mp->valid |= KDBUS_ATTACH_EXE;
 +      }
-+      up_read(&mm->mmap_sem);
-+
-+      mmput(mm);
++      rcu_read_unlock();
 +}
 +
 +static int kdbus_meta_proc_collect_cmdline(struct kdbus_meta_proc *mp)
 +{
-+      struct mm_struct *mm;
++      struct mm_struct *mm = current->mm;
 +      char *cmdline;
 +
-+      mm = get_task_mm(current);
-+      if (!mm)
-+              return 0;
-+
-+      if (!mm->arg_end) {
-+              mmput(mm);
++      if (!mm->arg_end)
 +              return 0;
-+      }
 +
 +      cmdline = strndup_user((const char __user *)mm->arg_start,
 +                             mm->arg_end - mm->arg_start);
-+      mmput(mm);
-+
 +      if (IS_ERR(cmdline))
 +              return PTR_ERR(cmdline);
 +
@@ -16062,25 +16092,7 @@ index 0000000..3adc6c2
 +
 +static void kdbus_meta_proc_collect_caps(struct kdbus_meta_proc *mp)
 +{
-+      const struct cred *c = current_cred();
-+      int i;
-+
-+      /* ABI: "last_cap" equals /proc/sys/kernel/cap_last_cap */
-+      mp->caps.last_cap = CAP_LAST_CAP;
-+      mp->caps_namespace = get_user_ns(current_user_ns());
-+
-+      CAP_FOR_EACH_U32(i) {
-+              mp->caps.set[0].caps[i] = c->cap_inheritable.cap[i];
-+              mp->caps.set[1].caps[i] = c->cap_permitted.cap[i];
-+              mp->caps.set[2].caps[i] = c->cap_effective.cap[i];
-+              mp->caps.set[3].caps[i] = c->cap_bset.cap[i];
-+      }
-+
-+      /* clear unused bits */
-+      for (i = 0; i < 4; i++)
-+              mp->caps.set[i].caps[CAP_TO_INDEX(CAP_LAST_CAP)] &=
-+                                              CAP_LAST_U32_VALID_MASK;
-+
++      mp->cred = get_current_cred();
 +      mp->valid |= KDBUS_ATTACH_CAPS;
 +}
 +
@@ -16543,7 +16555,6 @@ index 0000000..3adc6c2
 +      }
 +
 +      *mask &= valid;
-+      *mask &= kdbus_meta_attach_mask;
 +
 +      if (!*mask)
 +              goto exit;
@@ -16589,7 +16600,7 @@ index 0000000..3adc6c2
 +              size += KDBUS_ITEM_SIZE(strlen(mp->cgroup) + 1);
 +
 +      if (mp && (*mask & KDBUS_ATTACH_CAPS))
-+              size += KDBUS_ITEM_SIZE(sizeof(mp->caps));
++              size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_meta_caps));
 +
 +      if (mp && (*mask & KDBUS_ATTACH_SECLABEL))
 +              size += KDBUS_ITEM_SIZE(strlen(mp->seclabel) + 1);
@@ -16626,6 +16637,69 @@ index 0000000..3adc6c2
 +      return 2 + !!kdbus_kvec_pad(kvec++, size);
 +}
 +
++static void kdbus_meta_export_caps(struct kdbus_meta_caps *out,
++                                 struct kdbus_meta_proc *mp)
++{
++      struct user_namespace *iter;
++      const struct cred *cred = mp->cred;
++      bool parent = false, owner = false;
++      int i;
++
++      /*
++       * This translates the effective capabilities of 'cred' into the current
++       * user-namespace. If the current user-namespace is a child-namespace of
++       * the user-namespace of 'cred', the mask can be copied verbatim. If
++       * not, the mask is cleared.
++       * There's one exception: If 'cred' is the owner of any user-namespace
++       * in the path between the current user-namespace and the user-namespace
++       * of 'cred', then it has all effective capabilities set. This means,
++       * the user who created a user-namespace always has all effective
++       * capabilities in any child namespaces. Note that this is based on the
++       * uid of the namespace creator, not the task hierarchy.
++       */
++      for (iter = current_user_ns(); iter; iter = iter->parent) {
++              if (iter == cred->user_ns) {
++                      parent = true;
++                      break;
++              }
++
++              if (iter == &init_user_ns)
++                      break;
++
++              if ((iter->parent == cred->user_ns) &&
++                  uid_eq(iter->owner, cred->euid)) {
++                      owner = true;
++                      break;
++              }
++      }
++
++      out->last_cap = CAP_LAST_CAP;
++
++      CAP_FOR_EACH_U32(i) {
++              if (parent) {
++                      out->set[0].caps[i] = cred->cap_inheritable.cap[i];
++                      out->set[1].caps[i] = cred->cap_permitted.cap[i];
++                      out->set[2].caps[i] = cred->cap_effective.cap[i];
++                      out->set[3].caps[i] = cred->cap_bset.cap[i];
++              } else if (owner) {
++                      out->set[0].caps[i] = 0U;
++                      out->set[1].caps[i] = ~0U;
++                      out->set[2].caps[i] = ~0U;
++                      out->set[3].caps[i] = ~0U;
++              } else {
++                      out->set[0].caps[i] = 0U;
++                      out->set[1].caps[i] = 0U;
++                      out->set[2].caps[i] = 0U;
++                      out->set[3].caps[i] = 0U;
++              }
++      }
++
++      /* clear unused bits */
++      for (i = 0; i < 4; i++)
++              out->set[i].caps[CAP_TO_INDEX(CAP_LAST_CAP)] &=
++                                      CAP_LAST_U32_VALID_MASK;
++}
++
 +/* This is equivalent to from_kuid_munged(), but maps INVALID_UID to itself */
 +static uid_t kdbus_from_kuid_keep(kuid_t uid)
 +{
@@ -16684,14 +16758,6 @@ index 0000000..3adc6c2
 +
 +      hdr = &item_hdr[0];
 +
-+      /*
-+       * TODO: We currently have no sane way of translating a set of caps
-+       * between different user namespaces. Until that changes, we have
-+       * to drop such items.
-+       */
-+      if (mp && mp->caps_namespace != user_ns)
-+              mask &= ~KDBUS_ATTACH_CAPS;
-+
 +      if (mask == 0) {
 +              *real_size = 0;
 +              return 0;
@@ -16797,10 +16863,14 @@ index 0000000..3adc6c2
 +                                          KDBUS_ITEM_CGROUP, mp->cgroup,
 +                                          strlen(mp->cgroup) + 1, &size);
 +
-+      if (mp && (mask & KDBUS_ATTACH_CAPS))
++      if (mp && (mask & KDBUS_ATTACH_CAPS)) {
++              struct kdbus_meta_caps caps = {};
++
++              kdbus_meta_export_caps(&caps, mp);
 +              cnt += kdbus_meta_push_kvec(kvec + cnt, hdr++,
-+                                          KDBUS_ITEM_CAPS, &mp->caps,
-+                                          sizeof(mp->caps), &size);
++                                          KDBUS_ITEM_CAPS, &caps,
++                                          sizeof(caps), &size);
++      }
 +
 +      if (mp && (mask & KDBUS_ATTACH_SECLABEL))
 +              cnt += kdbus_meta_push_kvec(kvec + cnt, hdr++,
@@ -16864,10 +16934,10 @@ index 0000000..3adc6c2
 +}
 diff --git a/ipc/kdbus/metadata.h b/ipc/kdbus/metadata.h
 new file mode 100644
-index 0000000..42c942b
+index 0000000..79b6ac3
 --- /dev/null
 +++ b/ipc/kdbus/metadata.h
-@@ -0,0 +1,57 @@
+@@ -0,0 +1,55 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -16894,8 +16964,6 @@ index 0000000..42c942b
 +struct kdbus_meta_proc;
 +struct kdbus_meta_conn;
 +
-+extern unsigned long long kdbus_meta_attach_mask;
-+
 +struct kdbus_meta_proc *kdbus_meta_proc_new(void);
 +struct kdbus_meta_proc *kdbus_meta_proc_ref(struct kdbus_meta_proc *mp);
 +struct kdbus_meta_proc *kdbus_meta_proc_unref(struct kdbus_meta_proc *mp);
@@ -16927,10 +16995,10 @@ index 0000000..42c942b
 +#endif
 diff --git a/ipc/kdbus/names.c b/ipc/kdbus/names.c
 new file mode 100644
-index 0000000..657008e
+index 0000000..d77ee08
 --- /dev/null
 +++ b/ipc/kdbus/names.c
-@@ -0,0 +1,772 @@
+@@ -0,0 +1,770 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -17402,7 +17470,7 @@ index 0000000..657008e
 + * @conn:             connection to operate on
 + * @argp:             command payload
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_name_acquire(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -17447,8 +17515,6 @@ index 0000000..657008e
 +
 +      ret = kdbus_name_acquire(conn->ep->bus->name_registry, conn, item_name,
 +                               cmd->flags, &cmd->return_flags);
-+      if (ret < 0)
-+              goto exit_dec;
 +
 +exit_dec:
 +      atomic_dec(&conn->name_count);
@@ -17461,7 +17527,7 @@ index 0000000..657008e
 + * @conn:             connection to operate on
 + * @argp:             command payload
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_name_release(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -17632,7 +17698,7 @@ index 0000000..657008e
 + * @conn:             connection to operate on
 + * @argp:             command payload
 + *
-+ * Return: 0 on success, negative error code on failure.
++ * Return: >=0 on success, negative error code on failure.
 + */
 +int kdbus_cmd_list(struct kdbus_conn *conn, void __user *argp)
 +{
@@ -17785,10 +17851,10 @@ index 0000000..3dd2589
 +#endif
 diff --git a/ipc/kdbus/node.c b/ipc/kdbus/node.c
 new file mode 100644
-index 0000000..520df00
+index 0000000..0d65c65
 --- /dev/null
 +++ b/ipc/kdbus/node.c
-@@ -0,0 +1,910 @@
+@@ -0,0 +1,897 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -17969,7 +18035,7 @@ index 0000000..520df00
 + *                   accessed by other callers to properly initialize
 + *                   filesystem nodes.
 + *
-+ *     * node->id: This is an unsigned 32bit integer allocated by an IDR. It 
is
++ *     * node->id: This is an unsigned 32bit integer allocated by an IDA. It 
is
 + *                 always kept as small as possible during allocation and is
 + *                 globally unique across all nodes allocated by this module. 0
 + *                 is reserved as "not assigned" and is the default.
@@ -18024,8 +18090,7 @@ index 0000000..520df00
 +#define KDBUS_NODE_NEW                        (KDBUS_NODE_BIAS - 4)
 +
 +/* global unique ID mapping for kdbus nodes */
-+static DEFINE_IDR(kdbus_node_idr);
-+static DECLARE_RWSEM(kdbus_node_idr_lock);
++DEFINE_IDA(kdbus_node_ida);
 +
 +/**
 + * kdbus_node_name_hash() - hash a name
@@ -18128,15 +18193,11 @@ index 0000000..520df00
 +              node->hash = kdbus_node_name_hash(name);
 +      }
 +
-+      down_write(&kdbus_node_idr_lock);
-+      ret = idr_alloc(&kdbus_node_idr, node, 1, 0, GFP_KERNEL);
-+      if (ret >= 0)
-+              node->id = ret;
-+      up_write(&kdbus_node_idr_lock);
-+
++      ret = ida_simple_get(&kdbus_node_ida, 1, 0, GFP_KERNEL);
 +      if (ret < 0)
 +              return ret;
 +
++      node->id = ret;
 +      ret = 0;
 +
 +      if (parent) {
@@ -18231,16 +18292,8 @@ index 0000000..520df00
 +
 +              if (node->free_cb)
 +                      node->free_cb(node);
-+
-+              down_write(&kdbus_node_idr_lock);
 +              if (safe.id > 0)
-+                      idr_remove(&kdbus_node_idr, safe.id);
-+              /* drop caches after last node to not leak memory on unload */
-+              if (idr_is_empty(&kdbus_node_idr)) {
-+                      idr_destroy(&kdbus_node_idr);
-+                      idr_init(&kdbus_node_idr);
-+              }
-+              up_write(&kdbus_node_idr_lock);
++                      ida_simple_remove(&kdbus_node_ida, safe.id);
 +
 +              kfree(safe.name);
 +
@@ -18701,10 +18754,10 @@ index 0000000..520df00
 +}
 diff --git a/ipc/kdbus/node.h b/ipc/kdbus/node.h
 new file mode 100644
-index 0000000..be125ce
+index 0000000..970e02b
 --- /dev/null
 +++ b/ipc/kdbus/node.h
-@@ -0,0 +1,84 @@
+@@ -0,0 +1,86 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -18765,6 +18818,8 @@ index 0000000..be125ce
 +
 +#define kdbus_node_from_rb(_node) rb_entry((_node), struct kdbus_node, rb)
 +
++extern struct ida kdbus_node_ida;
++
 +void kdbus_node_init(struct kdbus_node *node, unsigned int type);
 +
 +int kdbus_node_link(struct kdbus_node *node, struct kdbus_node *parent,
@@ -19633,7 +19688,7 @@ index 0000000..15dd7bc
 +#endif
 diff --git a/ipc/kdbus/pool.c b/ipc/kdbus/pool.c
 new file mode 100644
-index 0000000..139bb77
+index 0000000..45dcdea
 --- /dev/null
 +++ b/ipc/kdbus/pool.c
 @@ -0,0 +1,728 @@
@@ -20314,7 +20369,7 @@ index 0000000..139bb77
 +              }
 +
 +              kaddr = (char __force __user *)kmap(page) + page_off;
-+              n_read = f_src->f_op->read(f_src, kaddr, copy_len, &off_src);
++              n_read = __vfs_read(f_src, kaddr, copy_len, &off_src);
 +              kunmap(page);
 +              mark_page_accessed(page);
 +              flush_dcache_page(page);
@@ -20419,7 +20474,7 @@ index 0000000..a903821
 +#endif
 diff --git a/ipc/kdbus/queue.c b/ipc/kdbus/queue.c
 new file mode 100644
-index 0000000..a449464
+index 0000000..25bb3ad
 --- /dev/null
 +++ b/ipc/kdbus/queue.c
 @@ -0,0 +1,678 @@
@@ -21062,7 +21117,7 @@ index 0000000..a449464
 +      lockdep_assert_held(&src->lock);
 +      lockdep_assert_held(&dst->lock);
 +
-+      if (WARN_ON(IS_ERR(e->user)) || WARN_ON(list_empty(&e->entry)))
++      if (WARN_ON(list_empty(&e->entry)))
 +              return -EINVAL;
 +      if (src == dst)
 +              return 0;
@@ -21201,10 +21256,10 @@ index 0000000..7f2db96
 +#endif /* __KDBUS_QUEUE_H */
 diff --git a/ipc/kdbus/reply.c b/ipc/kdbus/reply.c
 new file mode 100644
-index 0000000..008dca8
+index 0000000..e6791d8
 --- /dev/null
 +++ b/ipc/kdbus/reply.c
-@@ -0,0 +1,257 @@
+@@ -0,0 +1,252 @@
 +#include <linux/init.h>
 +#include <linux/mm.h>
 +#include <linux/module.h>
@@ -21244,7 +21299,7 @@ index 0000000..008dca8
 +                                  bool sync)
 +{
 +      struct kdbus_reply *r;
-+      int ret = 0;
++      int ret;
 +
 +      if (atomic_inc_return(&reply_dst->request_count) >
 +          KDBUS_CONN_MAX_REQUESTS_PENDING) {
@@ -21271,13 +21326,11 @@ index 0000000..008dca8
 +              r->waiting = true;
 +      }
 +
-+exit_dec_request_count:
-+      if (ret < 0) {
-+              atomic_dec(&reply_dst->request_count);
-+              return ERR_PTR(ret);
-+      }
-+
 +      return r;
++
++exit_dec_request_count:
++      atomic_dec(&reply_dst->request_count);
++      return ERR_PTR(ret);
 +}
 +
 +static void __kdbus_reply_free(struct kref *kref)
@@ -21347,8 +21400,7 @@ index 0000000..008dca8
 + * @reply:    The reply object
 + * @err:      Error code to set on the remote side
 + *
-+ * Remove the synchronous reply object from its connection reply_list, and
-+ * wake up remote peer (method origin) with the appropriate synchronous reply
++ * Wake up remote peer (method origin) with the appropriate synchronous reply
 + * code.
 + */
 +void kdbus_sync_reply_wakeup(struct kdbus_reply *reply, int err)
@@ -21379,17 +21431,15 @@ index 0000000..008dca8
 +                                   struct kdbus_conn *reply_dst,
 +                                   u64 cookie)
 +{
-+      struct kdbus_reply *r, *reply = NULL;
++      struct kdbus_reply *r;
 +
 +      list_for_each_entry(r, &reply_dst->reply_list, entry) {
 +              if (r->cookie == cookie &&
-+                  (!replying || r->reply_src == replying)) {
-+                      reply = r;
-+                      break;
-+              }
++                  (!replying || r->reply_src == replying))
++                      return r;
 +      }
 +
-+      return reply;
++      return NULL;
 +}
 +
 +/**
@@ -21538,10 +21588,10 @@ index 0000000..68d5232
 +#endif /* __KDBUS_REPLY_H */
 diff --git a/ipc/kdbus/util.c b/ipc/kdbus/util.c
 new file mode 100644
-index 0000000..eaa806a
+index 0000000..72b1883
 --- /dev/null
 +++ b/ipc/kdbus/util.c
-@@ -0,0 +1,201 @@
+@@ -0,0 +1,156 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -21594,51 +21644,6 @@ index 0000000..eaa806a
 +}
 +
 +/**
-+ * kdbus_memdup_user() - copy dynamically sized object from user-space
-+ * @user_ptr: user-provided source buffer
-+ * @sz_min:   minimum object size
-+ * @sz_max:   maximum object size
-+ *
-+ * This copies a dynamically sized object from user-space into kernel-space. 
We
-+ * require the object to have a 64bit size field at offset 0. We read it out
-+ * first, allocate a suitably sized buffer and then copy all data.
-+ *
-+ * The @sz_min and @sz_max parameters define possible min and max object sizes
-+ * so user-space cannot trigger un-bound kernel-space allocations.
-+ *
-+ * The same alignment-restrictions as described in kdbus_copy_from_user() 
apply.
-+ *
-+ * Return: pointer to dynamically allocated copy, or ERR_PTR() on failure.
-+ */
-+void *kdbus_memdup_user(void __user *user_ptr, size_t sz_min, size_t sz_max)
-+{
-+      void *ptr;
-+      u64 size;
-+      int ret;
-+
-+      ret = kdbus_copy_from_user(&size, user_ptr, sizeof(size));
-+      if (ret < 0)
-+              return ERR_PTR(ret);
-+
-+      if (size < sz_min)
-+              return ERR_PTR(-EINVAL);
-+
-+      if (size > sz_max)
-+              return ERR_PTR(-EMSGSIZE);
-+
-+      ptr = memdup_user(user_ptr, size);
-+      if (IS_ERR(ptr))
-+              return ptr;
-+
-+      if (*(u64 *)ptr != size) {
-+              kfree(ptr);
-+              return ERR_PTR(-EINVAL);
-+      }
-+
-+      return ptr;
-+}
-+
-+/**
 + * kdbus_verify_uid_prefix() - verify UID prefix of a user-supplied name
 + * @name:     user-supplied name to verify
 + * @user_ns:  user-namespace to act in
@@ -21745,10 +21750,10 @@ index 0000000..eaa806a
 +}
 diff --git a/ipc/kdbus/util.h b/ipc/kdbus/util.h
 new file mode 100644
-index 0000000..740b198
+index 0000000..5297166
 --- /dev/null
 +++ b/ipc/kdbus/util.h
-@@ -0,0 +1,74 @@
+@@ -0,0 +1,73 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Greg Kroah-Hartman <[email protected]>
@@ -21791,7 +21796,7 @@ index 0000000..740b198
 +({                                                                    \
 +      u64 __user *_sz =                                               \
 +              (void __user *)((u8 __user *)(_b) + offsetof(_t, _m));  \
-+      copy_to_user(_sz, _s, sizeof(((_t *)0)->_m));                   \
++      copy_to_user(_sz, _s, FIELD_SIZEOF(_t, _m));                    \
 +})
 +
 +/**
@@ -21815,7 +21820,6 @@ index 0000000..740b198
 +int kdbus_sanitize_attach_flags(u64 flags, u64 *attach_flags);
 +
 +int kdbus_copy_from_user(void *dest, void __user *user_ptr, size_t size);
-+void *kdbus_memdup_user(void __user *user_ptr, size_t sz_min, size_t sz_max);
 +
 +struct kvec;
 +
@@ -21876,7 +21880,7 @@ index 0000000..137f842
 +HOSTLOADLIBES_kdbus-workers := -lrt
 diff --git a/samples/kdbus/kdbus-api.h b/samples/kdbus/kdbus-api.h
 new file mode 100644
-index 0000000..5ed5907
+index 0000000..7f3abae
 --- /dev/null
 +++ b/samples/kdbus/kdbus-api.h
 @@ -0,0 +1,114 @@
@@ -21890,12 +21894,12 @@ index 0000000..5ed5907
 +#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
 +#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
 +#define KDBUS_ITEM_NEXT(item) \
-+      (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size))
++      (typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
 +#define KDBUS_FOREACH(iter, first, _size)                             \
-+      for (iter = (first);                                            \
++      for ((iter) = (first);                                          \
 +           ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) &&      \
 +             ((uint8_t *)(iter) >= (uint8_t *)(first));               \
-+           iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size)))
++           (iter) = (void *)((uint8_t *)(iter) + KDBUS_ALIGN8((iter)->size)))
 +
 +static inline int kdbus_cmd_bus_make(int control_fd, struct kdbus_cmd *cmd)
 +{
@@ -21996,10 +22000,10 @@ index 0000000..5ed5907
 +#endif /* KDBUS_API_H */
 diff --git a/samples/kdbus/kdbus-workers.c b/samples/kdbus/kdbus-workers.c
 new file mode 100644
-index 0000000..d331e01
+index 0000000..c3ba958
 --- /dev/null
 +++ b/samples/kdbus/kdbus-workers.c
-@@ -0,0 +1,1326 @@
+@@ -0,0 +1,1345 @@
 +/*
 + * Copyright (C) 2013-2015 David Herrmann <[email protected]>
 + *
@@ -22059,6 +22063,12 @@ index 0000000..d331e01
 + * top-down, but requires some forward-declarations. Just ignore those.
 + */
 +
++#include <stdio.h>
++#include <stdlib.h>
++
++/* glibc < 2.7 does not ship sys/signalfd.h */
++#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 7
++
 +#include <ctype.h>
 +#include <errno.h>
 +#include <fcntl.h>
@@ -22067,8 +22077,6 @@ index 0000000..d331e01
 +#include <stdbool.h>
 +#include <stddef.h>
 +#include <stdint.h>
-+#include <stdio.h>
-+#include <stdlib.h>
 +#include <string.h>
 +#include <sys/mman.h>
 +#include <sys/poll.h>
@@ -23326,13 +23334,28 @@ index 0000000..d331e01
 +
 +      return fd;
 +}
-diff --git a/tools/testing/selftests/Makefile 
b/tools/testing/selftests/Makefile
-index 4e51122..7b51cce 100644
---- a/tools/testing/selftests/Makefile
-+++ b/tools/testing/selftests/Makefile
-@@ -5,6 +5,7 @@ TARGETS += exec
- TARGETS += firmware
- TARGETS += ftrace
++
++#else
++
++#warning "Skipping compilation due to unsupported libc version"
++
++int main(int argc, char **argv)
++{
++      fprintf(stderr,
++              "Compilation of %s was skipped due to unsupported libc.\n",
++              argv[0]);
++
++      return EXIT_FAILURE;
++}
++
++#endif /* libc sanity check */
+diff --git a/tools/testing/selftests/Makefile 
b/tools/testing/selftests/Makefile
+index 95abddc..b57100c 100644
+--- a/tools/testing/selftests/Makefile
++++ b/tools/testing/selftests/Makefile
+@@ -5,6 +5,7 @@ TARGETS += exec
+ TARGETS += firmware
+ TARGETS += ftrace
  TARGETS += kcmp
 +TARGETS += kdbus
  TARGETS += memfd
@@ -23347,10 +23370,10 @@ index 0000000..d3ef42f
 +kdbus-test
 diff --git a/tools/testing/selftests/kdbus/Makefile 
b/tools/testing/selftests/kdbus/Makefile
 new file mode 100644
-index 0000000..de8242f
+index 0000000..8f36cb5
 --- /dev/null
 +++ b/tools/testing/selftests/kdbus/Makefile
-@@ -0,0 +1,48 @@
+@@ -0,0 +1,49 @@
 +CFLAGS += -I../../../../usr/include/
 +CFLAGS += -I../../../../samples/kdbus/
 +CFLAGS += -I../../../../include/uapi/
@@ -23364,7 +23387,6 @@ index 0000000..de8242f
 +      kdbus-test.o            \
 +      kdbus-test.o            \
 +      test-activator.o        \
-+      test-attach-flags.o     \
 +      test-benchmark.o        \
 +      test-bus.o              \
 +      test-chat.o             \
@@ -23388,12 +23410,14 @@ index 0000000..de8242f
 +
 +include ../lib.mk
 +
-+%.o: %.c
++%.o: %.c kdbus-enum.h kdbus-test.h kdbus-util.h
 +      $(CC) $(CFLAGS) -c $< -o $@
 +
 +kdbus-test: $(OBJS)
 +      $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
 +
++TEST_PROGS := kdbus-test
++
 +run_tests:
 +      ./kdbus-test --tap
 +
@@ -23501,10 +23525,10 @@ index 0000000..4f1e579
 +LOOKUP(PAYLOAD);
 diff --git a/tools/testing/selftests/kdbus/kdbus-enum.h 
b/tools/testing/selftests/kdbus/kdbus-enum.h
 new file mode 100644
-index 0000000..a67cec3
+index 0000000..ed28cca
 --- /dev/null
 +++ b/tools/testing/selftests/kdbus/kdbus-enum.h
-@@ -0,0 +1,14 @@
+@@ -0,0 +1,15 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + *
@@ -23513,6 +23537,7 @@ index 0000000..a67cec3
 + * Free Software Foundation; either version 2.1 of the License, or (at
 + * your option) any later version.
 + */
++
 +#pragma once
 +
 +const char *enum_CMD(long long id);
@@ -23521,10 +23546,10 @@ index 0000000..a67cec3
 +const char *enum_PAYLOAD(long long id);
 diff --git a/tools/testing/selftests/kdbus/kdbus-test.c 
b/tools/testing/selftests/kdbus/kdbus-test.c
 new file mode 100644
-index 0000000..a43674c
+index 0000000..294e82a
 --- /dev/null
 +++ b/tools/testing/selftests/kdbus/kdbus-test.c
-@@ -0,0 +1,923 @@
+@@ -0,0 +1,900 @@
 +#include <errno.h>
 +#include <stdio.h>
 +#include <string.h>
@@ -23575,7 +23600,6 @@ index 0000000..a43674c
 +      char *root;
 +      char *test;
 +      char *busname;
-+      char *mask_param_path;
 +};
 +
 +static const struct kdbus_test tests[] = {
@@ -23801,13 +23825,6 @@ index 0000000..a43674c
 +              .func   = kdbus_test_benchmark_uds,
 +              .flags  = TEST_CREATE_BUS,
 +      },
-+      {
-+              /* Last test */
-+              .name   = "attach-flags",
-+              .desc   = "attach flags mask",
-+              .func   = kdbus_test_attach_flags,
-+              .flags  = 0,
-+      },
 +};
 +
 +#define N_TESTS ((int) (sizeof(tests) / sizeof(tests[0])))
@@ -23850,7 +23867,6 @@ index 0000000..a43674c
 +
 +      env->root = args->root;
 +      env->module = args->module;
-+      env->mask_param_path = args->mask_param_path;
 +
 +      return 0;
 +}
@@ -24281,8 +24297,7 @@ index 0000000..a43674c
 +{
 +      int ret;
 +      bool namespaces;
-+      uint64_t kdbus_param_mask;
-+      static char fspath[4096], parampath[4096];
++      static char fspath[4096];
 +
 +      namespaces = (kdbus_args->mntns || kdbus_args->pidns ||
 +                    kdbus_args->userns);
@@ -24318,19 +24333,6 @@ index 0000000..a43674c
 +              kdbus_args->root = fspath;
 +      }
 +
-+      snprintf(parampath, sizeof(parampath),
-+               "/sys/module/%s/parameters/attach_flags_mask",
-+               kdbus_args->module);
-+      kdbus_args->mask_param_path = parampath;
-+
-+      ret = kdbus_sysfs_get_parameter_mask(kdbus_args->mask_param_path,
-+                                           &kdbus_param_mask);
-+      if (ret < 0)
-+              return TEST_ERR;
-+
-+      printf("# Starting tests with an attach_flags_mask=0x%llx\n",
-+              (unsigned long long)kdbus_param_mask);
-+
 +      /* Start tests */
 +      if (namespaces)
 +              ret = run_tests_in_namespaces(kdbus_args);
@@ -24450,10 +24452,10 @@ index 0000000..a43674c
 +}
 diff --git a/tools/testing/selftests/kdbus/kdbus-test.h 
b/tools/testing/selftests/kdbus/kdbus-test.h
 new file mode 100644
-index 0000000..6473318
+index 0000000..a5c6ae8
 --- /dev/null
 +++ b/tools/testing/selftests/kdbus/kdbus-test.h
-@@ -0,0 +1,85 @@
+@@ -0,0 +1,83 @@
 +#ifndef _TEST_KDBUS_H_
 +#define _TEST_KDBUS_H_
 +
@@ -24461,7 +24463,6 @@ index 0000000..6473318
 +      char *buspath;
 +      const char *root;
 +      const char *module;
-+      const char *mask_param_path;
 +      int control_fd;
 +      struct kdbus_conn *conn;
 +};
@@ -24500,7 +24501,6 @@ index 0000000..6473318
 +      ASSERT_EXIT_VAL(cond, EXIT_FAILURE)
 +
 +int kdbus_test_activator(struct kdbus_test_env *env);
-+int kdbus_test_attach_flags(struct kdbus_test_env *env);
 +int kdbus_test_benchmark(struct kdbus_test_env *env);
 +int kdbus_test_benchmark_nomemfds(struct kdbus_test_env *env);
 +int kdbus_test_benchmark_uds(struct kdbus_test_env *env);
@@ -24541,10 +24541,10 @@ index 0000000..6473318
 +#endif /* _TEST_KDBUS_H_ */
 diff --git a/tools/testing/selftests/kdbus/kdbus-util.c 
b/tools/testing/selftests/kdbus/kdbus-util.c
 new file mode 100644
-index 0000000..4b376ec
+index 0000000..29a0cb1
 --- /dev/null
 +++ b/tools/testing/selftests/kdbus/kdbus-util.c
-@@ -0,0 +1,1615 @@
+@@ -0,0 +1,1617 @@
 +/*
 + * Copyright (C) 2013-2015 Daniel Mack
 + * Copyright (C) 2013-2015 Kay Sievers
@@ -24955,11 +24955,9 @@ index 0000000..4b376ec
 +{
 +      int ret, fd;
 +
-+      ret = syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING);
-+      if (ret < 0)
-+              return ret;
-+
-+      fd = ret;
++      fd = syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING);
++      if (fd < 0)
++              return fd;
 +
 +      ret = ftruncate(fd, size);
 +      if (ret < 0) {
@@ -25001,8 +24999,8 @@ index 0000000..4b376ec
 +                          uint64_t cmd_flags,
 +                          int cancel_fd)
 +{
-+      struct kdbus_cmd_send *cmd;
-+      struct kdbus_msg *msg;
++      struct kdbus_cmd_send *cmd = NULL;
++      struct kdbus_msg *msg = NULL;
 +      const char ref1[1024 * 128 + 3] = "0123456789_0";
 +      const char ref2[] = "0123456789_1";
 +      struct kdbus_item *item;
@@ -25011,10 +25009,7 @@ index 0000000..4b376ec
 +      int memfd = -1;
 +      int ret;
 +
-+      size = sizeof(*msg);
-+      size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
-+      size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
-+      size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
++      size = sizeof(*msg) + 3 * KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
 +
 +      if (dst_id == KDBUS_DST_ID_BROADCAST)
 +              size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
@@ -25028,14 +25023,14 @@ index 0000000..4b376ec
 +              if (write(memfd, "kdbus memfd 1234567", 19) != 19) {
 +                      ret = -errno;
 +                      kdbus_printf("writing to memfd failed: %m\n");
-+                      return ret;
++                      goto out;
 +              }
 +
 +              ret = sys_memfd_seal_set(memfd);
 +              if (ret < 0) {
 +                      ret = -errno;
 +                      kdbus_printf("memfd sealing failed: %m\n");
-+                      return ret;
++                      goto out;
 +              }
 +
 +              size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
@@ -25048,7 +25043,7 @@ index 0000000..4b376ec
 +      if (!msg) {
 +              ret = -errno;
 +              kdbus_printf("unable to malloc()!?\n");
-+              return ret;
++              goto out;
 +      }
 +
 +      if (dst_id == KDBUS_DST_ID_BROADCAST)
@@ -25066,7 +25061,7 @@ index 0000000..4b376ec
 +      if (timeout) {
 +              ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
 +              if (ret < 0)
-+                      return ret;
++                      goto out;
 +
 +              msg->timeout_ns = now.tv_sec * 1000000000ULL +
 +                                now.tv_nsec + timeout;
@@ -25117,6 +25112,12 @@ index 0000000..4b376ec
 +              size += KDBUS_ITEM_SIZE(sizeof(cancel_fd));
 +
 +      cmd = malloc(size);
++      if (!cmd) {
++              ret = -errno;
++              kdbus_printf("unable to malloc()!?\n");
++              goto out;
++      }
++
 +      cmd->size = size;
 +      cmd->flags = cmd_flags;
 +      cmd->msg_address = (uintptr_t)msg;
@@ -25131,12 +25132,9 @@ index 0000000..4b376ec
 +      }
 +
 +      ret = kdbus_cmd_send(conn->fd, cmd);
-+      if (memfd >= 0)
-+              close(memfd);
-+
 +      if (ret < 0) {
 +              kdbus_printf("error sending message: %d (%m)\n", ret);
-+              return ret;
++              goto out;
 +      }
 +
 +      if (cmd_flags & KDBUS_SEND_SYNC_REPLY) {
@@ -25150,13 +25148,17 @@ index 0000000..4b376ec
 +
 +              ret = kdbus_free(conn, cmd->reply.offset);
 +              if (ret < 0)
-+                      return ret;
++                      goto out;
 +      }
 +
++out:
 +      free(msg);
 +      free(cmd);
 +
-+      return 0;
++      if (memfd >= 0)
++              close(memfd);
++
++      return ret < 0 ? ret : 0;
 +}
 +
 +int kdbus_msg_send(const struct kdbus_conn *conn, const char *name,
@@ -25900,7 +25902,7 @@ index 0000000..4b376ec
 +      return 0;
 +}
 +
-+int all_uids_gids_are_mapped()
++int all_uids_gids_are_mapped(void)
 +{
 +      int ret;
 +
@@ -26094,7 +26096,7 @@ index 0000000..4b376ec
 +      cap_t caps;
 +
 +      caps = cap_get_proc();
-+      if (!cap) {
++      if (!caps) {
 +              ret = -errno;
 +              kdbus_printf("error cap_get_proc(): %d (%m)\n", ret);
 +              return ret;
@@ -26162,10 +26164,10 @@ index 0000000..4b376ec
 +}
 diff --git a/tools/testing/selftests/kdbus/kdbus-util.h 
b/tools/testing/selftests/kdbus/kdbus-util.h
 new file mode 100644
-index 0000000..50ff071
+index 0000000..d1a0f1b
 --- /dev/null
 +++ b/tools/testing/selftests/kdbus/kdbus-util.h
-@@ -0,0 +1,222 @@
+@@ -0,0 +1,219 @@
 +/*
 + * Copyright (C) 2013-2015 Kay Sievers
 + * Copyright (C) 2013-2015 Daniel Mack
@@ -26175,6 +26177,7 @@ index 0000000..50ff071
 + * Free Software Foundation; either version 2.1 of the License, or (at
 + * your option) any later version.
 + */
++
 +#pragma once
 +
 +#define BIT(X) (1 << (X))
@@ -26194,28 +26197,26 @@ index 0000000..50ff071
 +#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
 +
 +#define KDBUS_ITEM_NEXT(item) \
-+      (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size))
++      (typeof(item))((uint8_t *)(item) + KDBUS_ALIGN8((item)->size))
 +#define KDBUS_ITEM_FOREACH(item, head, first)                         \
-+      for (item = (head)->first;                                      \
++      for ((item) = (head)->first;                                    \
 +           ((uint8_t *)(item) < (uint8_t *)(head) + (head)->size) &&  \
-+             ((uint8_t *)(item) >= (uint8_t *)(head));        \
-+           item = KDBUS_ITEM_NEXT(item))
++             ((uint8_t *)(item) >= (uint8_t *)(head));                \
++           (item) = KDBUS_ITEM_NEXT(item))
 +#define KDBUS_FOREACH(iter, first, _size)                             \
-+      for (iter = (first);                                            \
++      for ((iter) = (first);                                          \
 +           ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) &&      \
 +             ((uint8_t *)(iter) >= (uint8_t *)(first));               \
-+           iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size)))
++           (iter) = (void *)((uint8_t *)(iter) + KDBUS_ALIGN8((iter)->size)))
 +
-+
-+#define _KDBUS_ATTACH_BITS_SET_NR  (__builtin_popcountll(_KDBUS_ATTACH_ALL))
++#define _KDBUS_ATTACH_BITS_SET_NR (__builtin_popcountll(_KDBUS_ATTACH_ALL))
 +
 +/* Sum of KDBUS_ITEM_* that reflects _KDBUS_ATTACH_ALL */
-+#define KDBUS_ATTACH_ITEMS_TYPE_SUM \
-+      ((((_KDBUS_ATTACH_BITS_SET_NR - 1) * \
-+      ((_KDBUS_ATTACH_BITS_SET_NR - 1) + 1)) / 2 ) + \
++#define KDBUS_ATTACH_ITEMS_TYPE_SUM                                   \
++      ((((_KDBUS_ATTACH_BITS_SET_NR - 1) *                            \
++      ((_KDBUS_ATTACH_BITS_SET_NR - 1) + 1)) / 2) +                   \
 +      (_KDBUS_ITEM_ATTACH_BASE * _KDBUS_ATTACH_BITS_SET_NR))
 +
-+
 +#define POOL_SIZE (16 * 1024LU * 1024LU)
 +
 +#define UNPRIV_UID 65534
@@ -26273,7 +26274,7 @@ index 0000000..50ff071
 +      _setup_;                                                        \
 +      efd = eventfd(0, EFD_CLOEXEC);                                  \
 +      ASSERT_RETURN(efd >= 0);                                        \
-+      *clone_ret = 0;                                                 \
++      *(clone_ret) = 0;                                               \
 +      pid = syscall(__NR_clone, flags, NULL);                         \
 +      if (pid == 0) {                                                 \
 +              eventfd_t event_status = 0;                             \
@@ -26298,7 +26299,7 @@ index 0000000..50ff071
 +              ret = TEST_OK;                                          \
 +      } else {                                                        \
 +              ret = -errno;                                           \
-+              *clone_ret = -errno;                                    \
++              *(clone_ret) = -errno;                                  \
 +      }                                                               \
 +      close(efd);                                                     \
 +      ret;                                                            \
@@ -26375,14 +26376,12 @@ index 0000000..50ff071
 +                     uint64_t type, uint64_t id);
 +int kdbus_add_match_empty(struct kdbus_conn *conn);
 +
-+int all_uids_gids_are_mapped();
++int all_uids_gids_are_mapped(void);
 +int drop_privileges(uid_t uid, gid_t gid);
 +uint64_t now(clockid_t clock);
 +char *unique_name(const char *prefix);
 +
-+int userns_map_uid_gid(pid_t pid,
-+                     const char *map_uid,
-+                     const char *map_gid);
++int userns_map_uid_gid(pid_t pid, const char *map_uid, const char *map_gid);
 +int test_is_capable(int cap, ...);
 +int config_user_ns_is_enabled(void);
 +int config_auditsyscall_is_enabled(void);
@@ -26712,762 +26711,6 @@ index 0000000..3d1b763
 +
 +      return TEST_OK;
 +}
-diff --git a/tools/testing/selftests/kdbus/test-attach-flags.c 
b/tools/testing/selftests/kdbus/test-attach-flags.c
-new file mode 100644
-index 0000000..deee7c3
---- /dev/null
-+++ b/tools/testing/selftests/kdbus/test-attach-flags.c
-@@ -0,0 +1,750 @@
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <stdbool.h>
-+#include <stddef.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <stdint.h>
-+#include <errno.h>
-+#include <assert.h>
-+#include <sys/capability.h>
-+#include <sys/mman.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#include <linux/unistd.h>
-+
-+#include "kdbus-api.h"
-+#include "kdbus-test.h"
-+#include "kdbus-util.h"
-+#include "kdbus-enum.h"
-+
-+/*
-+ * Should be the sum of the currently supported and compiled-in
-+ * KDBUS_ITEMS_* that reflect KDBUS_ATTACH_* flags.
-+ */
-+static unsigned int KDBUS_TEST_ITEMS_SUM = KDBUS_ATTACH_ITEMS_TYPE_SUM;
-+
-+static struct kdbus_conn *__kdbus_hello(const char *path, uint64_t flags,
-+                                      uint64_t attach_flags_send,
-+                                      uint64_t attach_flags_recv)
-+{
-+      struct kdbus_cmd_free cmd_free = {};
-+      int ret, fd;
-+      struct kdbus_conn *conn;
-+      struct {
-+              struct kdbus_cmd_hello hello;
-+
-+              struct {
-+                      uint64_t size;
-+                      uint64_t type;
-+                      char str[16];
-+              } conn_name;
-+
-+              uint8_t extra_items[0];
-+      } h;
-+
-+      memset(&h, 0, sizeof(h));
-+
-+      kdbus_printf("-- opening bus connection %s\n", path);
-+      fd = open(path, O_RDWR|O_CLOEXEC);
-+      if (fd < 0) {
-+              kdbus_printf("--- error %d (%m)\n", fd);
-+              return NULL;
-+      }
-+
-+      h.hello.flags = flags | KDBUS_HELLO_ACCEPT_FD;
-+      h.hello.attach_flags_send = attach_flags_send;
-+      h.hello.attach_flags_recv = attach_flags_recv;
-+      h.conn_name.type = KDBUS_ITEM_CONN_DESCRIPTION;
-+      strcpy(h.conn_name.str, "this-is-my-name");
-+      h.conn_name.size = KDBUS_ITEM_HEADER_SIZE + strlen(h.conn_name.str) + 1;
-+
-+      h.hello.size = sizeof(h);
-+      h.hello.pool_size = POOL_SIZE;
-+
-+      ret = kdbus_cmd_hello(fd, (struct kdbus_cmd_hello *) &h.hello);
-+      if (ret < 0) {
-+              kdbus_printf("--- error when saying hello: %d (%m)\n", ret);
-+              return NULL;
-+      }
-+
-+      kdbus_printf("-- New connection ID : %llu\n",
-+                   (unsigned long long)h.hello.id);
-+
-+      cmd_free.size = sizeof(cmd_free);
-+      cmd_free.offset = h.hello.offset;
-+      ret = kdbus_cmd_free(fd, &cmd_free);
-+      if (ret < 0)
-+              return NULL;
-+
-+      conn = malloc(sizeof(*conn));
-+      if (!conn) {
-+              kdbus_printf("unable to malloc()!?\n");
-+              return NULL;
-+      }
-+
-+      conn->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0);
-+      if (conn->buf == MAP_FAILED) {
-+              ret = -errno;
-+              free(conn);
-+              close(fd);
-+              kdbus_printf("--- error mmap: %d (%m)\n", ret);
-+              return NULL;
-+      }
-+
-+      conn->fd = fd;
-+      conn->id = h.hello.id;
-+      return conn;
-+}
-+
-+static int kdbus_test_peers_creation(struct kdbus_test_env *env)
-+{
-+      int ret;
-+      int control_fd;
-+      char *path;
-+      char *busname;
-+      char buspath[2048];
-+      char control_path[2048];
-+      uint64_t attach_flags_mask;
-+      struct kdbus_conn *conn;
-+
-+      snprintf(control_path, sizeof(control_path),
-+               "%s/control", env->root);
-+
-+      /*
-+       * Set kdbus system-wide mask to 0, this has nothing
-+       * to do with the following tests, bus and connection
-+       * creation nor connection update, but we do it so we are
-+       * sure that everything work as expected
-+       */
-+
-+      attach_flags_mask = 0;
-+      ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path,
-+                                           attach_flags_mask);
-+      ASSERT_RETURN(ret == 0);
-+
-+
-+      /*
-+       * Create bus with a full set of ATTACH flags
-+       */
-+
-+      control_fd = open(control_path, O_RDWR);
-+      ASSERT_RETURN(control_fd >= 0);
-+
-+      busname = unique_name("test-peers-creation-bus");
-+      ASSERT_RETURN(busname);
-+
-+      ret = kdbus_create_bus(control_fd, busname, _KDBUS_ATTACH_ALL,
-+                             0, &path);
-+      ASSERT_RETURN(ret == 0);
-+
-+      snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
-+
-+      /*
-+       * Create a connection with an empty send attach flags, or
-+       * with just KDBUS_ATTACH_CREDS, this should fail
-+       */
-+      conn = __kdbus_hello(buspath, 0, 0, 0);
-+      ASSERT_RETURN(conn == NULL);
-+      ASSERT_RETURN(errno == ECONNREFUSED);
-+
-+      conn = __kdbus_hello(buspath, 0, KDBUS_ATTACH_CREDS,
-+                           _KDBUS_ATTACH_ALL);
-+      ASSERT_RETURN(conn == NULL);
-+      ASSERT_RETURN(errno == ECONNREFUSED);
-+
-+      conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0);
-+      ASSERT_RETURN(conn);
-+
-+      /* Try to cut back some send attach flags */
-+      ret = kdbus_conn_update_attach_flags(conn,
-+                                           KDBUS_ATTACH_CREDS|
-+                                           KDBUS_ATTACH_PIDS,
-+                                           _KDBUS_ATTACH_ALL);
-+      ASSERT_RETURN(ret == -EINVAL);
-+
-+      ret = kdbus_conn_update_attach_flags(conn,
-+                                           _KDBUS_ATTACH_ALL, 0);
-+      ASSERT_RETURN(ret == 0);
-+
-+      kdbus_conn_free(conn);
-+      free(path);
-+      free(busname);
-+      close(control_fd);
-+
-+
-+      /* Test a new bus with KDBUS_ATTACH_PIDS */
-+
-+      control_fd = open(control_path, O_RDWR);
-+      ASSERT_RETURN(control_fd >= 0);
-+
-+      busname = unique_name("test-peer-flags-bus");
-+      ASSERT_RETURN(busname);
-+
-+      ret = kdbus_create_bus(control_fd, busname, KDBUS_ATTACH_PIDS,
-+                             0, &path);
-+      ASSERT_RETURN(ret == 0);
-+
-+      snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
-+
-+      /*
-+       * Create a connection with an empty send attach flags, or
-+       * all flags except KDBUS_ATTACH_PIDS
-+       */
-+      conn = __kdbus_hello(buspath, 0, 0, 0);
-+      ASSERT_RETURN(conn == NULL);
-+      ASSERT_RETURN(errno == ECONNREFUSED);
-+
-+      conn = __kdbus_hello(buspath, 0,
-+                           _KDBUS_ATTACH_ALL & ~KDBUS_ATTACH_PIDS,
-+                           _KDBUS_ATTACH_ALL);
-+      ASSERT_RETURN(conn == NULL);
-+      ASSERT_RETURN(errno == ECONNREFUSED);
-+
-+      /* The following should succeed */
-+      conn = __kdbus_hello(buspath, 0, KDBUS_ATTACH_PIDS, 0);
-+      ASSERT_RETURN(conn);
-+      kdbus_conn_free(conn);
-+
-+      conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0);
-+      ASSERT_RETURN(conn);
-+
-+      ret = kdbus_conn_update_attach_flags(conn,
-+                                           _KDBUS_ATTACH_ALL &
-+                                           ~KDBUS_ATTACH_PIDS,
-+                                           _KDBUS_ATTACH_ALL);
-+      ASSERT_RETURN(ret == -EINVAL);
-+
-+      ret = kdbus_conn_update_attach_flags(conn, 0,
-+                                           _KDBUS_ATTACH_ALL);
-+      ASSERT_RETURN(ret == -EINVAL);
-+
-+      /* Now we want only KDBUS_ATTACH_PIDS */
-+      ret = kdbus_conn_update_attach_flags(conn,
-+                                           KDBUS_ATTACH_PIDS, 0);
-+      ASSERT_RETURN(ret == 0);
-+
-+      kdbus_conn_free(conn);
-+      free(path);
-+      free(busname);
-+      close(control_fd);
-+
-+
-+      /*
-+       * Create bus with 0 as ATTACH flags, the bus does not
-+       * require any attach flags
-+       */
-+
-+      control_fd = open(control_path, O_RDWR);
-+      ASSERT_RETURN(control_fd >= 0);
-+
-+      busname = unique_name("test-peer-flags-bus");
-+      ASSERT_RETURN(busname);
-+
-+      ret = kdbus_create_bus(control_fd, busname, 0, 0, &path);
-+      ASSERT_RETURN(ret == 0);
-+
-+      snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
-+
-+      /* Bus is open it does not require any send attach flags */
-+      conn = __kdbus_hello(buspath, 0, 0, 0);
-+      ASSERT_RETURN(conn);
-+      kdbus_conn_free(conn);
-+
-+      conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0);
-+      ASSERT_RETURN(conn);
-+
-+      ret = kdbus_conn_update_attach_flags(conn, 0, 0);
-+      ASSERT_RETURN(ret == 0);
-+
-+      ret = kdbus_conn_update_attach_flags(conn, KDBUS_ATTACH_CREDS, 0);
-+      ASSERT_RETURN(ret == 0);
-+
-+      kdbus_conn_free(conn);
-+      free(path);
-+      free(busname);
-+      close(control_fd);
-+
-+      return 0;
-+}
-+
-+static int kdbus_test_peers_info(struct kdbus_test_env *env)
-+{
-+      int ret;
-+      int control_fd;
-+      char *path;
-+      char *busname;
-+      unsigned int i = 0;
-+      uint64_t offset = 0;
-+      char buspath[2048];
-+      char control_path[2048];
-+      uint64_t attach_flags_mask;
-+      struct kdbus_item *item;
-+      struct kdbus_info *info;
-+      struct kdbus_conn *conn;
-+      struct kdbus_conn *reader;
-+      unsigned long long attach_count = 0;
-+
-+      snprintf(control_path, sizeof(control_path),
-+               "%s/control", env->root);
-+
-+      attach_flags_mask = 0;
-+      ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path,
-+                                           attach_flags_mask);
-+      ASSERT_RETURN(ret == 0);
-+
-+      control_fd = open(control_path, O_RDWR);
-+      ASSERT_RETURN(control_fd >= 0);
-+
-+      busname = unique_name("test-peers-info-bus");
-+      ASSERT_RETURN(busname);
-+
-+      ret = kdbus_create_bus(control_fd, busname, _KDBUS_ATTACH_ALL,
-+                             0, &path);
-+      ASSERT_RETURN(ret == 0);
-+
-+      snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
-+
-+      /* Create connections with the appropriate flags */
-+      conn = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0);
-+      ASSERT_RETURN(conn);
-+
-+      reader = __kdbus_hello(buspath, 0, _KDBUS_ATTACH_ALL, 0);
-+      ASSERT_RETURN(reader);
-+
-+      ret = kdbus_conn_info(reader, conn->id, NULL,
-+                            _KDBUS_ATTACH_ALL, &offset);
-+      ASSERT_RETURN(ret == 0);
-+
-+      info = (struct kdbus_info *)(reader->buf + offset);
-+      ASSERT_RETURN(info->id == conn->id);
-+
-+      /* all attach flags are masked, no metadata */
-+      KDBUS_ITEM_FOREACH(item, info, items)
-+              i++;
-+
-+      ASSERT_RETURN(i == 0);
-+
-+      kdbus_free(reader, offset);
-+
-+      /* Set the mask to _KDBUS_ATTACH_ANY */
-+      attach_flags_mask = _KDBUS_ATTACH_ANY;
-+      ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path,
-+                                           attach_flags_mask);
-+      ASSERT_RETURN(ret == 0);
-+
-+      ret = kdbus_conn_info(reader, conn->id, NULL,
-+                            _KDBUS_ATTACH_ALL, &offset);
-+      ASSERT_RETURN(ret == 0);
-+
-+      info = (struct kdbus_info *)(reader->buf + offset);
-+      ASSERT_RETURN(info->id == conn->id);
-+
-+      attach_count = 0;
-+      KDBUS_ITEM_FOREACH(item, info, items)
-+                  attach_count += item->type;
-+
-+      /*
-+       * All flags have been returned except for:
-+       * KDBUS_ITEM_TIMESTAMP and
-+       * KDBUS_ITEM_OWNED_NAME we do not own any name.
-+       */
-+      ASSERT_RETURN(attach_count == (KDBUS_TEST_ITEMS_SUM -
-+                                     KDBUS_ITEM_OWNED_NAME -
-+                                     KDBUS_ITEM_TIMESTAMP));
-+
-+      kdbus_free(reader, offset);
-+
-+      /* Request only OWNED names */
-+      ret = kdbus_conn_info(reader, conn->id, NULL,
-+                            KDBUS_ATTACH_NAMES, &offset);
-+      ASSERT_RETURN(ret == 0);
-+
-+      info = (struct kdbus_info *)(reader->buf + offset);
-+      ASSERT_RETURN(info->id == conn->id);
-+
-+      attach_count = 0;
-+      KDBUS_ITEM_FOREACH(item, info, items)
-+              attach_count += item->type;
-+
-+      /* we should not get any metadata since we do not own names */
-+      ASSERT_RETURN(attach_count == 0);
-+
-+      kdbus_free(reader, offset);
-+
-+      kdbus_conn_free(conn);
-+      kdbus_conn_free(reader);
-+
-+      return 0;
-+}
-+
-+/**
-+ * @kdbus_mask_param: kdbus module mask parameter (system-wide)
-+ * @requested_meta:   The bus owner metadata that we want
-+ * @expected_items:   The returned KDBUS_ITEMS_* sum. Used to
-+ *                    validate the returned metadata items
-+ */
-+static int kdbus_cmp_bus_creator_metadata(struct kdbus_test_env *env,
-+                                        struct kdbus_conn *conn,
-+                                        uint64_t kdbus_mask_param,
-+                                        uint64_t requested_meta,
-+                                        unsigned long expected_items)
-+{
-+      int ret;
-+      uint64_t offset = 0;
-+      struct kdbus_info *info;
-+      struct kdbus_item *item;
-+      unsigned long attach_count = 0;
-+
-+      ret = kdbus_sysfs_set_parameter_mask(env->mask_param_path,
-+                                           kdbus_mask_param);
-+      ASSERT_RETURN(ret == 0);
-+
-+      ret = kdbus_bus_creator_info(conn, requested_meta, &offset);
-+      ASSERT_RETURN(ret == 0);
-+
-+      info = (struct kdbus_info *)(conn->buf + offset);
-+
-+      KDBUS_ITEM_FOREACH(item, info, items)
-+              attach_count += item->type;
-+
-+      ASSERT_RETURN(attach_count == expected_items);
-+
-+      ret = kdbus_free(conn, offset);
-+      ASSERT_RETURN(ret == 0);
-+
-+      return 0;
-+}
-+
-+static int kdbus_test_bus_creator_info(struct kdbus_test_env *env)
-+{
-+      int ret;
-+      int control_fd;
-+      char *path;
-+      char *busname;
-+      char buspath[2048];
-+      char control_path[2048];
-+      uint64_t attach_flags_mask;
-+      struct kdbus_conn *conn;
-+      unsigned long expected_items = 0;
-+
-+      snprintf(control_path, sizeof(control_path),
-+               "%s/control", env->root);
-+
-+      control_fd = open(control_path, O_RDWR);
-+      ASSERT_RETURN(control_fd >= 0);
-+
-+      busname = unique_name("test-peers-info-bus");
-+      ASSERT_RETURN(busname);
-+
-+      /*
-+       * Now the bus allows us to see all its KDBUS_ATTACH_*
-+       * items
-+       */
-+      ret = kdbus_create_bus(control_fd, busname, 0,
-+                             _KDBUS_ATTACH_ALL, &path);
-+      ASSERT_RETURN(ret == 0);
-+
-+      snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
-+
-+      conn = __kdbus_hello(buspath, 0, 0, 0);
-+      ASSERT_RETURN(conn);
-+
-+      /*
-+       * Start with a kdbus module mask set to _KDBUS_ATTACH_ANY
-+       */
-+      attach_flags_mask = _KDBUS_ATTACH_ANY;
-+
-+      /*
-+       * All flags will be returned except for:
-+       * KDBUS_ITEM_TIMESTAMP
-+       * KDBUS_ITEM_OWNED_NAME
-+       * KDBUS_ITEM_CONN_DESCRIPTION
-+       *
-+       * An extra flags is always returned KDBUS_ITEM_MAKE_NAME
-+       * which contains the bus name
-+       */
-+      expected_items = KDBUS_TEST_ITEMS_SUM + KDBUS_ITEM_MAKE_NAME;
-+      expected_items -= KDBUS_ITEM_TIMESTAMP +
-+                        KDBUS_ITEM_OWNED_NAME +
-+                        KDBUS_ITEM_CONN_DESCRIPTION;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           _KDBUS_ATTACH_ALL,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /*
-+       * We should have:
-+       * KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS + KDBUS_ITEM_MAKE_NAME
-+       */
-+      expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS +
-+                       KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           KDBUS_ATTACH_PIDS |
-+                                           KDBUS_ATTACH_CREDS,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /* KDBUS_ITEM_MAKE_NAME is always returned */
-+      expected_items = KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           0, expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /*
-+       * Restrict kdbus system-wide mask to KDBUS_ATTACH_PIDS
-+       */
-+
-+      attach_flags_mask = KDBUS_ATTACH_PIDS;
-+
-+      /*
-+       * We should have:
-+       * KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME
-+       */
-+      expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           _KDBUS_ATTACH_ALL,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+
-+      /* system-wide mask to 0 */
-+      attach_flags_mask = 0;
-+
-+      /* we should only see: KDBUS_ITEM_MAKE_NAME */
-+      expected_items = KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           _KDBUS_ATTACH_ALL,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      kdbus_conn_free(conn);
-+      free(path);
-+      free(busname);
-+      close(control_fd);
-+
-+
-+      /*
-+       * A new bus that hides all its owner metadata
-+       */
-+
-+      control_fd = open(control_path, O_RDWR);
-+      ASSERT_RETURN(control_fd >= 0);
-+
-+      busname = unique_name("test-peers-info-bus");
-+      ASSERT_RETURN(busname);
-+
-+      ret = kdbus_create_bus(control_fd, busname, 0, 0, &path);
-+      ASSERT_RETURN(ret == 0);
-+
-+      snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
-+
-+      conn = __kdbus_hello(buspath, 0, 0, 0);
-+      ASSERT_RETURN(conn);
-+
-+      /*
-+       * Start with a kdbus module mask set to _KDBUS_ATTACH_ANY
-+       */
-+      attach_flags_mask = _KDBUS_ATTACH_ANY;
-+
-+      /*
-+       * We only get the KDBUS_ITEM_MAKE_NAME
-+       */
-+      expected_items = KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           _KDBUS_ATTACH_ALL,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /*
-+       * We still get only kdbus_ITEM_MAKE_NAME
-+       */
-+      attach_flags_mask = 0;
-+      expected_items = KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           _KDBUS_ATTACH_ALL,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      kdbus_conn_free(conn);
-+      free(path);
-+      free(busname);
-+      close(control_fd);
-+
-+
-+      /*
-+       * A new bus that shows only the PID and CREDS metadata
-+       * of the bus owner.
-+       */
-+      control_fd = open(control_path, O_RDWR);
-+      ASSERT_RETURN(control_fd >= 0);
-+
-+      busname = unique_name("test-peers-info-bus");
-+      ASSERT_RETURN(busname);
-+
-+      ret = kdbus_create_bus(control_fd, busname, 0,
-+                             KDBUS_ATTACH_PIDS|
-+                             KDBUS_ATTACH_CREDS, &path);
-+      ASSERT_RETURN(ret == 0);
-+
-+      snprintf(buspath, sizeof(buspath), "%s/%s/bus", env->root, path);
-+
-+      conn = __kdbus_hello(buspath, 0, 0, 0);
-+      ASSERT_RETURN(conn);
-+
-+      /*
-+       * Start with a kdbus module mask set to _KDBUS_ATTACH_ANY
-+       */
-+      attach_flags_mask = _KDBUS_ATTACH_ANY;
-+
-+      /*
-+       * We should have:
-+       * KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS + KDBUS_ITEM_MAKE_NAME
-+       */
-+      expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_CREDS +
-+                       KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           _KDBUS_ATTACH_ALL,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      expected_items = KDBUS_ITEM_CREDS + KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           KDBUS_ATTACH_CREDS,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /* KDBUS_ITEM_MAKE_NAME is always returned */
-+      expected_items = KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           0, expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /*
-+       * Restrict kdbus system-wide mask to KDBUS_ATTACH_PIDS
-+       */
-+
-+      attach_flags_mask = KDBUS_ATTACH_PIDS;
-+      /*
-+       * We should have:
-+       * KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME
-+       */
-+      expected_items = KDBUS_ITEM_PIDS + KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           _KDBUS_ATTACH_ALL,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /* No KDBUS_ATTACH_CREDS */
-+      expected_items = KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           KDBUS_ATTACH_CREDS,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /* system-wide mask to 0 */
-+      attach_flags_mask = 0;
-+
-+      /* we should only see: KDBUS_ITEM_MAKE_NAME */
-+      expected_items = KDBUS_ITEM_MAKE_NAME;
-+      ret = kdbus_cmp_bus_creator_metadata(env, conn,
-+                                           attach_flags_mask,
-+                                           _KDBUS_ATTACH_ALL,
-+                                           expected_items);
-+      ASSERT_RETURN(ret == 0);
-+
-+
-+      kdbus_conn_free(conn);
-+      free(path);
-+      free(busname);
-+      close(control_fd);
-+
-+      return 0;
-+}
-+
-+int kdbus_test_attach_flags(struct kdbus_test_env *env)
-+{
-+      int ret;
-+      uint64_t flags_mask;
-+      uint64_t old_kdbus_flags_mask;
-+
-+      /* We need CAP_DAC_OVERRIDE to overwrite the kdbus mask */
-+      ret = test_is_capable(CAP_DAC_OVERRIDE, -1);
-+      ASSERT_RETURN(ret >= 0);
-+
-+      /* no enough privileges, SKIP test */
-+      if (!ret)
-+              return TEST_SKIP;
-+
-+      /*
-+       * We need to be able to write to
-+       * "/sys/module/kdbus/parameters/attach_flags_mask"
-+       * perhaps we are unprvileged/privileged in its userns
-+       */
-+      ret = access(env->mask_param_path, W_OK);
-+      if (ret < 0) {
-+              kdbus_printf("--- access() '%s' failed: %d (%m)\n",
-+                           env->mask_param_path, -errno);
-+              return TEST_SKIP;
-+      }
-+
-+      ret = kdbus_sysfs_get_parameter_mask(env->mask_param_path,
-+                                           &old_kdbus_flags_mask);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /* setup the right KDBUS_TEST_ITEMS_SUM */
-+      if (!config_auditsyscall_is_enabled())
-+              KDBUS_TEST_ITEMS_SUM -= KDBUS_ITEM_AUDIT;
-+
-+      if (!config_cgroups_is_enabled())
-+              KDBUS_TEST_ITEMS_SUM -= KDBUS_ITEM_CGROUP;
-+
-+      if (!config_security_is_enabled())
-+              KDBUS_TEST_ITEMS_SUM -= KDBUS_ITEM_SECLABEL;
-+
-+      /*
-+       * Test the connection creation attach flags
-+       */
-+      ret = kdbus_test_peers_creation(env);
-+      /* Restore previous kdbus mask */
-+      kdbus_sysfs_set_parameter_mask(env->mask_param_path,
-+                                     old_kdbus_flags_mask);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /*
-+       * Test the CONN_INFO attach flags
-+       */
-+      ret = kdbus_test_peers_info(env);
-+      /* Restore previous kdbus mask */
-+      kdbus_sysfs_set_parameter_mask(env->mask_param_path,
-+                                     old_kdbus_flags_mask);
-+      ASSERT_RETURN(ret == 0);
-+
-+      /*
-+       * Test the Bus creator info and its attach flags
-+       */
-+      ret = kdbus_test_bus_creator_info(env);
-+      /* Restore previous kdbus mask */
-+      kdbus_sysfs_set_parameter_mask(env->mask_param_path,
-+                                     old_kdbus_flags_mask);
-+      ASSERT_RETURN(ret == 0);
-+
-+      ret = kdbus_sysfs_get_parameter_mask(env->mask_param_path,
-+                                           &flags_mask);
-+      ASSERT_RETURN(ret == 0 && old_kdbus_flags_mask == flags_mask);
-+
-+      return TEST_OK;
-+}
 diff --git a/tools/testing/selftests/kdbus/test-benchmark.c 
b/tools/testing/selftests/kdbus/test-benchmark.c
 new file mode 100644
 index 0000000..8a9744b
@@ -28236,10 +27479,10 @@ index 0000000..71a92d8
 +}
 diff --git a/tools/testing/selftests/kdbus/test-connection.c 
b/tools/testing/selftests/kdbus/test-connection.c
 new file mode 100644
-index 0000000..5c2bf35
+index 0000000..e7c4866
 --- /dev/null
 +++ b/tools/testing/selftests/kdbus/test-connection.c
-@@ -0,0 +1,616 @@
+@@ -0,0 +1,606 @@
 +#include <stdio.h>
 +#include <string.h>
 +#include <fcntl.h>
@@ -28427,13 +27670,10 @@ index 0000000..5c2bf35
 +      int ret;
 +      unsigned int cnt = 0;
 +      uint64_t offset = 0;
-+      uint64_t kdbus_flags_mask;
 +      struct kdbus_info *info;
 +      struct kdbus_conn *conn;
 +      struct kdbus_conn *privileged;
 +      const struct kdbus_item *item;
-+      uint64_t valid_flags_set;
-+      uint64_t invalid_flags_set;
 +      uint64_t valid_flags = KDBUS_ATTACH_NAMES |
 +                             KDBUS_ATTACH_CREDS |
 +                             KDBUS_ATTACH_PIDS |
@@ -28469,13 +27709,6 @@ index 0000000..5c2bf35
 +              .ppid   = getppid(),
 +      };
 +
-+      ret = kdbus_sysfs_get_parameter_mask(env->mask_param_path,
-+                                           &kdbus_flags_mask);
-+      ASSERT_RETURN(ret == 0);
-+
-+      valid_flags_set = valid_flags & kdbus_flags_mask;
-+      invalid_flags_set = invalid_flags & kdbus_flags_mask;
-+
 +      ret = kdbus_conn_info(env->conn, env->conn->id, NULL,
 +                            valid_flags, &offset);
 +      ASSERT_RETURN(ret == 0);
@@ -28488,7 +27721,7 @@ index 0000000..5c2bf35
 +      ASSERT_RETURN(item == NULL);
 +
 +      item = kdbus_get_item(info, KDBUS_ITEM_CONN_DESCRIPTION);
-+      if (valid_flags_set & KDBUS_ATTACH_CONN_DESCRIPTION) {
++      if (valid_flags & KDBUS_ATTACH_CONN_DESCRIPTION) {
 +              ASSERT_RETURN(item);
 +      } else {
 +              ASSERT_RETURN(item == NULL);
@@ -28513,7 +27746,7 @@ index 0000000..5c2bf35
 +      ASSERT_RETURN(item == NULL);
 +
 +      cnt = kdbus_count_item(info, KDBUS_ITEM_CREDS);
-+      if (valid_flags_set & KDBUS_ATTACH_CREDS) {
++      if (valid_flags & KDBUS_ATTACH_CREDS) {
 +              ASSERT_RETURN(cnt == 1);
 +
 +              item = kdbus_get_item(info, KDBUS_ITEM_CREDS);
@@ -28527,7 +27760,7 @@ index 0000000..5c2bf35
 +      }
 +
 +      item = kdbus_get_item(info, KDBUS_ITEM_PIDS);
-+      if (valid_flags_set & KDBUS_ATTACH_PIDS) {
++      if (valid_flags & KDBUS_ATTACH_PIDS) {
 +              ASSERT_RETURN(item);
 +
 +              /* Compare item->pids with cached PIDs */
@@ -28554,7 +27787,7 @@ index 0000000..5c2bf35
 +      ASSERT_RETURN(info->id == conn->id);
 +
 +      item = kdbus_get_item(info, KDBUS_ITEM_OWNED_NAME);
-+      if (valid_flags_set & KDBUS_ATTACH_NAMES) {
++      if (valid_flags & KDBUS_ATTACH_NAMES) {
 +              ASSERT_RETURN(item && !strcmp(item->name.name, 
"com.example.a"));
 +      } else {
 +              ASSERT_RETURN(item == NULL);
@@ -28582,14 +27815,14 @@ index 0000000..5c2bf35
 +              info = (struct kdbus_info *)(conn->buf + offset);
 +              ASSERT_EXIT(info->id == conn->id);
 +
-+              if (valid_flags_set & KDBUS_ATTACH_NAMES) {
++              if (valid_flags & KDBUS_ATTACH_NAMES) {
 +                      item = kdbus_get_item(info, KDBUS_ITEM_OWNED_NAME);
 +                      ASSERT_EXIT(item &&
 +                                  strcmp(item->name.name,
 +                                         "com.example.a") == 0);
 +              }
 +
-+              if (valid_flags_set & KDBUS_ATTACH_CREDS) {
++              if (valid_flags & KDBUS_ATTACH_CREDS) {
 +                      item = kdbus_get_item(info, KDBUS_ITEM_CREDS);
 +                      ASSERT_EXIT(item);
 +
@@ -28598,7 +27831,7 @@ index 0000000..5c2bf35
 +                                  sizeof(struct kdbus_creds)) == 0);
 +              }
 +
-+              if (valid_flags_set & KDBUS_ATTACH_PIDS) {
++              if (valid_flags & KDBUS_ATTACH_PIDS) {
 +                      item = kdbus_get_item(info, KDBUS_ITEM_PIDS);
 +                      ASSERT_EXIT(item);
 +
@@ -28627,7 +27860,7 @@ index 0000000..5c2bf35
 +               * it points to the cached creds.
 +               */
 +              cnt = kdbus_count_item(info, KDBUS_ITEM_CREDS);
-+              if (invalid_flags_set & KDBUS_ATTACH_CREDS) {
++              if (invalid_flags & KDBUS_ATTACH_CREDS) {
 +                      ASSERT_EXIT(cnt == 1);
 +
 +                      item = kdbus_get_item(info, KDBUS_ITEM_CREDS);
@@ -28640,7 +27873,7 @@ index 0000000..5c2bf35
 +                      ASSERT_EXIT(cnt == 0);
 +              }
 +
-+              if (invalid_flags_set & KDBUS_ATTACH_PIDS) {
++              if (invalid_flags & KDBUS_ATTACH_PIDS) {
 +                      cnt = kdbus_count_item(info, KDBUS_ITEM_PIDS);
 +                      ASSERT_EXIT(cnt == 1);
 +
@@ -28653,14 +27886,14 @@ index 0000000..5c2bf35
 +              }
 +
 +              cnt = kdbus_count_item(info, KDBUS_ITEM_CGROUP);
-+              if (invalid_flags_set & KDBUS_ATTACH_CGROUP) {
++              if (invalid_flags & KDBUS_ATTACH_CGROUP) {
 +                      ASSERT_EXIT(cnt == 1);
 +              } else {
 +                      ASSERT_EXIT(cnt == 0);
 +              }
 +
 +              cnt = kdbus_count_item(info, KDBUS_ITEM_CAPS);
-+              if (invalid_flags_set & KDBUS_ATTACH_CAPS) {
++              if (invalid_flags & KDBUS_ATTACH_CAPS) {
 +                      ASSERT_EXIT(cnt == 1);
 +              } else {
 +                      ASSERT_EXIT(cnt == 0);
@@ -28684,7 +27917,7 @@ index 0000000..5c2bf35
 +      ASSERT_RETURN(info->id == conn->id);
 +
 +      cnt = kdbus_count_item(info, KDBUS_ITEM_OWNED_NAME);
-+      if (valid_flags_set & KDBUS_ATTACH_NAMES) {
++      if (valid_flags & KDBUS_ATTACH_NAMES) {
 +              ASSERT_RETURN(cnt == 2);
 +      } else {
 +              ASSERT_RETURN(cnt == 0);
@@ -28929,10 +28162,10 @@ index 0000000..8bc2386
 +}
 diff --git a/tools/testing/selftests/kdbus/test-endpoint.c 
b/tools/testing/selftests/kdbus/test-endpoint.c
 new file mode 100644
-index 0000000..dcc6ab9
+index 0000000..34a7be4
 --- /dev/null
 +++ b/tools/testing/selftests/kdbus/test-endpoint.c
-@@ -0,0 +1,341 @@
+@@ -0,0 +1,352 @@
 +#include <stdio.h>
 +#include <string.h>
 +#include <fcntl.h>
@@ -29190,6 +28423,13 @@ index 0000000..dcc6ab9
 +      ep_conn = kdbus_hello(ep, 0, NULL, 0);
 +      ASSERT_RETURN(ep_conn);
 +
++      /* Check that the reader got the IdAdd notification */
++      ret = kdbus_msg_recv(reader, &msg, NULL);
++      ASSERT_RETURN(ret == 0);
++      ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_ID_ADD);
++      ASSERT_RETURN(msg->items[0].id_change.id == ep_conn->id);
++      kdbus_msg_free(msg);
++
 +      /*
 +       * Add a name add match on the endpoint connection, acquire name from
 +       * the unfiltered connection, and make sure the filtered connection
@@ -29218,7 +28458,7 @@ index 0000000..dcc6ab9
 +      ret = kdbus_conn_info(ep_conn, 0x0fffffffffffffffULL, NULL, 0, NULL);
 +      ASSERT_RETURN(ret == -ENXIO);
 +
-+      /* Check that the reader did not receive anything */
++      /* Check that the reader did not receive the name notification */
 +      ret = kdbus_msg_recv(reader, NULL, NULL);
 +      ASSERT_RETURN(ret == -EAGAIN);
 +
@@ -29230,6 +28470,10 @@ index 0000000..dcc6ab9
 +      ret = kdbus_name_release(env->conn, name);
 +      ASSERT_RETURN(ret == 0);
 +
++      /* Check that the reader did not receive the name notification */
++      ret = kdbus_msg_recv(reader, NULL, NULL);
++      ASSERT_RETURN(ret == -EAGAIN);
++
 +      ret = update_endpoint(ep_fd, name);
 +      ASSERT_RETURN(ret == 0);
 +
@@ -31325,10 +30569,10 @@ index 0000000..f1615da
 +}
 diff --git a/tools/testing/selftests/kdbus/test-metadata-ns.c 
b/tools/testing/selftests/kdbus/test-metadata-ns.c
 new file mode 100644
-index 0000000..2cb1d4d
+index 0000000..ccdfae0
 --- /dev/null
 +++ b/tools/testing/selftests/kdbus/test-metadata-ns.c
-@@ -0,0 +1,506 @@
+@@ -0,0 +1,503 @@
 +/*
 + * Test metadata in new namespaces. Even if our tests can run
 + * in a namespaced setup, this test is necessary so we can inspect
@@ -31612,16 +30856,13 @@ index 0000000..2cb1d4d
 +static int kdbus_clone_userns_test(const char *bus,
 +                                 struct kdbus_conn *conn)
 +{
-+      int ret;
-+      int status;
-+      int efd = -1;
++      int ret, status, efd;
 +      pid_t pid, ppid;
-+      uint64_t unpriv_conn_id = 0;
-+      uint64_t userns_conn_id = 0;
++      uint64_t unpriv_conn_id, userns_conn_id;
 +      struct kdbus_msg *msg;
 +      const struct kdbus_item *item;
 +      struct kdbus_pids expected_pids;
-+      struct kdbus_conn *monitor = NULL;
++      struct kdbus_conn *monitor;
 +
 +      kdbus_printf("STARTING TEST 'metadata-ns'.\n");
 +

Reply via email to