diff options
author | Mike Pagano <mpagano@gentoo.org> | 2015-06-27 15:50:31 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2015-06-27 15:50:31 -0400 |
commit | 45ecdfc0d977755e3f15ba10a6b4fdb93581357b (patch) | |
tree | fa4a7d9cd282593daa1d05e948e934fb71ee3971 | |
parent | Add the kernel-level IPC implementation kdbus as an optional patch. (diff) | |
download | linux-patches-45ecdfc0d977755e3f15ba10a6b4fdb93581357b.tar.gz linux-patches-45ecdfc0d977755e3f15ba10a6b4fdb93581357b.tar.bz2 linux-patches-45ecdfc0d977755e3f15ba10a6b4fdb93581357b.zip |
-rw-r--r-- | 0000_README | 2 | ||||
-rw-r--r-- | 5015_kdbus-6-27-15.patch (renamed from 5015_kdbus-4.1-rc1.patch) | 1753 |
2 files changed, 498 insertions, 1257 deletions
diff --git a/0000_README b/0000_README index d33ec2f1..dd82b403 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 index a5169bd4..bc17abe7 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 <vgoyal@redhat.com> M: Haren Myneni <hbabu@us.ibm.com> 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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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; -+ -+ mm = get_task_mm(current); -+ if (!mm) -+ return; ++ struct file *exe_file; + -+ 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) ++ if (!mm->arg_end) + return 0; + -+ if (!mm->arg_end) { -+ mmput(mm); -+ 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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <gregkh@linuxfoundation.org> @@ -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 <dh.herrmann@gmail.com> + * @@ -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,8 +23334,23 @@ index 0000000..d331e01 + + return fd; +} ++ ++#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 4e51122..7b51cce 100644 +index 95abddc..b57100c 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -5,6 +5,7 @@ TARGETS += exec @@ -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"); + |