allow to set and query connections and memfds a human-readable names (ABI break)
authorKay Sievers <kay@vrfy.org>
Tue, 14 Jan 2014 11:15:10 +0000 (19:15 +0800)
committerKay Sievers <kay@vrfy.org>
Tue, 14 Jan 2014 12:20:18 +0000 (20:20 +0800)
22 files changed:
bus.c
connection.c
connection.h
defaults.h
endpoint.c
handle.c
kdbus.h
memfd.c
memfd.h
message.c
message.h
metadata.c
metadata.h
namespace.c
pool.c
pool.h
test/kdbus-enum.c
test/kdbus-util.c
test/test-kdbus-benchmark.c
test/test-kdbus.c
util.c
util.h

diff --git a/bus.c b/bus.c
index ef0c9a6e722d86a1996a8cc13aea99de86d8d917..bd196cae1c0f8a077f2867bacedc7b258893b4ed 100644 (file)
--- a/bus.c
+++ b/bus.c
@@ -302,7 +302,7 @@ int kdbus_bus_make_user(void __user *buf, struct kdbus_cmd_make **make,
                        }
 
                        if (item->size > KDBUS_ITEM_HEADER_SIZE +
-                                        KDBUS_MAKE_MAX_LEN + 1) {
+                                        KDBUS_SYSNAME_MAX_LEN + 1) {
                                ret = -ENAMETOOLONG;
                                goto exit;
                        }
@@ -313,7 +313,7 @@ int kdbus_bus_make_user(void __user *buf, struct kdbus_cmd_make **make,
                                goto exit;
                        }
 
-                       ret = kdbus_devname_valid(item->str);
+                       ret = kdbus_sysname_is_valid(item->str);
                        if (ret < 0)
                                goto exit;
 
@@ -328,10 +328,6 @@ int kdbus_bus_make_user(void __user *buf, struct kdbus_cmd_make **make,
 
                        bsize = item->data64[0];
                        break;
-
-               default:
-                       ret = -ENOTSUPP;
-                       goto exit;
                }
        }
 
index c0d280b2c464a5e8a908423fe11e07020b7818ca..b1afa0e5de2cf3e4de35af668d6b5aec5d5a5810 100644 (file)
@@ -37,6 +37,7 @@
 #include "namespace.h"
 #include "notify.h"
 #include "policy.h"
+#include "util.h"
 
 /**
  * struct kdbus_conn_queue - messages waiting to be read
@@ -1214,6 +1215,7 @@ static void __kdbus_conn_free(struct kref *kref)
        kdbus_match_db_free(conn->match_db);
        kdbus_pool_free(conn->pool);
        kdbus_ep_unref(conn->ep);
+       kfree(conn->name);
        kfree(conn);
 }
 
@@ -1469,6 +1471,7 @@ int kdbus_conn_new(struct kdbus_ep *ep,
        struct kdbus_bus *bus = ep->bus;
        const struct kdbus_item *item;
        const char *activator_name = NULL;
+       const char *conn_name = NULL;
        const struct kdbus_creds *creds = NULL;
        const char *seclabel = NULL;
        size_t seclabel_len = 0;
@@ -1496,6 +1499,14 @@ int kdbus_conn_new(struct kdbus_ep *ep,
 
                        if (activator_name)
                                return -EINVAL;
+
+                       if (!kdbus_validate_nul(item->str,
+                                       item->size - KDBUS_ITEM_HEADER_SIZE))
+                               return -EINVAL;
+
+                       if (!kdbus_name_is_valid(item->str))
+                               return -EINVAL;
+
                        activator_name = item->str;
                        break;
 
@@ -1516,9 +1527,36 @@ int kdbus_conn_new(struct kdbus_ep *ep,
                        if (!kdbus_bus_uid_is_privileged(bus))
                                return -EPERM;
 
+                       if (!kdbus_validate_nul(item->str,
+                                       item->size - KDBUS_ITEM_HEADER_SIZE))
+                               return -EINVAL;
+
+                       if (!kdbus_name_is_valid(item->str))
+                               return -EINVAL;
+
                        seclabel = item->str;
                        seclabel_len = item->size - KDBUS_ITEM_HEADER_SIZE;
                        break;
+
+               case KDBUS_ITEM_CONN_NAME:
+                       /* human-readable connection name (debugging) */
+                       if (conn_name)
+                               return -EINVAL;
+
+                       if (item->size > KDBUS_SYSNAME_MAX_LEN +
+                                        KDBUS_ITEM_HEADER_SIZE + 1)
+                               return -ENAMETOOLONG;
+
+                       if (!kdbus_validate_nul(item->str,
+                                       item->size - KDBUS_ITEM_HEADER_SIZE))
+                               return -EINVAL;
+
+                       ret = kdbus_sysname_is_valid(item->str);
+                       if (ret < 0)
+                               return ret;
+
+                       conn_name = item->str;
+                       break;
                }
        }
 
