From: Daniel Mack Date: Tue, 21 Oct 2014 17:07:14 +0000 (+0200) Subject: kdbus.h: split in and out flags of ioctls (ABI break) X-Git-Tag: upstream/0.20141102.012929utc~64 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=20e3a970d94afa83e9127106a4a0b757f1289da7;p=platform%2Fcore%2Fsystem%2Fkdbus-bus.git kdbus.h: split in and out flags of ioctls (ABI break) Instead of negotating kernel flags via the same field for input and output, use two different bitfields for that, and call the returned flags 'kernel_flags'. The approach implemented before didn't turn out to work too well for more complex userspace programs that retain the same ioctl buffers for multiple calls, and which had to manually save and restore the flags before. While at it, rename conn_flags → flags in kdbus_cmd_hello to ease the internal helper functions and unify the API a bit more. Signed-off-by: Daniel Mack --- diff --git a/connection.c b/connection.c index 6093c13..363da06 100644 --- a/connection.c +++ b/connection.c @@ -1408,9 +1408,9 @@ int kdbus_conn_new(struct kdbus_ep *ep, BUG_ON(*c); - is_monitor = hello->conn_flags & KDBUS_HELLO_MONITOR; - is_activator = hello->conn_flags & KDBUS_HELLO_ACTIVATOR; - is_policy_holder = hello->conn_flags & KDBUS_HELLO_POLICY_HOLDER; + is_monitor = hello->flags & KDBUS_HELLO_MONITOR; + is_activator = hello->flags & KDBUS_HELLO_ACTIVATOR; + is_policy_holder = hello->flags & KDBUS_HELLO_POLICY_HOLDER; /* can't be activator or policy holder and monitor at the same time */ if (is_monitor && (is_activator || is_policy_holder)) @@ -1539,7 +1539,7 @@ int kdbus_conn_new(struct kdbus_ep *ep, BUILD_BUG_ON(sizeof(bus->id128) != sizeof(hello->id128)); memcpy(hello->id128, bus->id128, sizeof(hello->id128)); - conn->flags = hello->conn_flags; + conn->flags = hello->flags; atomic64_set(&conn->attach_flags, hello->attach_flags); if (is_activator) { diff --git a/handle.c b/handle.c index 762046c..5e6843d 100644 --- a/handle.c +++ b/handle.c @@ -440,8 +440,7 @@ static long kdbus_handle_ioctl_control(struct file *file, unsigned int cmd, make = p; - ret = kdbus_negotiate_flags(make->flags, buf, - offsetof(typeof(*make), flags), + ret = kdbus_negotiate_flags(make, buf, typeof(*make), KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD); if (ret < 0) @@ -496,8 +495,7 @@ static long kdbus_handle_ioctl_control(struct file *file, unsigned int cmd, make = p; - ret = kdbus_negotiate_flags(make->flags, buf, - offsetof(typeof(*make), flags), + ret = kdbus_negotiate_flags(make, buf, typeof(*make), KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD); if (ret < 0) @@ -573,8 +571,7 @@ static long kdbus_handle_ioctl_ep(struct file *file, unsigned int cmd, make = p; - ret = kdbus_negotiate_flags(make->flags, buf, - offsetof(typeof(*make), flags), + ret = kdbus_negotiate_flags(make, buf, typeof(*make), KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD); if (ret < 0) @@ -648,9 +645,7 @@ static long kdbus_handle_ioctl_ep(struct file *file, unsigned int cmd, hello = p; - ret = kdbus_negotiate_flags(hello->conn_flags, buf, - offsetof(struct kdbus_cmd_hello, - conn_flags), + ret = kdbus_negotiate_flags(hello, buf, typeof(*hello), KDBUS_HELLO_ACCEPT_FD | KDBUS_HELLO_ACTIVATOR | KDBUS_HELLO_POLICY_HOLDER | @@ -744,8 +739,7 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd, cmd_name = p; - ret = kdbus_negotiate_flags(cmd_name->flags, buf, - offsetof(typeof(*cmd_name), flags), + ret = kdbus_negotiate_flags(cmd_name, buf, typeof(*cmd_name), KDBUS_NAME_REPLACE_EXISTING | KDBUS_NAME_ALLOW_REPLACEMENT | KDBUS_NAME_QUEUE); @@ -762,7 +756,7 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd, break; /* return flags to the caller */ - if (copy_to_user(buf, p, ((struct kdbus_cmd_name *)p)->size)) + if (copy_to_user(buf, p, cmd_name->size)) ret = -EFAULT; break; @@ -786,8 +780,7 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd, cmd_name = p; - ret = kdbus_negotiate_flags(cmd_name->flags, buf, - offsetof(typeof(*cmd_name), flags), + ret = kdbus_negotiate_flags(cmd_name, buf, typeof(*cmd_name), 0); if (ret < 0) break; @@ -810,8 +803,7 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd, break; } - ret = kdbus_negotiate_flags(cmd_list.flags, buf, - offsetof(typeof(cmd_list), flags), + ret = kdbus_negotiate_flags(&cmd_list, buf, typeof(cmd_list), KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES | KDBUS_NAME_LIST_ACTIVATORS | @@ -844,8 +836,7 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd, cmd_info = p; - ret = kdbus_negotiate_flags(cmd_info->flags, buf, - offsetof(typeof(*cmd_info), flags), + ret = kdbus_negotiate_flags(cmd_info, buf, typeof(*cmd_info), _KDBUS_ATTACH_ALL); if (ret < 0) break; @@ -878,10 +869,8 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd, cmd_update = p; - ret = kdbus_negotiate_flags(cmd_update->flags, buf, - offsetof(typeof(*cmd_update), - flags), - 0); + ret = kdbus_negotiate_flags(cmd_update, buf, + typeof(*cmd_update), 0); if (ret < 0) break; @@ -911,9 +900,7 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd, cmd_match = p; - ret = kdbus_negotiate_flags(cmd_match->flags, buf, - offsetof(typeof(*cmd_match), - flags), + ret = kdbus_negotiate_flags(cmd_match, buf, typeof(*cmd_match), KDBUS_MATCH_REPLACE); if (ret < 0) break; @@ -945,9 +932,7 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd, cmd_match = p; - ret = kdbus_negotiate_flags(cmd_match->flags, buf, - offsetof(typeof(*cmd_match), - flags), + ret = kdbus_negotiate_flags(cmd_match, buf, typeof(*cmd_match), 0); if (ret < 0) break; @@ -1007,8 +992,7 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd, if (ret < 0) break; - ret = kdbus_negotiate_flags(cmd_recv.flags, buf, - offsetof(typeof(cmd_recv), flags), + ret = kdbus_negotiate_flags(&cmd_recv, buf, typeof(cmd_recv), KDBUS_RECV_PEEK | KDBUS_RECV_DROP | KDBUS_RECV_USE_PRIORITY); if (ret < 0) @@ -1061,8 +1045,7 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd, if (ret < 0) break; - ret = kdbus_negotiate_flags(cmd_free.flags, buf, - offsetof(typeof(cmd_free), flags), + ret = kdbus_negotiate_flags(&cmd_free, buf, typeof(cmd_free), 0); if (ret < 0) break; @@ -1102,10 +1085,8 @@ static long kdbus_handle_ioctl_ep_owner(struct file *file, unsigned int cmd, cmd_update = p; - ret = kdbus_negotiate_flags(cmd_update->flags, buf, - offsetof(typeof(*cmd_update), - flags), - 0); + ret = kdbus_negotiate_flags(cmd_update, buf, + typeof(*cmd_update), 0); if (ret < 0) break; diff --git a/kdbus.h b/kdbus.h index b255f37..087d50a 100644 --- a/kdbus.h +++ b/kdbus.h @@ -373,7 +373,8 @@ enum kdbus_payload_type { /** * struct kdbus_msg - the representation of a kdbus message * @size: Total size of the message - * @flags: Message flags (KDBUS_MSG_FLAGS_*) + * @flags: Message flags (KDBUS_MSG_FLAGS_*), userspace → kernel + * @kernel_flags: Supported message flags, kernel → userspace * @priority: Message queue priority value * @dst_id: 64-bit ID of the destination connection * @src_id: 64-bit ID of the source connection @@ -395,6 +396,7 @@ enum kdbus_payload_type { struct kdbus_msg { __u64 size; __u64 flags; + __u64 kernel_flags; __s64 priority; __u64 dst_id; __u64 src_id; @@ -429,7 +431,8 @@ enum kdbus_recv_flags { /** * struct kdbus_cmd_recv - struct to de-queue a buffered message - * @flags: KDBUS_RECV_* flags + * @flags: KDBUS_RECV_* flags, userspace → kernel + * @kernel_flags: Supported KDBUS_RECV_* flags, kernel → userspace * @priority: Minimum priority of the messages to de-queue. Lowest * values have the highest priority. * @offset: Returned offset in the pool where the message is @@ -440,6 +443,7 @@ enum kdbus_recv_flags { */ struct kdbus_cmd_recv { __u64 flags; + __u64 kernel_flags; __s64 priority; __u64 offset; } __attribute__((aligned(8))); @@ -458,15 +462,17 @@ struct kdbus_cmd_cancel { /** * struct kdbus_cmd_free - struct to free a slice of memory in the pool - * @offset The offset of the memory slice, as returned by other + * @offset: The offset of the memory slice, as returned by other * ioctls - * @flags Flags for the free command. Currently unused. + * @flags: Flags for the free command, userspace → kernel + * @kernel_flags: Supported flags of the free command, userspace → kernel * * This struct is used with the KDBUS_CMD_FREE ioctl. */ struct kdbus_cmd_free { __u64 offset; __u64 flags; + __u64 kernel_flags; } __attribute__((aligned(8))); /** @@ -557,7 +563,8 @@ enum kdbus_attach_flags { /** * struct kdbus_cmd_hello - struct to say hello to kdbus * @size: The total size of the structure - * @conn_flags: Connection flags (KDBUS_HELLO_*). + * @flags: Connection flags (KDBUS_HELLO_*), userspace → kernel + * @kernel_flags: Supported connection flags, kernel → userspace * @attach_flags: Mask of metadata to attach to each message sent * (KDBUS_ATTACH_*) * @bus_flags: The flags field copied verbatim from the original @@ -576,7 +583,8 @@ enum kdbus_attach_flags { */ struct kdbus_cmd_hello { __u64 size; - __u64 conn_flags; + __u64 flags; + __u64 kernel_flags; __u64 attach_flags; __u64 bus_flags; __u64 id; @@ -599,7 +607,9 @@ enum kdbus_make_flags { /** * struct kdbus_cmd_make - struct to make a bus, an endpoint or a domain * @size: The total size of the struct - * @flags: Properties for the bus/ep/domain to create + * @flags: Properties for the bus/ep/domain to create, + * userspace → kernel + * @kernel_flags: Supported flags for the used command, kernel → userspace * @items: Items describing details * * This structure is used with the KDBUS_CMD_BUS_MAKE, KDBUS_CMD_ENDPOINT_MAKE @@ -608,6 +618,7 @@ enum kdbus_make_flags { struct kdbus_cmd_make { __u64 size; __u64 flags; + __u64 kernel_flags; struct kdbus_item items[0]; } __attribute__((aligned(8))); @@ -630,7 +641,9 @@ enum kdbus_name_flags { /** * struct kdbus_cmd_name - struct to describe a well-known name * @size: The total size of the struct - * @flags: Flags for a name entry (KDBUS_NAME_*) + * @flags: Flags for a name entry (KDBUS_NAME_*), + * userspace → kernel, kernel → userspace + * @kernel_flags: Supported flags for a name entry, kernel → userspace * @items: Item list, containing the well-known name as * KDBUS_ITEM_NAME * @@ -639,6 +652,7 @@ enum kdbus_name_flags { struct kdbus_cmd_name { __u64 size; __u64 flags; + __u64 kernel_flags; struct kdbus_item items[0]; } __attribute__((aligned(8))); @@ -677,7 +691,9 @@ enum kdbus_name_list_flags { /** * struct kdbus_cmd_name_list - request a list of name entries - * @flags: Flags for the query (KDBUS_NAME_LIST_*) + * @flags: Flags for the query (KDBUS_NAME_LIST_*), + * userspace → kernel + * @kernel_flags: Supported flags for queries, kernel → userspace * @offset: The returned offset in the caller's pool buffer. * The user must use KDBUS_CMD_FREE to free the * allocated memory. @@ -686,6 +702,7 @@ enum kdbus_name_list_flags { */ struct kdbus_cmd_name_list { __u64 flags; + __u64 kernel_flags; __u64 offset; } __attribute__((aligned(8))); @@ -705,7 +722,8 @@ struct kdbus_name_list { /** * struct kdbus_cmd_conn_info - struct used for KDBUS_CMD_CONN_INFO ioctl * @size: The total size of the struct - * @flags: KDBUS_ATTACH_* flags + * @flags: KDBUS_ATTACH_* flags, userspace → kernel + * @kernel_flags: Supported KDBUS_ATTACH_* flags, kernel → userspace * @id: The 64-bit ID of the connection. If set to zero, passing * @name is required. kdbus will look up the name to * determine the ID in this case. @@ -722,6 +740,7 @@ struct kdbus_name_list { struct kdbus_cmd_conn_info { __u64 size; __u64 flags; + __u64 kernel_flags; __u64 id; __u64 offset; struct kdbus_item items[0]; @@ -747,6 +766,8 @@ struct kdbus_conn_info { /** * struct kdbus_cmd_update - update flags of a connection * @size: The total size of the struct + * @flags: Flags for the update command, userspace → kernel + * @kernel_flags: Supported flags for this command, kernel → userspace * @items: A list of struct kdbus_item * * This struct is used with the KDBUS_CMD_CONN_UPDATE ioctl. @@ -754,6 +775,7 @@ struct kdbus_conn_info { struct kdbus_cmd_update { __u64 size; __u64 flags; + __u64 kernel_flags; struct kdbus_item items[0]; } __attribute__((aligned(8))); @@ -772,6 +794,9 @@ enum kdbus_cmd_match_flags { * @size: The total size of the struct * @cookie: Userspace supplied cookie. When removing, the cookie * identifies the match to remove + * @flags: Flags for match command (KDBUS_MATCH_*), + * userspace → kernel + * @kernel_flags: Supported flags of the used command, kernel → userspace * @items: A list of items for additional information * * This structure is used with the KDBUS_CMD_ADD_MATCH and @@ -781,6 +806,7 @@ struct kdbus_cmd_match { __u64 size; __u64 cookie; __u64 flags; + __u64 kernel_flags; struct kdbus_item items[0]; } __attribute__((aligned(8))); diff --git a/kdbus.txt b/kdbus.txt index 00704b6..944d283 100644 --- a/kdbus.txt +++ b/kdbus.txt @@ -230,15 +230,15 @@ other usespace code that aims for compatibility to D-Bus might. 3.2 Flags --------- -All ioctls used in the communication with the driver contain a 64-bit flags -field. All bits that are not recognized by the kernel are rejected, and the -ioctl fails with -EINVAL. Regardless of whether the kernel accepts the -provided flags or not, the flags field in the ioctl buffer will be updated with -all the bits the kernel driver knows about in its current state, and set the -highest bit (KDBUS_FLAGS_KERNEL) as well. Userspace can use the returned value -to negotiate features. The KDBUS_FLAGS_KERNEL bit will never be valid in any -flags field of any command, so setting it will always make the ioctl fail. -Hence, this is a way to probe possible kernel features. +All ioctls used in the communication with the driver contain two 64-bit fields, +'flags' and 'kernel_flags'. In 'flags', the behavior of the command can be +tweaked, whereas in 'kernel_flags', the kernel driver writes back the mask of +supported bits upon each call, and sets the KDBUS_FLAGS_KERNEL bit. This is a +way to probe possible kernel features and make code forward and backward +compatible. + +All bits that are not recognized by the kernel in 'flags' are rejected, and the +ioctl fails with -EINVAL. 4. Items @@ -332,6 +332,9 @@ struct kdbus_cmd_make { KDBUS_MAKE_ACCESS_WORLD Make the device node world-accessible + __u64 kernel_flags; + Valid flags for this command, returned by the kernel upon each call. + struct kdbus_item items[0]; A list of items, only used for creating custom endpoints. Ignored for buses and domains. @@ -553,6 +556,9 @@ struct kdbus_cmd_conn_info { After the ioctl returns, this field will contain the current metadata attach flags of the connection. + __u64 kernel_flags; + Valid flags for this command, returned by the kernel upon each call. + __u64 id; The connection's numerical ID to retrieve information for. If set to non-zero value, the 'name' field is ignored. @@ -580,6 +586,9 @@ struct kdbus_conn_info { __u64 flags; The connection's flags as specified when it was created. + __u64 kernel_flags; + Valid flags for this command, returned by the kernel upon each call. + struct kdbus_item items[0]; Depending on the 'flags' field in struct kdbus_cmd_conn_info, items of types KDBUS_ITEM_NAME and KDBUS_ITEM_CONN_NAME are followed here. @@ -695,6 +704,10 @@ struct kdbus_msg { that behavior. With this bit set, and the remote being an activator, -EADDRNOTAVAIL is returned from the ioctl. + __u64 kernel_flags; + Valid flags for this command, returned by the kernel upon each call of + KDBUS_MSG_SEND. + __s64 priority; The priority of this message. Receiving messages (see below) may optionally be constrained to messages of a minimal priority. This @@ -855,6 +868,9 @@ struct kdbus_cmd_recv { KDBUS_RECV_USE_PRIORITY Use the priority field (see below). + __u64 kernel_flags; + Valid flags for this command, returned by the kernel upon each call. + __s64 priority; With KDBUS_RECV_USE_PRIORITY set in flags, receive the next message in the queue with at least the given priority. If no such message is waiting @@ -948,9 +964,8 @@ struct kdbus_cmd_name { first connection in that queue becomes the new owner and is notified accordingly. - __u64 owner_id; - __u64 conn_flags; - Unused in this use case. + __u64 kernel_flags; + Valid flags for this command, returned by the kernel upon each call. struct kdbus_item items[0]; Items to submit the name. Currently, one one item of type KDBUS_ITEM_NAME @@ -976,9 +991,6 @@ struct kdbus_cmd_name { terminator. __u64 flags; - __u64 owner_id; - __u64 conn_flags; - All unused for this use case. struct kdbus_item items[0]; Items to submit the name. Currently, one one item of type KDBUS_ITEM_NAME @@ -1021,7 +1033,7 @@ The returned list of names is stored in a struct kdbus_name_list that in turn contains a dynamic number of struct kdbus_cmd_name that carry the actual information. The fields inside that struct kdbus_cmd_name is described next. -struct kdbus_cmd_name { +struct kdbus_name_info { __u64 size; The overall size of this struct, including the name with its 0-byte string terminator. @@ -1293,6 +1305,9 @@ struct kdbus_cmd_match { __u64 flags; Unused for this use case, + __u64 kernel_flags; + Valid flags for this command, returned by the kernel upon each call. + struct kdbus_item items[0]; Unused for this use case. }; diff --git a/message.c b/message.c index 89dfd4a..65c3a26 100644 --- a/message.c +++ b/message.c @@ -372,8 +372,7 @@ int kdbus_kmsg_new_from_user(struct kdbus_conn *conn, goto exit_free; } - ret = kdbus_negotiate_flags(m->msg.flags, msg, - offsetof(struct kdbus_msg, flags), + ret = kdbus_negotiate_flags(&m->msg, msg, struct kdbus_msg, KDBUS_MSG_FLAGS_EXPECT_REPLY | KDBUS_MSG_FLAGS_SYNC_REPLY | KDBUS_MSG_FLAGS_NO_AUTO_START); diff --git a/test/kdbus-util.c b/test/kdbus-util.c index f3a2144..5b9ff06 100644 --- a/test/kdbus-util.c +++ b/test/kdbus-util.c @@ -139,7 +139,7 @@ kdbus_hello(const char *path, uint64_t flags, return NULL; } - h.hello.conn_flags = flags | KDBUS_HELLO_ACCEPT_FD; + h.hello.flags = flags | KDBUS_HELLO_ACCEPT_FD; h.hello.attach_flags = _KDBUS_ATTACH_ALL; h.conn_name.type = KDBUS_ITEM_CONN_NAME; strcpy(h.conn_name.str, "this-is-my-name"); @@ -820,8 +820,6 @@ int kdbus_name_acquire(struct kdbus_conn *conn, cmd_name->size = size; if (flags) cmd_name->flags = *flags; - else - cmd_name->flags = 0; ret = ioctl(conn->fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name); if (ret < 0) { diff --git a/test/test-connection.c b/test/test-connection.c index de74c34..f451794 100644 --- a/test/test-connection.c +++ b/test/test-connection.c @@ -57,7 +57,6 @@ int kdbus_test_bus_make(struct kdbus_test_env *env) bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1; bus_make.head.size = sizeof(struct kdbus_cmd_make) + sizeof(bus_make.bs) + bus_make.n_size; - bus_make.head.flags = 0; ret = ioctl(env->control_fd, KDBUS_CMD_BUS_MAKE, &bus_make); ASSERT_RETURN(ret == -1 && errno == EINVAL); @@ -66,7 +65,6 @@ int kdbus_test_bus_make(struct kdbus_test_env *env) bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1; bus_make.head.size = sizeof(struct kdbus_cmd_make) + sizeof(bus_make.bs) + bus_make.n_size; - bus_make.head.flags = 0; ret = ioctl(env->control_fd, KDBUS_CMD_BUS_MAKE, &bus_make); ASSERT_RETURN(ret == -1 && errno == EINVAL); @@ -75,7 +73,6 @@ int kdbus_test_bus_make(struct kdbus_test_env *env) bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1; bus_make.head.size = sizeof(struct kdbus_cmd_make) + sizeof(bus_make.bs) + bus_make.n_size; - bus_make.head.flags = 0; ret = ioctl(env->control_fd, KDBUS_CMD_BUS_MAKE, &bus_make); ASSERT_RETURN(ret == -1 && errno == EINVAL); @@ -84,7 +81,6 @@ int kdbus_test_bus_make(struct kdbus_test_env *env) bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1; bus_make.head.size = sizeof(struct kdbus_cmd_make) + sizeof(bus_make.bs) + bus_make.n_size; - bus_make.head.flags = 0; ret = ioctl(env->control_fd, KDBUS_CMD_BUS_MAKE, &bus_make); ASSERT_RETURN(ret == 0); snprintf(s, sizeof(s), "/dev/" KBUILD_MODNAME "/%u-blah-1/bus", uid); @@ -108,7 +104,7 @@ int kdbus_test_hello(struct kdbus_test_env *env) if (fd < 0) return TEST_ERR; - hello.conn_flags = KDBUS_HELLO_ACCEPT_FD; + hello.flags = KDBUS_HELLO_ACCEPT_FD; hello.attach_flags = _KDBUS_ATTACH_ALL; hello.size = sizeof(struct kdbus_cmd_hello); hello.pool_size = POOL_SIZE; @@ -119,37 +115,33 @@ int kdbus_test_hello(struct kdbus_test_env *env) /* a size of 0 must return EMSGSIZE */ hello.size = 1; - hello.conn_flags = KDBUS_HELLO_ACCEPT_FD; + hello.flags = KDBUS_HELLO_ACCEPT_FD; ret = ioctl(fd, KDBUS_CMD_HELLO, &hello); ASSERT_RETURN(ret == -1 && errno == EINVAL); hello.size = sizeof(struct kdbus_cmd_hello); /* check faulty flags */ - hello.conn_flags = 1ULL << 32; + hello.flags = 1ULL << 32; ret = ioctl(fd, KDBUS_CMD_HELLO, &hello); ASSERT_RETURN(ret == -1 && errno == EINVAL); /* kernel must have set its bit in the ioctl buffer */ - ASSERT_RETURN(hello.conn_flags & KDBUS_FLAG_KERNEL); - - hello.conn_flags = KDBUS_HELLO_ACCEPT_FD; + ASSERT_RETURN(hello.kernel_flags & KDBUS_FLAG_KERNEL); /* check for faulty pool sizes */ hello.pool_size = 0; - hello.conn_flags = KDBUS_HELLO_ACCEPT_FD; + hello.flags = KDBUS_HELLO_ACCEPT_FD; ret = ioctl(fd, KDBUS_CMD_HELLO, &hello); ASSERT_RETURN(ret == -1 && errno == EFAULT); hello.pool_size = 4097; - hello.conn_flags = KDBUS_HELLO_ACCEPT_FD; ret = ioctl(fd, KDBUS_CMD_HELLO, &hello); ASSERT_RETURN(ret == -1 && errno == EFAULT); hello.pool_size = POOL_SIZE; /* success test */ - hello.conn_flags = KDBUS_HELLO_ACCEPT_FD; ret = ioctl(fd, KDBUS_CMD_HELLO, &hello); ASSERT_RETURN(ret == 0); @@ -159,7 +151,7 @@ int kdbus_test_hello(struct kdbus_test_env *env) ASSERT_RETURN(fd >= 0); /* no ACTIVATOR flag without a name */ - hello.conn_flags = KDBUS_HELLO_ACTIVATOR; + hello.flags = KDBUS_HELLO_ACTIVATOR; ret = ioctl(fd, KDBUS_CMD_HELLO, &hello); ASSERT_RETURN(ret == -1 && errno == EINVAL); @@ -315,7 +307,7 @@ int kdbus_test_writable_pool(struct kdbus_test_env *env) ASSERT_RETURN(fd >= 0); memset(&hello, 0, sizeof(hello)); - hello.conn_flags = KDBUS_HELLO_ACCEPT_FD; + hello.flags = KDBUS_HELLO_ACCEPT_FD; hello.attach_flags = _KDBUS_ATTACH_ALL; hello.size = sizeof(struct kdbus_cmd_hello); hello.pool_size = POOL_SIZE; diff --git a/test/test-domain.c b/test/test-domain.c index 9d7b08a..9b54e0a 100644 --- a/test/test-domain.c +++ b/test/test-domain.c @@ -48,13 +48,11 @@ int kdbus_test_domain_make(struct kdbus_test_env *env) F_OK) == 0); /* can't use the same fd for domain make twice */ - domain_make.head.flags = 0; ret = ioctl(fd, KDBUS_CMD_DOMAIN_MAKE, &domain_make); ASSERT_RETURN(ret == -1 && errno == EBADFD); /* can't register the same name twice */ fd2 = open("/dev/" KBUILD_MODNAME "/control", O_RDWR|O_CLOEXEC); - domain_make.head.flags = 0; ret = ioctl(fd2, KDBUS_CMD_DOMAIN_MAKE, &domain_make); ASSERT_RETURN(ret == -1 && errno == EEXIST); close(fd2); diff --git a/test/test-free.c b/test/test-free.c index abac022..f43e3f6 100644 --- a/test/test-free.c +++ b/test/test-free.c @@ -26,7 +26,6 @@ int kdbus_test_free(struct kdbus_test_env *env) ASSERT_RETURN(ret == -1 && errno == ENXIO); /* free a buffer out of the pool's bounds */ - cmd_free.flags = 0; cmd_free.offset = POOL_SIZE + 1; ret = ioctl(env->conn->fd, KDBUS_CMD_FREE, &cmd_free); ASSERT_RETURN(ret == -1 && errno == ENXIO); diff --git a/tools/kdbus-monitor.c b/tools/kdbus-monitor.c index 4bb61b7..cf15ac2 100644 --- a/tools/kdbus-monitor.c +++ b/tools/kdbus-monitor.c @@ -81,7 +81,7 @@ static struct conn *kdbus_hello(const char *path, uint64_t flags) return NULL; } - h.hello.conn_flags = flags | KDBUS_HELLO_ACCEPT_FD; + h.hello.flags = flags | KDBUS_HELLO_ACCEPT_FD; h.hello.attach_flags = _KDBUS_ATTACH_ALL; h.type = KDBUS_ITEM_CONN_NAME; strncpy(h.comm, "monitor", sizeof(h.comm) - 1); diff --git a/util.c b/util.c index d97b9d8..8241e15 100644 --- a/util.c +++ b/util.c @@ -51,11 +51,11 @@ int kdbus_sysname_is_valid(const char *name) } /** - * kdbus_negotiate_flags() - check flags provided by user, and write the - * valid mask back + * kdbus_check_and_write_flags() - check flags provided by user, and write the + * valid mask back * @flags: The flags mask provided by userspace * @buf: The buffer provided by userspace - * @offset: Offset of the flags field inside the user-provided struct + * @offset_out: Offset of the kernel_flags field inside the user-provided struct * @valid: Mask of valid bits * * This function will check whether the flags provided by userspace are within @@ -65,7 +65,8 @@ int kdbus_sysname_is_valid(const char *name) * Return: 0 on success, -EFAULT if copy_to_user() failed, or -EINVAL if * userspace submitted invalid bits in its mask. */ -int kdbus_negotiate_flags(u64 flags, void __user *buf, off_t offset, u64 valid) +int kdbus_check_and_write_flags(u64 flags, void __user *buf, + off_t offset_out, u64 valid) { u64 val = valid | KDBUS_FLAG_KERNEL; @@ -75,7 +76,7 @@ int kdbus_negotiate_flags(u64 flags, void __user *buf, off_t offset, u64 valid) */ WARN_ON_ONCE(valid & KDBUS_FLAG_KERNEL); - if (copy_to_user(((u8 __user *) buf) + offset, &val, sizeof(val))) + if (copy_to_user(((u8 __user *) buf) + offset_out, &val, sizeof(val))) return -EFAULT; if (flags & ~valid) diff --git a/util.h b/util.h index 477f311..d84b820 100644 --- a/util.h +++ b/util.h @@ -83,7 +83,12 @@ static inline bool kdbus_str_valid(const char *str, size_t size) } int kdbus_sysname_is_valid(const char *name); -int kdbus_negotiate_flags(u64 flags, void __user *buf, off_t offset, u64 valid); void kdbus_fput_files(struct file **files, unsigned int count); +int kdbus_check_and_write_flags(u64 flags, void __user *buf, + off_t offset_out, u64 valid); + +#define kdbus_negotiate_flags(_s, _b, _t, _v) \ + kdbus_check_and_write_flags((_s)->flags, _b, \ + offsetof(_t, kernel_flags), _v) \ #endif