Permalink
Browse files

allow to set and query connections and memfds a human-readable names …

…(ABI break)
  • Loading branch information...
1 parent 3485129 commit 7a36e7969278d982ce36bfa90faf1d2d8d841d6d @kaysievers kaysievers committed Jan 14, 2014
Showing with 302 additions and 98 deletions.
  1. +2 −6 bus.c
  2. +47 −1 connection.c
  3. +2 −0 connection.h
  4. +1 −1 defaults.h
  5. +2 −6 endpoint.c
  6. +93 −24 handle.c
  7. +40 −15 kdbus.h
  8. +31 −6 memfd.c
  9. +1 −1 memfd.h
  10. +0 −3 message.c
  11. +0 −1 message.h
  12. +9 −0 metadata.c
  13. +0 −2 metadata.h
  14. +2 −6 namespace.c
  15. +19 −5 pool.c
  16. +1 −1 pool.h
  17. +1 −0 test/kdbus-enum.c
  18. +39 −15 test/kdbus-util.c
  19. +4 −1 test/test-kdbus-benchmark.c
  20. +5 −1 test/test-kdbus.c
  21. +2 −2 util.c
  22. +1 −1 util.h
View
8 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;
}
}
View
@@ -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;
View
@@ -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;
View
@@ -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
View
@@ -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;
}
}
View
117 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;
Oops, something went wrong.

0 comments on commit 7a36e79

Please sign in to comment.