diff options
-rw-r--r-- | src/libsystemd-bus/bus-control.c | 95 | ||||
-rw-r--r-- | src/libsystemd-bus/bus-kernel.c | 2 | ||||
-rw-r--r-- | src/libsystemd-bus/bus-message.c | 2 | ||||
-rw-r--r-- | src/libsystemd-bus/kdbus.h | 53 | ||||
-rw-r--r-- | src/libsystemd-bus/sd-bus.c | 5 |
5 files changed, 67 insertions, 90 deletions
diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c index a0eeb305da..1d1f6d0f39 100644 --- a/src/libsystemd-bus/bus-control.c +++ b/src/libsystemd-bus/bus-control.c @@ -174,36 +174,23 @@ _public_ int sd_bus_list_names(sd_bus *bus, char ***l) { assert_return(!bus_pid_changed(bus), -ECHILD); if (bus->is_kernel) { - _cleanup_free_ struct kdbus_cmd_names *names = NULL; + _cleanup_free_ struct kdbus_cmd_name_list *cmd = NULL; + struct kdbus_name_list *name_list; struct kdbus_cmd_name *name; - size_t size; - /* assume 8k size first. If that doesn't suffice, kdbus will tell us - * how big the buffer needs to be. */ - size = 8192; - - for(;;) { - names = realloc(names, size); - if (!names) - return -ENOMEM; - - names->size = size; - names->flags = KDBUS_NAME_LIST_UNIQUE_NAMES; + cmd = malloc0(sizeof(struct kdbus_cmd_name_list *)); + if (!cmd) + return -ENOMEM; - r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_LIST, names); - if (r < 0) { - if (errno == ENOBUFS && size != names->size) { - size = names->size; - continue; - } + cmd->flags = KDBUS_NAME_LIST_UNIQUE_NAMES; - return -errno; - } + r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_LIST, cmd); + if (r < 0) + return -errno; - break; - } + name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd->offset); - KDBUS_PART_FOREACH(name, names, names) { + KDBUS_PART_FOREACH(name, name_list, names) { char *n; if (name->size > sizeof(*name)) @@ -216,6 +203,10 @@ _public_ int sd_bus_list_names(sd_bus *bus, char ***l) { return -ENOMEM; } + r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_FREE, &cmd->offset); + if (r < 0) + return -errno; + *l = x; } else { r = sd_bus_call_method( @@ -587,7 +578,7 @@ static int add_name_change_match(sd_bus *bus, return 0; } -static int kdbus_name_query( +static int kdbus_name_info( sd_bus *bus, const char *name, uint64_t mask, @@ -596,52 +587,32 @@ static int kdbus_name_query( _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL; + _cleanup_free_ struct kdbus_cmd_name_info *cmd = NULL; _cleanup_free_ char *unique = NULL; - struct kdbus_cmd_name_info *name_info = NULL; + struct kdbus_name_info *name_info; struct kdbus_item *item; uint64_t attach_flags, m; - size_t slen, size; + size_t size; int r; r = kdbus_translate_attach_flags(mask, &attach_flags); if (r < 0) return r; - slen = strlen(name) + 1; - - /* - * The structure is used for both directions. Start with 8k buffer size and - * expand to the size kdbus reports in case we fail. - */ - size = slen + 8192; - - for(;;) { - name_info = realloc(name_info, size); - if (!name_info) - return -ENOMEM; - - memset(name_info, 0, size); - - name_info->size = size; - name_info->attach_flags = attach_flags; - - item = name_info->items; - item->type = KDBUS_NAME_INFO_ITEM_NAME; - item->size = KDBUS_ITEM_SIZE(slen); - strcpy(item->str, name); + size = sizeof(struct kdbus_cmd_name_info) + strlen(name) + 1; + cmd = malloc0(size); + if (!cmd) + return -ENOMEM; - r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_QUERY, name_info); - if (r < 0) { - if (errno == ENOBUFS && size != name_info->size) { - size = name_info->size; - continue; - } + cmd ->size = size; + cmd->attach_flags = attach_flags; + strcpy(cmd->name, name); - return -errno; - } + r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_INFO, cmd); + if (r < 0) + return -errno; - break; - } + name_info = (struct kdbus_name_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset); asprintf(&unique, ":1.%llu", (unsigned long long) name_info->id); @@ -756,6 +727,10 @@ static int kdbus_name_query( } } + r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_FREE, &cmd->offset); + if (r < 0) + return -errno; + if (creds) { *creds = c; c = NULL; @@ -784,7 +759,7 @@ _public_ int sd_bus_get_owner( assert_return(!bus_pid_changed(bus), -ECHILD); if (bus->is_kernel) - return kdbus_name_query(bus, name, mask, owner, creds); + return kdbus_name_info(bus, name, mask, owner, creds); return sd_bus_get_owner_dbus(bus, name, mask, owner, creds); } diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 1cab2544ec..b63fe56c41 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -459,7 +459,7 @@ static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) { assert(k); off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer; - ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off); + ioctl(bus->input_fd, KDBUS_CMD_FREE, &off); KDBUS_PART_FOREACH(d, k, items) { diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 920488dae7..56bf88c394 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -129,7 +129,7 @@ static void message_free(sd_bus_message *m) { uint64_t off; off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer; - ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off); + ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off); } if (m->bus) diff --git a/src/libsystemd-bus/kdbus.h b/src/libsystemd-bus/kdbus.h index bfd299bd26..3dafeceec2 100644 --- a/src/libsystemd-bus/kdbus.h +++ b/src/libsystemd-bus/kdbus.h @@ -297,6 +297,11 @@ enum { enum { _KDBUS_MAKE_NULL, KDBUS_MAKE_NAME, + KDBUS_MAKE_CRED, /* allow translator services which connect + * to the bus on behalf of somebody else, + * allow specifying the credentials of the + * client to connect on behalf on. Needs + * privileges */ }; struct kdbus_cmd_bus_make { @@ -345,7 +350,7 @@ enum { KDBUS_NAME_IN_QUEUE = 1 << 16, }; -/* We allow (de)regestration of names of other peers */ +/* We allow (de)registration of names of other peers */ struct kdbus_cmd_name { __u64 size; __u64 flags; @@ -354,32 +359,39 @@ struct kdbus_cmd_name { char name[0]; }; +/* KDBUS_CMD_NAME_LIST */ enum { KDBUS_NAME_LIST_UNIQUE_NAMES = 1 << 0, }; -struct kdbus_cmd_names { - __u64 size; +struct kdbus_cmd_name_list { __u64 flags; - struct kdbus_cmd_name names[0]; + __u64 offset; /* returned offset in the caller's buffer */ }; -enum { - _KDBUS_NAME_INFO_ITEM_NULL, - KDBUS_NAME_INFO_ITEM_NAME, /* userspace → kernel */ - KDBUS_NAME_INFO_ITEM_SECLABEL, /* kernel → userspace */ - KDBUS_NAME_INFO_ITEM_AUDIT, /* kernel → userspace */ +struct kdbus_name_list { + __u64 size; + struct kdbus_cmd_name names[0]; }; +/* KDBUS_CMD_NAME_INFO */ struct kdbus_cmd_name_info { - __u64 size; /* overall size of info */ + __u64 size; __u64 flags; /* query flags */ __u64 attach_flags; /* which meta data payload to attach */ - __u64 id; /* either ID, or 0 and _ITEM_NAME follows */ - struct kdbus_creds creds; + __u64 id; /* either ID, or 0 and name follows */ + __u64 offset; /* returned offset in the caller's buffer */ + char name[0]; +}; + +struct kdbus_name_info { + __u64 size; + __u64 id; + __u64 flags; /* connection flags */ struct kdbus_item items[0]; /* list of item records */ }; +/* KDBUS_CMD_MATCH_ADD/REMOVE */ enum { _KDBUS_MATCH_NULL, KDBUS_MATCH_BLOOM, /* Matches a mask blob against KDBUS_MSG_BLOOM */ @@ -399,22 +411,13 @@ struct kdbus_cmd_match { struct kdbus_item items[0]; }; +/* KDBUS_CMD_MONITOR */ struct kdbus_cmd_monitor { __u64 id; /* We allow setting the monitor flag of other peers */ unsigned int enable; /* A boolean to enable/disable monitoring */ __u32 __pad; }; -/* FD states: - * control nodes: unset - * bus owner (via KDBUS_CMD_BUS_MAKE) - * ns owner (via KDBUS_CMD_NS_MAKE) - * - * ep nodes: unset - * connected (via KDBUS_CMD_HELLO) - * starter (via KDBUS_CMD_HELLO with KDBUS_CMD_HELLO_STARTER) - * ep owner (via KDBUS_CMD_EP_MAKE) - */ enum { /* kdbus control node commands: require unset state */ KDBUS_CMD_BUS_MAKE = _IOW(KDBUS_IOC_MAGIC, 0x00, struct kdbus_cmd_bus_make), @@ -427,12 +430,12 @@ enum { /* kdbus ep node commands: require connected state */ KDBUS_CMD_MSG_SEND = _IOW(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg), KDBUS_CMD_MSG_RECV = _IOR(KDBUS_IOC_MAGIC, 0x41, __u64 *), - KDBUS_CMD_MSG_RELEASE = _IOW(KDBUS_IOC_MAGIC, 0x42, __u64 *), + KDBUS_CMD_FREE = _IOW(KDBUS_IOC_MAGIC, 0x42, __u64 *), KDBUS_CMD_NAME_ACQUIRE = _IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name), KDBUS_CMD_NAME_RELEASE = _IOW(KDBUS_IOC_MAGIC, 0x51, struct kdbus_cmd_name), - KDBUS_CMD_NAME_LIST = _IOWR(KDBUS_IOC_MAGIC, 0x52, struct kdbus_cmd_names), - KDBUS_CMD_NAME_QUERY = _IOWR(KDBUS_IOC_MAGIC, 0x53, struct kdbus_cmd_name_info), + KDBUS_CMD_NAME_LIST = _IOWR(KDBUS_IOC_MAGIC, 0x52, struct kdbus_cmd_name_list), + KDBUS_CMD_NAME_INFO = _IOWR(KDBUS_IOC_MAGIC, 0x53, struct kdbus_cmd_name_info), KDBUS_CMD_MATCH_ADD = _IOW(KDBUS_IOC_MAGIC, 0x60, struct kdbus_cmd_match), KDBUS_CMD_MATCH_REMOVE = _IOW(KDBUS_IOC_MAGIC, 0x61, struct kdbus_cmd_match), diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 0d5deb6c6d..37b6fedf03 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -1153,9 +1153,8 @@ _public_ void sd_bus_close(sd_bus *bus) { /* We'll leave the fd open in case this is a kernel bus, since * there might still be memblocks around that reference this - * bus, and they might need to invoke the - * KDBUS_CMD_MSG_RELEASE ioctl on the fd when they are - * freed. */ + * bus, and they might need to invoke the * KDBUS_CMD_FREE + * ioctl on the fd when they are freed. */ } static void bus_enter_closing(sd_bus *bus) { |