@@ -1529,6 +1567,14 @@ int kdbus_conn_new(struct kdbus_ep *ep,
        if (!conn)
                return -ENOMEM;
 
+       if (conn_name) {
+               conn->name = kstrdup(conn_name, GFP_KERNEL);
+               if (!conn->name) {
+                       kfree(conn);
+                       return -ENOMEM;
+               }
+       }
+
        kref_init(&conn->kref);
        mutex_init(&conn->lock);
        INIT_LIST_HEAD(&conn->msg_list);
@@ -1546,7 +1592,7 @@ int kdbus_conn_new(struct kdbus_ep *ep,
        /* init entry, so we can unconditionally remove it */
        INIT_LIST_HEAD(&conn->monitor_entry);
 
-       ret = kdbus_pool_new(&conn->pool, hello->pool_size);
+       ret = kdbus_pool_new(conn->name, hello->pool_size, &conn->pool);
        if (ret < 0)
                goto exit_unref;
 
index 7cfcec45246e8aed38d3d8f66114d02b794c3e3a..0a7aaa9cdf0130db8efef4c336d654d8f09f1bcf 100644 (file)
@@ -22,6 +22,7 @@
  * struct kdbus_conn - connection to a bus
  * @kref:              Reference count
  * @disconnected:      Invalidated data
+ * @name:              Human-readable connection name, used for debugging
  * @ep:                        The endpoint this connection belongs to
  * @id:                        Connection ID
  * @flags:             KDBUS_HELLO_* flags
@@ -50,6 +51,7 @@
 struct kdbus_conn {
        struct kref kref;
        bool disconnected;
+       const char *name;
        struct kdbus_ep *ep;
        u64 id;
        u64 flags;
index 50a9b6a2a29b39a1d7767cdb72109db2b004b9fa..da6b83c986e47ff2e657e3f8cd4d0b9bcd1a10fb 100644 (file)
@@ -29,7 +29,7 @@
 #define KDBUS_NAME_MAX_LEN             255
 
 /* maximum length of bus, ns, ep name */
-#define KDBUS_MAKE_MAX_LEN             63
+#define KDBUS_SYSNAME_MAX_LEN          63
 
 /* maximum size of make data */
 #define KDBUS_MAKE_MAX_SIZE            SZ_32K
index 6bb6180473cea9aaa51cee4b7867434407101dd5..5534dba38f1c6fc096fa95b1e3507f2b0daac88c 100644 (file)
@@ -275,7 +275,7 @@ int kdbus_ep_make_user(void __user *buf,
                        }
 
                        if (item->size > KDBUS_ITEM_HEADER_SIZE +
-                                        KDBUS_MAKE_MAX_LEN + 1) {
+                                        KDBUS_SYSNAME_MAX_LEN + 1) {
                                ret = -ENAMETOOLONG;
                                goto exit;
                        }
@@ -286,16 +286,12 @@ int kdbus_ep_make_user(void __user *buf,
                                goto exit;
                        }
 
-                       ret = kdbus_devname_valid(item->str);
+                       ret = kdbus_sysname_is_valid(item->str);
                        if (ret < 0)
                                goto exit;
 
                        n = item->str;
                        continue;
-
-               default:
-                       ret = -ENOTSUPP;
-                       goto exit;
                }
        }
 
index 1bfec196f27cbd619d5ad0e2937390361e697510..cbc56287f2d1696ce8294d0449fd545fea0e62b3 100644 (file)
--- a/handle.c
+++ b/handle.c
@@ -22,6 +22,7 @@
 #include <linux/sizes.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/syscalls.h>
 
 #include "bus.h"
 #include "connection.h"
@@ -199,7 +200,94 @@ static bool kdbus_check_flags(u64 kernel_flags)
         * The higher 32bit are considered 'incompatible
         * flags'. Refuse them all for now.
         */
-       return kernel_flags <= 0xFFFFFFFFULL;
+       return kernel_flags <= 0xffffffffULL;
+}
+
+static int kdbus_handle_memfd(void __user *buf)
+{
+       u64 size;
+       struct kdbus_cmd_memfd_make *m = NULL;
+       const struct kdbus_item *item;
+       const char *n = NULL;
+       int fd;
+       int __user *addr;
+       int ret;
+
+       if (!KDBUS_IS_ALIGNED8((uintptr_t)buf))
+               return -EFAULT;
+
+       if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_conn_info))
+               return -EFAULT;
+
+       if (size < sizeof(struct kdbus_cmd_memfd_make))
+               return -EINVAL;
+
+       if (size > sizeof(struct kdbus_cmd_memfd_make) + KDBUS_MAKE_MAX_SIZE)
+               return -EMSGSIZE;
+
+       m = memdup_user(buf, size);
+       if (IS_ERR(m))
+               return PTR_ERR(m);
+
+       KDBUS_ITEM_FOREACH(item, m, items) {
+               if (!KDBUS_ITEM_VALID(item, m)) {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+
+               switch (item->type) {
+               case KDBUS_ITEM_MEMFD_NAME:
+                       if (n) {
+                               ret = -EEXIST;
+                               goto exit;
+                       }
+
+                       if (item->size < KDBUS_ITEM_HEADER_SIZE + 2) {
+                               ret = -EINVAL;
+                               goto exit;
+                       }
+
+                       if (item->size > KDBUS_ITEM_HEADER_SIZE +
+                                        KDBUS_SYSNAME_MAX_LEN + 1) {
+                               ret = -ENAMETOOLONG;
+                               goto exit;
+                       }
+
+                       if (!kdbus_validate_nul(item->str,
+                                       item->size - KDBUS_ITEM_HEADER_SIZE)) {
+                               ret = -EINVAL;
+                               goto exit;
+                       }
+
+                       ret = kdbus_sysname_is_valid(item->str);
+                       if (ret < 0)
+                               goto exit;
+
+                       n = item->str;
+                       break;
+               }
+       }
+
+       if (!KDBUS_ITEM_END(item, m)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       ret = kdbus_memfd_new(n, m->file_size, &fd);
+       if (ret < 0)
+               goto exit;
+
+       /* return fd number to caller */
+       addr = buf + offsetof(struct kdbus_cmd_memfd_make, fd);
+       if (put_user(fd, addr)) {
+               sys_close(fd);
+               ret = -EFAULT;
+               goto exit;
+       }
+
+exit:
+       kfree(m);
+       return ret;
 }
 
 /* kdbus control device commands */
@@ -286,25 +374,15 @@ static long kdbus_handle_ioctl_control(struct file *file, unsigned int cmd,
                break;
        }
 
-       case KDBUS_CMD_MEMFD_NEW: {
-               int fd;
-               int __user *addr = buf;
-
-               ret = kdbus_memfd_new(&fd);
-               if (ret < 0)
-                       break;
-
-               if (put_user(fd, addr))
-                       ret = -EFAULT;
+       case KDBUS_CMD_MEMFD_NEW:
+               ret = kdbus_handle_memfd(buf);
                break;
-       }
 
        default:
                ret = -ENOTTY;
                break;
        }
 
