summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2013-05-17 23:23:38 +0200
committerKay Sievers <kay@vrfy.org>2013-05-17 23:23:38 +0200
commit9fd5af6ccb405b11385758e0046a2f6b0abec64d (patch)
tree1779f8ef4d340d9d8b66c76f29b3b6a5f5a6db2e
parentb40d52eb207c938c15aa600aba43c2cab33875ef (diff)
downloadkdbus-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.c2
-rw-r--r--connection.c28
-rw-r--r--endpoint.c2
-rw-r--r--internal.h37
-rw-r--r--kdbus.h2
-rw-r--r--match.c2
-rw-r--r--memfd.c6
-rw-r--r--message.c4
-rw-r--r--names.c8
-rw-r--r--namespace.c2
-rw-r--r--policy.c2
-rw-r--r--test/kdbus-util.c8
-rw-r--r--test/kdbus-util.h2
13 files changed, 46 insertions, 59 deletions
diff --git a/bus.c b/bus.c
index 292260bb740..d2ce3dcc7bf 100644
--- a/bus.c
+++ b/bus.c
@@ -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)
diff --git a/kdbus.h b/kdbus.h
index 20b804539b5..214bf51197b 100644
--- a/kdbus.h
+++ b/kdbus.h
@@ -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),
diff --git a/match.c b/match.c
index 04fb82f87f2..4081babb20c 100644
--- a/match.c
+++ b/match.c
@@ -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)
diff --git a/memfd.c b/memfd.c
index cbc7155d039..db50c64bf30 100644
--- a/memfd.c
+++ b/memfd.c
@@ -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)
diff --git a/names.c b/names.c
index 670668ed784..26d43ee35e7 100644
--- a/names.c
+++ b/names.c
@@ -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(&reg->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)
diff --git a/policy.c b/policy.c
index 5ab4797ff7f..6688a16a7a8 100644
--- a/policy.c
+++ b/policy.c
@@ -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)