diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-05-16 06:46:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-16 06:46:29 -0700 |
commit | 3907b2563855f42562643fd26e9dec515d4ef928 (patch) | |
tree | a841f95791531fdbfb1beeede5e3d932afc32d26 /src | |
parent | 93d4a200fbc1dd741a9971853a5efee7e537cc3e (diff) | |
parent | acf493390ac601d90dc4ac188475635a5c327522 (diff) | |
download | systemd-3907b2563855f42562643fd26e9dec515d4ef928.tar.gz |
Merge pull request #27573 from poettering/sd-bus-description
sd-bus: pass bus description (and comm name) to per via socket address binding on AF_UNIX
Diffstat (limited to 'src')
-rw-r--r-- | src/busctl/busctl.c | 2 | ||||
-rw-r--r-- | src/core/dbus.c | 22 | ||||
-rw-r--r-- | src/libsystemd/meson.build | 4 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-control.c | 78 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-internal.h | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-socket.c | 60 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-chat.c | 156 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-peersockaddr.c | 127 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-server.c | 7 |
9 files changed, 346 insertions, 112 deletions
diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 90f20c05a1..820d27da20 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -77,6 +77,8 @@ static int acquire_bus(bool set_monitor, sd_bus **ret) { if (r < 0) return log_error_errno(r, "Failed to allocate bus: %m"); + (void) sd_bus_set_description(bus, "busctl"); + if (set_monitor) { r = sd_bus_set_monitor(bus, true); if (r < 0) diff --git a/src/core/dbus.c b/src/core/dbus.c index c41e1a6c74..7277696196 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -684,7 +684,7 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void return 0; } - nfd = -EBADF; + TAKE_FD(nfd); r = bus_check_peercred(bus); if (r < 0) { @@ -703,7 +703,8 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void r = sd_bus_negotiate_creds(bus, 1, SD_BUS_CREDS_PID|SD_BUS_CREDS_UID| SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS| - SD_BUS_CREDS_SELINUX_CONTEXT); + SD_BUS_CREDS_SELINUX_CONTEXT| + SD_BUS_CREDS_COMM|SD_BUS_CREDS_DESCRIPTION); if (r < 0) { log_warning_errno(r, "Failed to enable credentials for new connection: %m"); return 0; @@ -721,6 +722,23 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void return 0; } + if (DEBUG_LOGGING) { + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL; + const char *comm = NULL, *description = NULL; + pid_t pid = 0; + + r = sd_bus_get_owner_creds(bus, SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_DESCRIPTION, &c); + if (r < 0) + log_warning_errno(r, "Failed to get peer creds, ignoring: %m"); + else { + (void) sd_bus_creds_get_pid(c, &pid); + (void) sd_bus_creds_get_comm(c, &comm); + (void) sd_bus_creds_get_description(c, &description); + } + + log_debug("Accepting direct incoming connection from " PID_FMT " (%s) [%s]", pid, strna(comm), strna(description)); + } + r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL); if (r < 0) { log_warning_errno(r, "Failed to attach new connection bus to event loop: %m"); diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index aa42497080..ee24240cd1 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -211,6 +211,10 @@ tests += [ 'dependencies' : threads, }, { + 'sources' : files('sd-bus/test-bus-peersockaddr.c'), + 'dependencies' : threads, + }, + { 'sources' : files('sd-bus/test-bus-queue-ref-cycle.c'), 'dependencies' : threads, }, diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 864acd73ac..287cde6d41 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -722,9 +722,51 @@ _public_ int sd_bus_get_name_creds( return 0; } +static int parse_sockaddr_string(const char *t, char **ret_comm, char **ret_description) { + _cleanup_free_ char *comm = NULL, *description = NULL; + const char *e, *sl; + + assert(t); + assert(ret_comm); + assert(ret_description); + + e = strstrafter(t, "/bus/"); + if (!e) { + log_debug("Didn't find /bus/ substring in peer socket address, ignoring."); + goto not_found; + } + + sl = strchr(e, '/'); + if (!sl) { + log_debug("Didn't find / substring after /bus/ in peer socket address, ignoring."); + goto not_found; + } + + if (sl - e > 0) { + comm = strndup(e, sl - e); + if (!comm) + return -ENOMEM; + } + + sl++; + if (!isempty(sl)) { + description = strdup(sl); + if (!description) + return -ENOMEM; + } + + *ret_comm = TAKE_PTR(comm); + *ret_description = TAKE_PTR(description); + return 0; + +not_found: + *ret_comm = *ret_description = NULL; + return 0; +} + _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) { _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL; - bool do_label, do_groups; + bool do_label, do_groups, do_sockaddr_peer; pid_t pid = 0; int r; @@ -742,9 +784,12 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r do_label = bus->label && (mask & SD_BUS_CREDS_SELINUX_CONTEXT); do_groups = bus->n_groups != SIZE_MAX && (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS); + do_sockaddr_peer = bus->sockaddr_size_peer >= offsetof(struct sockaddr_un, sun_path) + 1 && + bus->sockaddr_peer.sa.sa_family == AF_UNIX && + bus->sockaddr_peer.un.sun_path[0] == 0; /* Avoid allocating anything if we have no chance of returning useful data */ - if (!bus->ucred_valid && !do_label && !do_groups) + if (!bus->ucred_valid && !do_label && !do_groups && !do_sockaddr_peer) return -ENODATA; c = bus_creds_new(); @@ -786,6 +831,35 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS; } + if (do_sockaddr_peer) { + _cleanup_free_ char *t = NULL; + + assert(bus->sockaddr_size_peer >= offsetof(struct sockaddr_un, sun_path) + 1); + assert(bus->sockaddr_peer.sa.sa_family == AF_UNIX); + assert(bus->sockaddr_peer.un.sun_path[0] == 0); + + /* So this is an abstract namespace socket, good. Now let's find the data we are interested in */ + r = make_cstring(bus->sockaddr_peer.un.sun_path + 1, + bus->sockaddr_size_peer - offsetof(struct sockaddr_un, sun_path) - 1, + MAKE_CSTRING_ALLOW_TRAILING_NUL, + &t); + if (r == -ENOMEM) + return r; + if (r < 0) + log_debug_errno(r, "Can't extract string from peer socket address, ignoring: %m"); + else { + r = parse_sockaddr_string(t, &c->comm, &c->description); + if (r < 0) + return r; + + if (c->comm) + c->mask |= SD_BUS_CREDS_COMM & mask; + + if (c->description) + c->mask |= SD_BUS_CREDS_DESCRIPTION & mask; + } + } + r = bus_creds_add_more(c, mask, pid, 0); if (r < 0 && r != -ESRCH) /* If the process vanished, then don't complain, just return what we got */ return r; diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index 0e44897e0e..1cf6974bff 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -267,6 +267,8 @@ struct sd_bus { char *label; gid_t *groups; size_t n_groups; + union sockaddr_union sockaddr_peer; + socklen_t sockaddr_size_peer; uint64_t creds_mask; diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index ceda20f289..741d54cabd 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -22,6 +22,7 @@ #include "memory-util.h" #include "path-util.h" #include "process-util.h" +#include "random-util.h" #include "signal-util.h" #include "stdio-util.h" #include "string-util.h" @@ -651,6 +652,17 @@ static void bus_get_peercred(sd_bus *b) { b->n_groups = (size_t) r; else if (!IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT)) log_debug_errno(r, "Failed to determine peer's group list: %m"); + + /* Let's query the peers socket address, it might carry information such as the peer's comm or + * description string */ + zero(b->sockaddr_peer); + b->sockaddr_size_peer = 0; + + socklen_t l = sizeof(b->sockaddr_peer) - 1; /* Leave space for a NUL */ + if (getpeername(b->input_fd, &b->sockaddr_peer.sa, &l) < 0) + log_debug_errno(errno, "Failed to get peer's socket address, ignoring: %m"); + else + b->sockaddr_size_peer = l; } static int bus_socket_start_auth_client(sd_bus *b) { @@ -889,6 +901,50 @@ fail: return r; } +static int bind_description(sd_bus *b, int fd, int family) { + _cleanup_free_ char *bind_name = NULL, *comm = NULL; + union sockaddr_union bsa; + const char *d = NULL; + int r; + + assert(b); + assert(fd >= 0); + + /* If this is an AF_UNIX socket, let's set our client's socket address to carry the description + * string for this bus connection. This is useful for debugging things, as the connection name is + * visible in various socket-related tools, and can even be queried by the server side. */ + + if (family != AF_UNIX) + return 0; + + (void) sd_bus_get_description(b, &d); + + /* Generate a recognizable source address in the abstract namespace. We'll include: + * - a random 64bit value (to avoid collisions) + * - our "comm" process name (suppressed if contains "/" to avoid parsing issues) + * - the description string of the bus connection. */ + (void) get_process_comm(0, &comm); + if (comm && strchr(comm, '/')) + comm = mfree(comm); + + if (!d && !comm) /* skip if we don't have either field, rely on kernel autobind instead */ + return 0; + + if (asprintf(&bind_name, "@%" PRIx64 "/bus/%s/%s", random_u64(), strempty(comm), strempty(d)) < 0) + return -ENOMEM; + + strshorten(bind_name, sizeof_field(struct sockaddr_un, sun_path)); + + r = sockaddr_un_set_path(&bsa.un, bind_name); + if (r < 0) + return r; + + if (bind(fd, &bsa.sa, r) < 0) + return -errno; + + return 0; +} + int bus_socket_connect(sd_bus *b) { bool inotify_done = false; int r; @@ -911,6 +967,10 @@ int bus_socket_connect(sd_bus *b) { if (b->input_fd < 0) return -errno; + r = bind_description(b, b->input_fd, b->sockaddr.sa.sa_family); + if (r < 0) + return r; + b->input_fd = fd_move_above_stdio(b->input_fd); b->output_fd = b->input_fd; diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c index 8e66919b46..7abe129186 100644 --- a/src/libsystemd/sd-bus/test-bus-chat.c +++ b/src/libsystemd/sd-bus/test-bus-chat.c @@ -46,31 +46,25 @@ static int object_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_ return 0; } -static int server_init(sd_bus **_bus) { - sd_bus *bus = NULL; +static int server_init(sd_bus **ret_bus) { + _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; + const char *unique, *desc; sd_id128_t id; int r; - const char *unique, *desc; - assert_se(_bus); + assert_se(ret_bus); r = sd_bus_open_user_with_description(&bus, "my bus!"); - if (r < 0) { - log_error_errno(r, "Failed to connect to user bus: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to connect to user bus: %m"); r = sd_bus_get_bus_id(bus, &id); - if (r < 0) { - log_error_errno(r, "Failed to get server ID: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to get server ID: %m"); r = sd_bus_get_unique_name(bus, &unique); - if (r < 0) { - log_error_errno(r, "Failed to get unique name: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to get unique name: %m"); assert_se(sd_bus_get_description(bus, &desc) >= 0); assert_se(streq(desc, "my bus!")); @@ -80,48 +74,35 @@ static int server_init(sd_bus **_bus) { log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h')); r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0); - if (r < 0) { - log_error_errno(r, "Failed to acquire name: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to acquire name: %m"); r = sd_bus_add_fallback(bus, NULL, "/foo/bar", object_callback, NULL); - if (r < 0) { - log_error_errno(r, "Failed to add object: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to add object: %m"); r = sd_bus_match_signal(bus, NULL, NULL, NULL, "foo.bar", "Notify", match_callback, NULL); - if (r < 0) { - log_error_errno(r, "Failed to request match: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to request match: %m"); r = sd_bus_match_signal(bus, NULL, NULL, NULL, "foo.bar", "NotifyTo", match_callback, NULL); - if (r < 0) { - log_error_errno(r, "Failed to request match: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to request match: %m"); r = sd_bus_add_match(bus, NULL, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", match_callback, NULL); - if (r < 0) { - log_error_errno(r, "Failed to add match: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to add match: %m"); bus_match_dump(stdout, &bus->match_callbacks, 0); - *_bus = bus; + *ret_bus = TAKE_PTR(bus); return 0; - -fail: - sd_bus_unref(bus); - return r; } -static int server(sd_bus *bus) { - int r; +static int server(sd_bus *_bus) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = ASSERT_PTR(_bus); bool client1_gone = false, client2_gone = false; + int r; while (!client1_gone || !client2_gone) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; @@ -129,30 +110,26 @@ static int server(sd_bus *bus) { const char *label = NULL; r = sd_bus_process(bus, &m); - if (r < 0) { - log_error_errno(r, "Failed to process requests: %m"); - goto fail; - } - + if (r < 0) + return log_error_errno(r, "Failed to process requests: %m"); if (r == 0) { r = sd_bus_wait(bus, UINT64_MAX); - if (r < 0) { - log_error_errno(r, "Failed to wait: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to wait: %m"); continue; } - if (!m) continue; - sd_bus_creds_get_pid(sd_bus_message_get_creds(m), &pid); - sd_bus_creds_get_selinux_context(sd_bus_message_get_creds(m), &label); + (void) sd_bus_creds_get_pid(sd_bus_message_get_creds(m), &pid); + (void) sd_bus_creds_get_selinux_context(sd_bus_message_get_creds(m), &label); + log_info("Got message! member=%s pid="PID_FMT" label=%s", strna(sd_bus_message_get_member(m)), pid, strna(label)); + /* sd_bus_message_dump(m); */ /* sd_bus_message_rewind(m, true); */ @@ -161,40 +138,31 @@ static int server(sd_bus *bus) { _cleanup_free_ char *lowercase = NULL; r = sd_bus_message_read(m, "s", &hello); - if (r < 0) { - log_error_errno(r, "Failed to get parameter: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to get parameter: %m"); lowercase = strdup(hello); - if (!lowercase) { - r = log_oom(); - goto fail; - } + if (!lowercase) + return log_oom(); ascii_strlower(lowercase); r = sd_bus_reply_method_return(m, "s", lowercase); - if (r < 0) { - log_error_errno(r, "Failed to send reply: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to send reply: %m"); + } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) { r = sd_bus_reply_method_return(m, NULL); - if (r < 0) { - log_error_errno(r, "Failed to send reply: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to send reply: %m"); client1_gone = true; } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) { r = sd_bus_reply_method_return(m, NULL); - if (r < 0) { - log_error_errno(r, "Failed to send reply: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to send reply: %m"); client2_gone = true; } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) { @@ -202,56 +170,40 @@ static int server(sd_bus *bus) { sleep(1); r = sd_bus_reply_method_return(m, NULL); - if (r < 0) { - log_error_errno(r, "Failed to send reply: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to send reply: %m"); } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "FileDescriptor")) { int fd; static const char x = 'X'; r = sd_bus_message_read(m, "h", &fd); - if (r < 0) { - log_error_errno(r, "Failed to get parameter: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to get parameter: %m"); log_info("Received fd=%d", fd); if (write(fd, &x, 1) < 0) { - log_error_errno(errno, "Failed to write to fd: %m"); + r = log_error_errno(errno, "Failed to write to fd: %m"); safe_close(fd); - goto fail; + return r; } r = sd_bus_reply_method_return(m, NULL); - if (r < 0) { - log_error_errno(r, "Failed to send reply: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to send reply: %m"); } else if (sd_bus_message_is_method_call(m, NULL, NULL)) { r = sd_bus_reply_method_error( m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method.")); - if (r < 0) { - log_error_errno(r, "Failed to send reply: %m"); - goto fail; - } + if (r < 0) + return log_error_errno(r, "Failed to send reply: %m"); } } - r = 0; - -fail: - if (bus) { - sd_bus_flush(bus); - sd_bus_unref(bus); - } - - return r; + return 0; } static void* client1(void *p) { diff --git a/src/libsystemd/sd-bus/test-bus-peersockaddr.c b/src/libsystemd/sd-bus/test-bus-peersockaddr.c new file mode 100644 index 0000000000..8bab429624 --- /dev/null +++ b/src/libsystemd/sd-bus/test-bus-peersockaddr.c @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include <pthread.h> +#include <unistd.h> + +#include "sd-bus.h" + +#include "fd-util.h" +#include "process-util.h" +#include "socket-util.h" +#include "tests.h" + +static void *server(void *p) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + _cleanup_close_ int listen_fd = PTR_TO_INT(p), fd = -EBADF; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL; + _cleanup_free_ char *our_comm = NULL; + sd_id128_t id; + int r; + + assert_se(sd_id128_randomize(&id) >= 0); + + fd = accept4(listen_fd, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK); + assert_se(fd >= 0); + + assert_se(sd_bus_new(&bus) >= 0); + assert_se(sd_bus_set_fd(bus, fd, fd) >= 0); + TAKE_FD(fd); + assert_se(sd_bus_set_server(bus, true, id) >= 0); + assert_se(sd_bus_negotiate_creds(bus, 1, SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_DESCRIPTION) >= 0); + + assert_se(sd_bus_start(bus) >= 0); + + assert_se(sd_bus_get_owner_creds(bus, SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_DESCRIPTION, &c) >= 0); + + uid_t u; + assert_se(sd_bus_creds_get_euid(c, &u) >= 0); + assert_se(u == getuid()); + + gid_t g; + assert_se(sd_bus_creds_get_egid(c, &g) >= 0); + assert_se(g == getgid()); + + pid_t pid; + assert_se(sd_bus_creds_get_pid(c, &pid) >= 0); + assert_se(pid == getpid_cached()); + + const char *comm; + assert_se(sd_bus_creds_get_comm(c, &comm) >= 0); + assert_se(get_process_comm(0, &our_comm) >= 0); + assert_se(streq_ptr(comm, our_comm)); + + const char *description; + assert_se(sd_bus_creds_get_description(c, &description) >= 0); + assert_se(streq_ptr(description, "wuffwuff")); + + for (;;) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + + r = sd_bus_process(bus, &m); + assert_se(r >= 0); + + if (r == 0) { + assert_se(sd_bus_wait(bus, UINT64_MAX) >= 0); + continue; + } + + if (sd_bus_message_is_method_call(m, "foo.foo", "Foo") > 0) { + assert_se(sd_bus_reply_method_return(m, "s", "bar") >= 0); + break; + } + } + + return NULL; +} + +static void* client(void *p) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + const char *z; + + assert_se(sd_bus_new(&bus) >= 0); + assert_se(sd_bus_set_description(bus, "wuffwuff") >= 0); + assert_se(sd_bus_set_address(bus, p) >= 0); + assert_se(sd_bus_start(bus) >= 0); + + assert_se(sd_bus_call_method(bus, "foo.foo", "/foo", "foo.foo", "Foo", NULL, &reply, "s", "foo") >= 0); + + assert_se(sd_bus_message_read(reply, "s", &z) >= 0); + assert_se(streq_ptr(z, "bar")); + + return NULL; +} + +TEST(description) { + _cleanup_free_ char *a = NULL; + _cleanup_close_ int fd = -EBADF; + union sockaddr_union sa = { + .un.sun_family = AF_UNIX, + }; + socklen_t salen; + pthread_t s, c; + + fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); + assert_se(fd >= 0); + + assert_se(bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path)) >= 0); /* force auto-bind */ + + assert_se(listen(fd, 1) >= 0); + + salen = sizeof(sa); + assert_se(getsockname(fd, &sa.sa, &salen) >= 0); + assert_se(salen >= offsetof(struct sockaddr_un, sun_path)); + assert_se(sa.un.sun_path[0] == 0); + + assert_se(asprintf(&a, "unix:abstract=%s", sa.un.sun_path + 1) >= 0); + + assert_se(pthread_create(&s, NULL, server, INT_TO_PTR(fd)) == 0); + TAKE_FD(fd); + + assert_se(pthread_create(&c, NULL, client, a) == 0); + + assert_se(pthread_join(s, NULL) == 0); + assert_se(pthread_join(c, NULL) == 0); +} + +DEFINE_TEST_MAIN(LOG_INFO); diff --git a/src/libsystemd/sd-bus/test-bus-server.c b/src/libsystemd/sd-bus/test-bus-server.c index ab4045ee15..5024c1d4f5 100644 --- a/src/libsystemd/sd-bus/test-bus-server.c +++ b/src/libsystemd/sd-bus/test-bus-server.c @@ -22,8 +22,8 @@ struct context { }; static void *server(void *p) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; struct context *c = p; - sd_bus *bus = NULL; sd_id128_t id; bool quit = false; int r; @@ -97,11 +97,6 @@ static void *server(void *p) { r = 0; fail: - if (bus) { - sd_bus_flush(bus); - sd_bus_unref(bus); - } - return INT_TO_PTR(r); } |