-       kfree(make);
        return ret;
 }
 
@@ -571,18 +649,9 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd,
                ret = kdbus_conn_src_msg(conn, buf);
                break;
 
-       case KDBUS_CMD_MEMFD_NEW: {
-               int fd;
-               int __user *addr = buf;
-
-               ret = kdbus_memfd_new(&fd);
-               if (ret < 0)
-                       break;
-
-               if (put_user(fd, addr))
-                       ret = -EFAULT;
+       case KDBUS_CMD_MEMFD_NEW:
+               ret = kdbus_handle_memfd(buf);
                break;
-       }
 
        default:
                ret = -ENOTTY;
diff --git a/kdbus.h b/kdbus.h
index 601d0188d3841409700e6cb4a4f67c5226b7f0d9..d2e4fd301bf07faf42364e59a840195534c3ab96 100644 (file)
--- a/kdbus.h
+++ b/kdbus.h
@@ -137,7 +137,7 @@ struct kdbus_vec {
  * struct kdbus_memfd - a kdbus memfd
  * @size:              The memfd's size
  * @fd:                        The file descriptor number
- * @__pad:             Padding to make the struct aligned
+ * @__pad:             Padding to ensure proper alignement and size
  *
  * Attached to:
  *   KDBUS_ITEM_PAYLOAD_MEMFD
@@ -205,6 +205,7 @@ struct kdbus_policy {
  * @KDBUS_ITEM_BLOOM_SIZE:     Desired bloom size, used by KDBUS_CMD_BUS_MAKE
  * @KDBUS_ITEM_DST_NAME:       Destination's well-known name
  * @KDBUS_ITEM_MAKE_NAME:      Name of namespace, bus, endpoint
+ * @KDBUS_ITEM_MEMFD_NAME:     The human readable name of a memfd (debugging)
  * @_KDBUS_ITEM_POLICY_BASE:   Start of policy items
  * @KDBUS_ITEM_POLICY_NAME:    Policy in struct kdbus_policy
  * @KDBUS_ITEM_POLICY_ACCESS:  Policy in struct kdbus_policy
@@ -221,6 +222,7 @@ struct kdbus_policy {
  * @KDBUS_ITEM_CAPS:           The process capabilities
  * @KDBUS_ITEM_SECLABEL:       The security label
  * @KDBUS_ITEM_AUDIT:          The audit IDs
+ * @KDBUS_ITEM_CONN_NAME:      The connection's human-readable name (debugging)
  * @_KDBUS_ITEM_KERNEL_BASE:   Start of kernel-generated message items
  * @KDBUS_ITEM_NAME_ADD:       Notify in struct kdbus_notify_name_change
  * @KDBUS_ITEM_NAME_REMOVE:    Notify in struct kdbus_notify_name_change
@@ -241,12 +243,13 @@ enum kdbus_item_type {
        KDBUS_ITEM_BLOOM_SIZE,
        KDBUS_ITEM_DST_NAME,
        KDBUS_ITEM_MAKE_NAME,
+       KDBUS_ITEM_MEMFD_NAME,
 
-       _KDBUS_ITEM_POLICY_BASE = 0x400,
+       _KDBUS_ITEM_POLICY_BASE = 0x1000,
        KDBUS_ITEM_POLICY_NAME = _KDBUS_ITEM_POLICY_BASE,
        KDBUS_ITEM_POLICY_ACCESS,
 
-       _KDBUS_ITEM_ATTACH_BASE = 0x600,
+       _KDBUS_ITEM_ATTACH_BASE = 0x2000,
        KDBUS_ITEM_NAME         = _KDBUS_ITEM_ATTACH_BASE,
        KDBUS_ITEM_ID,
        KDBUS_ITEM_TIMESTAMP,
@@ -259,8 +262,9 @@ enum kdbus_item_type {
        KDBUS_ITEM_CAPS,
        KDBUS_ITEM_SECLABEL,
        KDBUS_ITEM_AUDIT,
+       KDBUS_ITEM_CONN_NAME,
 
-       _KDBUS_ITEM_KERNEL_BASE = 0x800,
+       _KDBUS_ITEM_KERNEL_BASE = 0x3000,
        KDBUS_ITEM_NAME_ADD     = _KDBUS_ITEM_KERNEL_BASE,
        KDBUS_ITEM_NAME_REMOVE,
        KDBUS_ITEM_NAME_CHANGE,
@@ -350,13 +354,13 @@ enum kdbus_payload_type {
  * @payload_type:      Payload type (KDBUS_PAYLOAD_*)
  * @cookie:            Userspace-supplied cookie, for the connection
  *                     to identify its messages
- * @cookie_reply:      A reply to the requesting message with the same
- *                     cookie. The requesting connection can match its
- *                     request and the reply with this value
  * @timeout_ns:                The time to wait for a message reply from the peer.
  *                     If there is no reply, a kernel-generated message
  *                     with an attached KDBUS_ITEM_REPLY_TIMEOUT item
  *                     is sent to @src_id.
+ * @cookie_reply:      A reply to the requesting message with the same
+ *                     cookie. The requesting connection can match its
+ *                     request and the reply with this value
  * @items:             A list of kdbus_items containing the message payload
  */
 struct kdbus_msg {
@@ -367,8 +371,8 @@ struct kdbus_msg {
        __u64 payload_type;
        __u64 cookie;
        union {
-               __u64 cookie_reply;
                __u64 timeout_ns;
+               __u64 cookie_reply;
        };
        struct kdbus_item items[0];
 } __attribute__((aligned(8)));
@@ -441,6 +445,7 @@ enum kdbus_hello_flags {
  * @KDBUS_ATTACH_CAPS:         The process capabilities
  * @KDBUS_ATTACH_SECLABEL:     The security label
  * @KDBUS_ATTACH_AUDIT:                The audit IDs
+ * @KDBUS_ATTACH_CONN_NAME:    The human-readable connection name
  */
 enum kdbus_attach_flags {
        KDBUS_ATTACH_TIMESTAMP          =  1 <<  0,
@@ -453,6 +458,7 @@ enum kdbus_attach_flags {
        KDBUS_ATTACH_CAPS               =  1 <<  7,
        KDBUS_ATTACH_SECLABEL           =  1 <<  8,
        KDBUS_ATTACH_AUDIT              =  1 <<  9,
+       KDBUS_ATTACH_CONN_NAME          =  1 << 10,
 };
 
 /**
@@ -649,6 +655,24 @@ struct kdbus_cmd_match {
        struct kdbus_item items[0];
 } __attribute__((aligned(8)));
 
+/**
+ * struct kdbus_cmd_memfd_make - create a kdbus memfd
+ * @size:              The total size of the struct
+ * @file_size:         The initial file size
+ * @fd:                        The returned file descriptor number
+ * @__pad:             Padding to ensure proper alignement
+ * @items:             A list of items for additional information
+ *
+ * This structure is used with the KDBUS_CMD_MEMFD_NEW ioctl.
+ */
+struct kdbus_cmd_memfd_make {
+       __u64 size;
+       __u64 file_size;
+       int fd;
+       __u32 __pad;
+       struct kdbus_item items[0];
+} __attribute__((aligned(8)));
+
 /**
  * enum kdbus_ioctl_type - Ioctl API
  * @KDBUS_CMD_BUS_MAKE:                After opening the "control" device node, this
@@ -678,8 +702,9 @@ struct kdbus_cmd_match {
  *                             pool.
  * @KDBUS_CMD_DROP:            Drop and free the next queued message and all
  *                             its ressources without actually receiveing it.
- * @KDBUS_CMD_SRC:             Return the sender's connection ID of the next
- *                             queued message.
+ * @KDBUS_CMD_SRC:             Query the sender's connection ID of the next
+ *                             queued message, used to determine the activating
+ *                             connection of a bus name.
  * @KDBUS_CMD_NAME_ACQUIRE:    Request a well-known bus name to associate with
  *                             the connection. Well-known names are used to
  *                             address a peer on the bus.
@@ -750,11 +775,11 @@ enum kdbus_ioctl_type {
 
        KDBUS_CMD_EP_POLICY_SET =       _IOW (KDBUS_IOC_MAGIC, 0x80, struct kdbus_cmd_policy),
 
-       KDBUS_CMD_MEMFD_NEW =           _IOR (KDBUS_IOC_MAGIC, 0x90, int *),
-       KDBUS_CMD_MEMFD_SIZE_GET =      _IOR (KDBUS_IOC_MAGIC, 0x91, __u64 *),
-       KDBUS_CMD_MEMFD_SIZE_SET =      _IOW (KDBUS_IOC_MAGIC, 0x92, __u64 *),
-       KDBUS_CMD_MEMFD_SEAL_GET =      _IOR (KDBUS_IOC_MAGIC, 0x93, int *),
-       KDBUS_CMD_MEMFD_SEAL_SET =      _IO  (KDBUS_IOC_MAGIC, 0x94),
+       KDBUS_CMD_MEMFD_NEW =           _IOWR(KDBUS_IOC_MAGIC, 0xc0, struct kdbus_cmd_memfd_make),
+       KDBUS_CMD_MEMFD_SIZE_GET =      _IOR (KDBUS_IOC_MAGIC, 0xc1, __u64 *),
+       KDBUS_CMD_MEMFD_SIZE_SET =      _IOW (KDBUS_IOC_MAGIC, 0xc2, __u64 *),
+       KDBUS_CMD_MEMFD_SEAL_GET =      _IOR (KDBUS_IOC_MAGIC, 0xc3, int *),
+       KDBUS_CMD_MEMFD_SEAL_SET =      _IO  (KDBUS_IOC_MAGIC, 0xc4),
 };
 
 /*
diff --git a/memfd.c b/memfd.c
index 95206929abe7cdccc5fa78736e84c039254b6e2f..0bda31df857ccde97a38b2cb5e5fde95f3f1f065 100644 (file)
--- a/memfd.c
+++ b/memfd.c
@@ -31,14 +31,17 @@ static const struct file_operations kdbus_memfd_fops;
 
 /**
  * struct kdbus_memfile - protectable shared memory file
- * @sealed:            Flag if the content is writable
+ * @name:              Name of the (deleted) file which shows up in
+ *                     /proc, used for debugging
  * @lock:              Locking
  * @fp:                        Shared memory backing file
+ * @sealed:            Flag if the content is writable
  */
 struct kdbus_memfile {
-       bool sealed;
+       const char *name;
        struct mutex lock;
        struct file *fp;
+       bool sealed;
 };
 
 /**
@@ -90,13 +93,18 @@ u64 kdbus_memfd_size(const struct file *fp)
 
 /**
  * kdbus_memfd_new() - create and install a memfd and file descriptor
- * @fd:                        installed file descriptor
+ * @name:              Name of the (deleted) file which shows up in
+ *                     /proc, used for debugging
+ * @size:              Initial size of the file
+ * @fd:                        Installed file descriptor
  *
  * Returns: 0 on success, negative errno on failure.
  */
-int kdbus_memfd_new(int *fd)
+int kdbus_memfd_new(const char *name, size_t size, int *fd)
 {
        struct kdbus_memfile *mf;
+       const char *shmem_name = NULL;
+       const char *anon_name = NULL;
        struct file *shmemfp;
        struct file *fp;
        int f;
@@ -108,8 +116,19 @@ int kdbus_memfd_new(int *fd)
 
        mutex_init(&mf->lock);
 
+       if (name) {
+               mf->name = kstrdup(name, GFP_KERNEL);
+               shmem_name = kasprintf(GFP_KERNEL, KBUILD_MODNAME "-memfd:%s", name);
+               anon_name = kasprintf(GFP_KERNEL, "[" KBUILD_MODNAME "-memfd:%s]", name);
+               if (!mf->name || !shmem_name || !anon_name) {
+                       ret = -ENOMEM;
+                       goto exit;
+               }
+       }
+
        /* allocate a new unlinked shmem file */
-       shmemfp = shmem_file_setup(KBUILD_MODNAME "-memfd", 0, 0);
+       shmemfp = shmem_file_setup(name ? shmem_name : KBUILD_MODNAME "-memfd",
+                                  size, 0);
        if (IS_ERR(shmemfp)) {
                ret = PTR_ERR(shmemfp);
                goto exit;
@@ -126,7 +145,7 @@ int kdbus_memfd_new(int *fd)
         * invisible shmem inode. We rely on the fact that nothing else
         * can create a new file for the shmem inode, like by opening the
         * fd in /proc/$PID/fd/ */
-       fp = anon_inode_getfile("[" KBUILD_MODNAME "-memfd]",
+       fp = anon_inode_getfile(name ? anon_name : "[" KBUILD_MODNAME "-memfd]",
                                &kdbus_memfd_fops, mf, O_RDWR);
        if (IS_ERR(fp)) {
                ret = PTR_ERR(fp);
@@ -137,6 +156,8 @@ int kdbus_memfd_new(int *fd)
        fp->f_mapping = shmemfp->f_mapping;
        fd_install(f, fp);
 
+       kfree(anon_name);
+       kfree(shmem_name);
        *fd = f;
        return 0;
 
@@ -145,6 +166,9 @@ exit_fd:
 exit_shmem:
        fput(shmemfp);
 exit:
+       kfree(anon_name);
+       kfree(shmem_name);
+       kfree(mf->name);
        kfree(mf);
        return ret;
 }
@@ -154,6 +178,7 @@ static int kdbus_memfd_release(struct inode *ignored, struct file *file)
        struct kdbus_memfile *mf = file->private_data;
 
        fput(mf->fp);
+       kfree(mf->name);
        kfree(mf);
        return 0;
 }
diff --git a/memfd.h b/memfd.h
index 3a7b21310549a68203d634d6e25a977fe33ebf3c..acfc70add4e1fd66340aedc10408b467122cd43f 100644 (file)
--- a/memfd.h
+++ b/memfd.h
@@ -16,5 +16,5 @@
 bool kdbus_is_memfd(const struct file *fp);
 bool kdbus_is_memfd_sealed(const struct file *fp);
 u64 kdbus_memfd_size(const struct file *fp);
-int kdbus_memfd_new(int *fd);
+int kdbus_memfd_new(const char *name, size_t size, int *fd);
 #endif
index e9b8f5203cef4263ef6c347d9ad174d0f04c6988..b36199f982ae36464b469b63e2dd43d82f281c70 100644 (file)
--- a/message.c
+++ b/message.c
@@ -196,9 +196,6 @@ static int kdbus_msg_scan_items(struct kdbus_conn *conn,
 
                        kmsg->dst_name = item->str;
                        break;
-
-               default:
-                       return -ENOTSUPP;
                }
        }
 
index 44ed106e480515cab48602fd8d0d54c9869a6546..8f93938ca1b05675ed26ade301c3929ab722ef17 100644 (file)
--- a/message.h
+++ b/message.h
@@ -14,7 +14,6 @@
 #define __KDBUS_MESSAGE_H
 
 #include "util.h"
-#include "namespace.h"
 #include "metadata.h"
 
 /**
index 3fe639e044de413493cf1294c2c16daa270d0ec7..cc30fae9d1a9e7b6b240b1976acd2bfaaa814732 100644 (file)
@@ -491,6 +491,15 @@ int kdbus_meta_append(struct kdbus_meta *meta,
                        goto exit;
        }
 #endif
+
+       if (which & KDBUS_ATTACH_CONN_NAME &&
+           !(meta->attached & KDBUS_ATTACH_CONN_NAME)) {
+               ret = kdbus_meta_append_str(meta, KDBUS_ITEM_CONN_NAME,
+                                           conn->name);
+               if (ret < 0)
+                       goto exit;
+       }
+
        /*
         * We tried to add everything we got asked for; do not get
         * here again for the same question.
index 1ee510e19c60a3d0bfe961936614c7dbb1e4c0ee..d72b01f108419a08b045e53a51aac164b341c6c9 100644 (file)
@@ -13,8 +13,6 @@
 #ifndef __KDBUS_METADATA_H
 #define __KDBUS_METADATA_H
 
-#include "message.h"
-
 /**
  * struct kdbus_meta - metadata buffer
  * @attached:          Flags for already attached data
index c19816e5da20a5f68c671a9846bd255543999786..3fc0bc5cce9395f1de206882a191b651df2e2791 100644 (file)
@@ -357,7 +357,7 @@ int kdbus_ns_make_user(void __user *buf,
                                goto exit;
                        }
 
-                       if (payload_size > KDBUS_MAKE_MAX_LEN + 1) {
+                       if (payload_size > KDBUS_SYSNAME_MAX_LEN + 1) {
                                ret = -ENAMETOOLONG;
                                goto exit;
                        }
@@ -367,16 +367,12 @@ int kdbus_ns_make_user(void __user *buf,
                                goto exit;
                        }
 
-                       ret = kdbus_devname_valid(item->str);
+                       ret = kdbus_sysname_is_valid(item->str);
                        if (ret < 0)
                                goto exit;
 
                        n = item->str;
                        continue;
-
-               default:
-                       ret = -ENOTSUPP;
-                       goto exit;
                }
        }
 
diff --git a/pool.c b/pool.c
index e3e29950162ff510e68acb5a70d76b7feb4e3dbb..ba66ea126d4722235c408dd7682109bdf63d0aab 100644 (file)
--- a/pool.c
+++ b/pool.c
@@ -284,12 +284,14 @@ static void kdbus_pool_free_slice(struct kdbus_pool *pool,
 
 /**
  * kdbus_pool_new() - create a new pool
- * @pool:              Newly allocated pool
+ * @name:              Name of the (deleted) file which shows up in
+ *                     /proc, used for debugging
  * @size:              Maximum size of the pool
+ * @pool:              Newly allocated pool
  *
  * Returns: 0 on success, negative errno on failure.
  */
-int kdbus_pool_new(struct kdbus_pool **pool, size_t size)
+int kdbus_pool_new(const char *name, size_t size, struct kdbus_pool **pool)
 {
        struct kdbus_pool *p;
        struct file *f;
@@ -302,10 +304,22 @@ int kdbus_pool_new(struct kdbus_pool **pool, size_t size)
        if (!p)
                return -ENOMEM;
 
-       f = shmem_file_setup(KBUILD_MODNAME "-pool", size, 0);
+       if (name) {
+               char *n;
+
+               n = kasprintf(GFP_KERNEL, KBUILD_MODNAME "-conn:%s", name);
+               if (!n) {
+                       ret = -ENOMEM;
+                       goto exit_free;
+               }
+               f = shmem_file_setup(n, size, 0);
+               kfree(n);
+       } else {
+               f = shmem_file_setup(KBUILD_MODNAME "-conn", size, 0);
+       }
        if (IS_ERR(f)) {
                ret = PTR_ERR(f);
-               goto exit_free_p;
+               goto exit_free;
        }
 
        /* allocate first slice spanning the entire pool */
@@ -331,7 +345,7 @@ int kdbus_pool_new(struct kdbus_pool **pool, size_t size)
 
 exit_put_shmem:
        fput(f);
-exit_free_p:
+exit_free:
        kfree(p);
        return ret;
 }
diff --git a/pool.h b/pool.h
index b0453b2cb59e124fa1aec78ac54e24424576f592..0efca232356eb64a4266c46721fa451c851a37e9 100644 (file)
--- a/pool.h
+++ b/pool.h
@@ -15,7 +15,7 @@
 
 struct kdbus_pool;
 
-int kdbus_pool_new(struct kdbus_pool **pool, size_t size);
+int kdbus_pool_new(const char *name, size_t size, struct kdbus_pool **pool);
 void kdbus_pool_free(struct kdbus_pool *pool);
 
 int kdbus_pool_alloc_range(struct kdbus_pool *pool, size_t size, size_t *off);
index 8207f6a2c723d3dccffad75635792168cd9ae534..b87effbaf4189429a1f9583d28868a043b0bad53 100644 (file)
@@ -68,6 +68,7 @@ TABLE(MSG) = {
        ENUM(KDBUS_ITEM_CAPS),
        ENUM(KDBUS_ITEM_SECLABEL),
        ENUM(KDBUS_ITEM_AUDIT),
+       ENUM(KDBUS_ITEM_CONN_NAME),
        ENUM(KDBUS_ITEM_NAME),
        ENUM(KDBUS_ITEM_TIMESTAMP),
        ENUM(KDBUS_ITEM_NAME_ADD),
index a8e2b807a79acf832822338bfe822284747f688b..26c4a75b4b5f5c0ec22cdd5e3c76ee895a612cd9 100644 (file)
 struct conn *connect_to_bus(const char *path, uint64_t hello_flags)
 {
        int fd, ret;
-       struct kdbus_cmd_hello hello;
+       struct {
+               struct kdbus_cmd_hello hello;
+               uint64_t size;
+               uint64_t type;
+               char comm[16];
+       } h;
        struct conn *conn;
 
-       memset(&hello, 0, sizeof(hello));
+       memset(&h, 0, sizeof(h));
 
        printf("-- opening bus connection %s\n", path);
        fd = open(path, O_RDWR|O_CLOEXEC);
@@ -42,9 +47,9 @@ struct conn *connect_to_bus(const char *path, uint64_t hello_flags)
                return NULL;
        }
 
-       hello.conn_flags = hello_flags | KDBUS_HELLO_ACCEPT_FD;
+       h.hello.conn_flags = hello_flags | KDBUS_HELLO_ACCEPT_FD;
 
-       hello.attach_flags = KDBUS_ATTACH_TIMESTAMP |
+       h.hello.attach_flags = KDBUS_ATTACH_TIMESTAMP |
                             KDBUS_ATTACH_CREDS |
                             KDBUS_ATTACH_NAMES |
                             KDBUS_ATTACH_COMM |
@@ -53,22 +58,27 @@ struct conn *connect_to_bus(const char *path, uint64_t hello_flags)
                             KDBUS_ATTACH_CAPS |
                             KDBUS_ATTACH_CGROUP |
                             KDBUS_ATTACH_SECLABEL |
-                            KDBUS_ATTACH_AUDIT;
+                            KDBUS_ATTACH_AUDIT |
+                            KDBUS_ATTACH_CONN_NAME;
+
+       h.type = KDBUS_ITEM_CONN_NAME;
+       h.size = KDBUS_ITEM_HEADER_SIZE + sizeof(h.comm);
+       strcpy(h.comm, "this-is-my-name");
 
-       hello.size = sizeof(struct kdbus_cmd_hello);
-       hello.pool_size = POOL_SIZE;
+       h.hello.size = sizeof(h);
+       h.hello.pool_size = POOL_SIZE;
 
-       ret = ioctl(fd, KDBUS_CMD_HELLO, &hello);
+       ret = ioctl(fd, KDBUS_CMD_HELLO, &h.hello);
        if (ret < 0) {
                fprintf(stderr, "--- error when saying hello: %d (%m)\n", ret);
                return NULL;
        }
        printf("-- Our peer ID for %s: %llu -- bus uuid: '%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'\n",
-               path, (unsigned long long)hello.id,
-               hello.id128[0],  hello.id128[1],  hello.id128[2],  hello.id128[3],
-               hello.id128[4],  hello.id128[5],  hello.id128[6],  hello.id128[7],
-               hello.id128[8],  hello.id128[9],  hello.id128[10], hello.id128[11],
-               hello.id128[12], hello.id128[13], hello.id128[14], hello.id128[15]);
+               path, (unsigned long long)h.hello.id,
+               h.hello.id128[0],  h.hello.id128[1],  h.hello.id128[2],  h.hello.id128[3],
+               h.hello.id128[4],  h.hello.id128[5],  h.hello.id128[6],  h.hello.id128[7],
+               h.hello.id128[8],  h.hello.id128[9],  h.hello.id128[10], h.hello.id128[11],
+               h.hello.id128[12], h.hello.id128[13], h.hello.id128[14], h.hello.id128[15]);
 
        conn = malloc(sizeof(*conn));
        if (!conn) {
@@ -84,7 +94,7 @@ struct conn *connect_to_bus(const char *path, uint64_t hello_flags)
        }
 
        conn->fd = fd;
-       conn->id = hello.id;
+       conn->id = h.hello.id;
        return conn;
 }
 
@@ -109,11 +119,24 @@ int msg_send(const struct conn *conn,
        if (dst_id == KDBUS_DST_ID_BROADCAST)
                size += KDBUS_ITEM_HEADER_SIZE + 64;
        else {
-               ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &memfd);
+               struct {
+                       struct kdbus_cmd_memfd_make cmd;
+                       uint64_t size;
+                       uint64_t type;
+                       char name[16];
+               } m = {};
+
+               m.cmd.size = sizeof(m);
+               m.cmd.file_size = 1024 * 1024;
+               m.cmd.items[0].type = KDBUS_ITEM_MEMFD_NAME;
+               m.cmd.items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(m.name);
+               strcpy(m.name, "my-name-is-nice");
+               ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &m);
                if (ret < 0) {
                        fprintf(stderr, "KDBUS_CMD_MEMFD_NEW failed: %m\n");
                        return EXIT_FAILURE;
                }
+               memfd = m.cmd.fd;
 
                if (write(memfd, "kdbus memfd 1234567", 19) != 19) {
                        fprintf(stderr, "writing to memfd failed: %m\n");
@@ -283,6 +306,7 @@ void msg_dump(const struct conn *conn, const struct kdbus_msg *msg)
                case KDBUS_ITEM_CGROUP:
                case KDBUS_ITEM_SECLABEL:
                case KDBUS_ITEM_DST_NAME:
+               case KDBUS_ITEM_CONN_NAME:
                        printf("  +%s (%llu bytes) '%s' (%zu)\n",
                               enum_MSG(item->type), item->size, item->str, strlen(item->str));
                        break;
index 163734f6ee4efa89d37a106b9c2232e550224f56..a7014adbae102bf09c211e125a45d316fdab69c4 100644 (file)
@@ -83,6 +83,7 @@ static int
 send_echo_request(struct conn *conn, uint64_t dst_id)
 {
        struct kdbus_msg *msg;
+       struct kdbus_cmd_memfd_make mfd = {};
        struct kdbus_item *item;
        uint64_t size;
        int memfd = -1;
@@ -94,11 +95,13 @@ send_echo_request(struct conn *conn, uint64_t dst_id)
        size = sizeof(struct kdbus_msg);
        size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
 
-       ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &memfd);
+       mfd.size = sizeof(struct kdbus_cmd_memfd_make);
+       ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &mfd);
        if (ret < 0) {
                fprintf(stderr, "KDBUS_CMD_MEMFD_NEW failed: %m\n");
                return EXIT_FAILURE;
        }
+       memfd = mfd.fd;
 
        if (write(memfd, &now, sizeof(now)) != sizeof(now)) {
                fprintf(stderr, "writing to memfd failed: %m\n");
index 14ccac710b4cb2493016fdb51449f5607d53a63b..9b8a07391bcc30b70c3f9f085858fb499448e23a 100644 (file)
@@ -180,8 +180,12 @@ static int send_message(const struct kdbus_conn *conn,
        if (dst_id == KDBUS_DST_ID_BROADCAST)
                size += KDBUS_ITEM_HEADER_SIZE + 64;
        else {
-               ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &memfd);
+               struct kdbus_cmd_memfd_make mfd;
+
+               mfd.size = sizeof(struct kdbus_cmd_memfd_make);
+               ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &mfd);
                ASSERT_RETURN(ret == 0);
+               memfd = mfd.fd;
 
                ASSERT_RETURN(write(memfd, "kdbus memfd 1234567", 19) == 19);
 
diff --git a/util.c b/util.c
index 9b0fef7843e771f17adbdb67418f8c4524938f00..48f121e78e5191a2216e9d3a1a30cef874ab9cc5 100644 (file)
--- a/util.c
+++ b/util.c
 #include "util.h"
 
 /**
- * kdbus_devname_valid - validate names showing up in /dev
+ * kdbus_sysname_valid - validate names showing up in /proc, /sys and /dev
  * @name:              Name of namespace, bus, endpoint
  *
  * Returns: 0 if the given name is valid, otherwise negative errno
  */
-int kdbus_devname_valid(const char *name)
+int kdbus_sysname_is_valid(const char *name)
 {
        unsigned int i;
        size_t len;
diff --git a/util.h b/util.h
index ade7841e9baf899a61bd467c0aaf96ac9669a8ae..919f18ad9d9edc7db991d441962b3d8235ab1ed8 100644 (file)
--- a/util.h
+++ b/util.h
@@ -105,5 +105,5 @@ static inline unsigned int kdbus_str_hash(const char *str)
        return full_name_hash(str, strlen(str));
 }
 
-int kdbus_devname_valid(const char *name);
+int kdbus_sysname_is_valid(const char *name);
 #endif