diff options
author | Kay Sievers <kay@vrfy.org> | 2013-05-17 23:23:38 +0200 |
---|---|---|
committer | Kay Sievers <kay@vrfy.org> | 2013-05-17 23:23:38 +0200 |
commit | 9fd5af6ccb405b11385758e0046a2f6b0abec64d (patch) | |
tree | 1779f8ef4d340d9d8b66c76f29b3b6a5f5a6db2e | |
parent | b40d52eb207c938c15aa600aba43c2cab33875ef (diff) | |
download | kdbus-bus-9fd5af6ccb405b11385758e0046a2f6b0abec64d.tar.gz kdbus-bus-9fd5af6ccb405b11385758e0046a2f6b0abec64d.tar.bz2 kdbus-bus-9fd5af6ccb405b11385758e0046a2f6b0abec64d.zip |
make sure we always pass __u64 in the API, never long or pointer
-rw-r--r-- | bus.c | 2 | ||||
-rw-r--r-- | connection.c | 28 | ||||
-rw-r--r-- | endpoint.c | 2 | ||||
-rw-r--r-- | internal.h | 37 | ||||
-rw-r--r-- | kdbus.h | 2 | ||||
-rw-r--r-- | match.c | 2 | ||||
-rw-r--r-- | memfd.c | 6 | ||||
-rw-r--r-- | message.c | 4 | ||||
-rw-r--r-- | names.c | 8 | ||||
-rw-r--r-- | namespace.c | 2 | ||||
-rw-r--r-- | policy.c | 2 | ||||
-rw-r--r-- | test/kdbus-util.c | 8 | ||||
-rw-r--r-- | test/kdbus-util.h | 2 |
13 files changed, 46 insertions, 59 deletions
@@ -215,7 +215,7 @@ int kdbus_bus_make_user(void __user *buf, struct kdbus_cmd_bus_kmake **kmake) const struct kdbus_item *item; int ret; - if (kdbus_size_get_user(size, buf, struct kdbus_cmd_bus_make)) + if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_bus_make)) return -EFAULT; if (size < sizeof(struct kdbus_cmd_bus_make) || size > KDBUS_MAKE_MAX_SIZE) diff --git a/connection.c b/connection.c index c2d41a50690..fcf80823506 100644 --- a/connection.c +++ b/connection.c @@ -205,9 +205,9 @@ static int kdbus_conn_payload_add(struct kdbus_conn_queue *queue, it->size = size; /* A NULL address is a "padding vec" for alignement */ - if (KDBUS_VEC_PTR(&item->vec)) + if (KDBUS_PTR(item->vec.address)) addr = slice->buf + vec_data; - it->vec.address = KDBUS_VEC_ADDR(addr); + it->vec.address = KDBUS_ADDR(addr); it->vec.size = item->vec.size; ret = kdbus_pool_slice_copy(slice, items, it, size); if (ret < 0) @@ -215,8 +215,7 @@ static int kdbus_conn_payload_add(struct kdbus_conn_queue *queue, /* copy kdbus_vec data directly from sender */ ret = kdbus_pool_slice_copy_user(slice, vec_data, - KDBUS_VEC_PTR(&item->vec), - item->vec.size); + KDBUS_PTR(item->vec.address), item->vec.size); if (ret < 0) return ret; @@ -680,14 +679,15 @@ remove_unused: } static int -kdbus_conn_recv_msg(struct kdbus_conn *conn, struct kdbus_msg __user **msg_ptr) +kdbus_conn_recv_msg(struct kdbus_conn *conn, __u64 __user *address) { struct kdbus_conn_queue *queue; + u64 addr; int *memfds = NULL; unsigned int i; int ret; - if (!KDBUS_IS_ALIGNED8((unsigned long)msg_ptr)) + if (!KDBUS_IS_ALIGNED8((unsigned long)address)) return -EFAULT; mutex_lock(&conn->lock); @@ -699,7 +699,8 @@ kdbus_conn_recv_msg(struct kdbus_conn *conn, struct kdbus_msg __user **msg_ptr) /* return the address of the next message in the pool */ queue = list_first_entry(&conn->msg_list, struct kdbus_conn_queue, entry); - if (put_user(queue->msg, msg_ptr)) { + addr = KDBUS_ADDR(queue->msg); + if (copy_to_user(address, &addr, sizeof(__u64))) { ret = -EFAULT; goto exit_unlock; } @@ -1117,7 +1118,7 @@ static long kdbus_conn_ioctl_ep(struct file *file, unsigned int cmd, break; } - if (kdbus_size_get_user(size, buf, struct kdbus_cmd_hello)) { + if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_hello)) { ret = -EFAULT; break; } @@ -1147,8 +1148,10 @@ static long kdbus_conn_ioctl_ep(struct file *file, unsigned int cmd, } switch (item->type) { - case KDBUS_HELLO_POOL: - if (!KDBUS_VEC_PTR(&item->vec) || + case KDBUS_HELLO_POOL: { + void *p; + + if (!KDBUS_PTR(item->vec.address) || item->vec.size == 0) { ret = -EINVAL; break; @@ -1161,10 +1164,11 @@ static long kdbus_conn_ioctl_ep(struct file *file, unsigned int cmd, break; } + p = KDBUS_PTR(item->vec.address); ret = kdbus_pool_init(&conn->pool, - KDBUS_VEC_PTR(&item->vec), - item->vec.size); + p, item->vec.size); break; + } default: ret = -ENOTSUPP; diff --git a/endpoint.c b/endpoint.c index d56c40d52d9..c0edf0fa984 100644 --- a/endpoint.c +++ b/endpoint.c @@ -221,7 +221,7 @@ int kdbus_ep_kmake_user(void __user *buf, struct kdbus_cmd_ep_kmake **kmake) const struct kdbus_item *item; int ret; - if (kdbus_size_get_user(size, buf, struct kdbus_cmd_ep_make)) + if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_ep_make)) return -EFAULT; if (size < sizeof(struct kdbus_cmd_ep_make) || size > KDBUS_MAKE_MAX_SIZE) diff --git a/internal.h b/internal.h index f8e460fa28c..7c1ba7f6e2f 100644 --- a/internal.h +++ b/internal.h @@ -34,8 +34,8 @@ #define KDBUS_CHAR_MAJOR 222 /* FIXME: move to uapi/linux/major.h */ -#define KDBUS_VEC_PTR(vec) ((void *)(uintptr_t)(vec)->address) -#define KDBUS_VEC_ADDR(ptr) ((u64)(ptr)) +#define KDBUS_PTR(addr) ((void *)(uintptr_t)(addr)) +#define KDBUS_ADDR(ptr) ((u64)(ptr)) #define KDBUS_ALIGN8(s) ALIGN((s), 8) #define KDBUS_IS_ALIGNED8(s) (IS_ALIGNED(s, 8)) @@ -57,33 +57,16 @@ #define KDBUS_MSG_HEADER_SIZE offsetof(struct kdbus_msg, items) -/* some architectures miss get_user_8(); copy only the lower 32bit */ -#ifdef CONFIG_64BIT -#define kdbus_size_get_user(_s, _b, _t) \ -({ \ - u64 __user *_sz = (void __user *)(_b) + offsetof(typeof(_t), size); \ - get_user(_s, _sz); \ +#define kdbus_size_get_user(_s, _b, _t) \ +({ \ + u64 __user *_sz = (void __user *)(_b) + offsetof(typeof(_t), size); \ + copy_from_user(_s, _sz, sizeof(__u64)); \ }) -#else - #ifdef __LITTLE_ENDIAN__ - #define kdbus_size_get_user(_s, _b, _t) \ - ({ \ - u32 __user *_sz = (void __user *)(_b) + offsetof(typeof(_t), size); \ - get_user(_s, _sz); \ - }) - #else - #define kdbus_size_get_user(_s, _b, _t) \ - ({ \ - u32 __user *_sz = (void __user *)(_b) + sizeof(u32) + offsetof(typeof(_t), size); \ - get_user(_s, _sz); \ - }) - #endif -#endif -#define kdbus_size_set_user(_s, _b, _t) \ -({ \ - u64 __user *_sz = _b + offsetof(typeof(_t), size); \ - put_user(_s, _sz); \ +#define kdbus_size_set_user(_s, _b, _t) \ +({ \ + u64 __user *_sz = _b + offsetof(typeof(_t), size); \ + put_user(_s, _sz); \ }) static inline bool kdbus_validate_nul(const char *s, size_t l) @@ -405,7 +405,7 @@ enum kdbus_cmd { /* kdbus ep node commands: require connected state */ KDBUS_CMD_MSG_SEND = _IOWR(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg), - KDBUS_CMD_MSG_RECV = _IOWR(KDBUS_IOC_MAGIC, 0x41, struct kdbus_msg *), + KDBUS_CMD_MSG_RECV = _IOWR(KDBUS_IOC_MAGIC, 0x41, __u64 *), KDBUS_CMD_MSG_RELEASE = _IOWR(KDBUS_IOC_MAGIC, 0x42, struct kdbus_msg), KDBUS_CMD_NAME_ACQUIRE = _IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name), @@ -269,7 +269,7 @@ struct kdbus_cmd_match *cmd_match_from_user(void __user *buf) struct kdbus_cmd_match *cmd_match; u64 size; - if (kdbus_size_get_user(size, buf, struct kdbus_cmd_match)) + if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_match)) return ERR_PTR(-EFAULT); if (size < sizeof(*cmd_match) || size > KDBUS_MATCH_MAX_SIZE) @@ -241,9 +241,8 @@ kdbus_memfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case KDBUS_CMD_MEMFD_SIZE_GET: { u64 size = i_size_read(file_inode(mf->fp)); - u64 __user *addr = argp; - if (put_user(size, addr)) { + if (copy_to_user(argp, &size, sizeof(__u64))) { ret = -EFAULT; goto exit; } @@ -251,10 +250,9 @@ kdbus_memfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } case KDBUS_CMD_MEMFD_SIZE_SET: { - int __user *addr = argp; u64 size; - if (get_user(size, addr)) { + if (copy_from_user(&size, argp, sizeof(__u64))) { ret = -EFAULT; goto exit; } diff --git a/message.c b/message.c index fa75d6f4442..a82e84ea4f9 100644 --- a/message.c +++ b/message.c @@ -54,7 +54,7 @@ static void __maybe_unused kdbus_msg_dump(const struct kdbus_msg *msg) switch (item->type) { case KDBUS_MSG_PAYLOAD_VEC: pr_info("+KDBUS_MSG_PAYLOAD_VEC (%zu bytes) address=%p size=%zu\n", - (size_t)item->size, KDBUS_VEC_PTR(&item->vec), + (size_t)item->size, KDBUS_PTR(item->vec.address), (size_t)item->vec.size); break; @@ -252,7 +252,7 @@ int kdbus_kmsg_new_from_user(struct kdbus_conn *conn, if (!KDBUS_IS_ALIGNED8((unsigned long)msg)) return -EFAULT; - if (kdbus_size_get_user(size, msg, struct kdbus_msg)) + if (kdbus_size_get_user(&size, msg, struct kdbus_msg)) return -EFAULT; if (size < sizeof(struct kdbus_msg) || size > KDBUS_MSG_MAX_SIZE) @@ -269,7 +269,7 @@ int kdbus_cmd_name_acquire(struct kdbus_name_registry *reg, u32 hash; int ret = 0; - if (kdbus_size_get_user(size, buf, struct kdbus_cmd_name)) + if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_name)) return -EFAULT; if ((size < sizeof(struct kdbus_cmd_name)) || @@ -378,7 +378,7 @@ int kdbus_cmd_name_release(struct kdbus_name_registry *reg, u32 hash; int ret = 0; - if (kdbus_size_get_user(size, buf, struct kdbus_cmd_name)) + if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_name)) return -EFAULT; if ((size < sizeof(struct kdbus_cmd_name)) || @@ -419,7 +419,7 @@ int kdbus_cmd_name_list(struct kdbus_name_registry *reg, u64 user_size, size = 0, tmp; int ret = 0; - if (kdbus_size_get_user(user_size, buf, struct kdbus_cmd_names)) + if (kdbus_size_get_user(&user_size, buf, struct kdbus_cmd_names)) return -EFAULT; mutex_lock(®->entries_lock); @@ -519,7 +519,7 @@ int kdbus_cmd_name_query(struct kdbus_name_registry *reg, int ret = 0; char *name = NULL; - if (kdbus_size_get_user(size, buf, struct kdbus_cmd_name_info)) + if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_name_info)) return -EFAULT; if ((size < sizeof(struct kdbus_cmd_name_info)) || diff --git a/namespace.c b/namespace.c index 830466d1f13..0c83ac8e457 100644 --- a/namespace.c +++ b/namespace.c @@ -240,7 +240,7 @@ int kdbus_ns_kmake_user(void __user *buf, struct kdbus_cmd_ns_kmake **kmake) const struct kdbus_item *item; int ret; - if (kdbus_size_get_user(size, buf, struct kdbus_cmd_ns_make)) + if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_ns_make)) return -EFAULT; if (size < sizeof(struct kdbus_cmd_ns_make) || size > KDBUS_MAKE_MAX_SIZE) @@ -436,7 +436,7 @@ int kdbus_cmd_policy_set_from_user(struct kdbus_policy_db *db, void __user *buf) u64 size; int ret; - if (kdbus_size_get_user(size, buf, struct kdbus_cmd_policy)) + if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_policy)) return -EFAULT; if (size < sizeof(struct kdbus_msg) || size > KDBUS_POLICY_MAX_SIZE) { diff --git a/test/kdbus-util.c b/test/kdbus-util.c index 33dd5a368de..7f15d23fbe7 100644 --- a/test/kdbus-util.c +++ b/test/kdbus-util.c @@ -227,13 +227,13 @@ void msg_dump(struct kdbus_msg *msg) switch (item->type) { case KDBUS_MSG_PAYLOAD_VEC: { - char *s = (char *)KDBUS_VEC_PTR(&item->vec); + char *s = (char *)KDBUS_PTR(item->vec.address); if (!s) s = "[padding bytes]"; printf(" +%s (%llu bytes) addr=%p size=%llu '%s'\n", - enum_MSG(item->type), item->size, KDBUS_VEC_PTR(&item->vec), + enum_MSG(item->type), item->size, KDBUS_PTR(item->vec.address), (unsigned long long)item->vec.size, s); break; } @@ -376,15 +376,17 @@ void msg_dump(struct kdbus_msg *msg) int msg_recv(struct conn *conn) { + uint64_t addr; struct kdbus_msg *msg; int ret; - ret = ioctl(conn->fd, KDBUS_CMD_MSG_RECV, &msg); + ret = ioctl(conn->fd, KDBUS_CMD_MSG_RECV, &addr); if (ret < 0) { fprintf(stderr, "error receiving message: %d (%m)\n", ret); return EXIT_FAILURE; } + msg = KDBUS_PTR(addr); msg_dump(msg); ret = ioctl(conn->fd, KDBUS_CMD_MSG_RELEASE, msg); diff --git a/test/kdbus-util.h b/test/kdbus-util.h index ca5358f3cf6..69fbe4a0c51 100644 --- a/test/kdbus-util.h +++ b/test/kdbus-util.h @@ -14,7 +14,7 @@ #define STRINGIFY(x) _STRINGIFY(x) #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) -#define KDBUS_VEC_PTR(vec) ((void *)(uintptr_t)(vec)->address) +#define KDBUS_PTR(addr) ((void *)(uintptr_t)(addr)) #define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) #define KDBUS_ALIGN8(l) (((l) + 7) & ~7) |