From: ShiroKSH Date: Wed, 12 Aug 2026 19:10:33 +0000 (+0000) Subject: sd-varlink: decrement connection counters on failure X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=db08fdbc33924b2ca22900e2c126fca737329808;p=thirdparty%2Fsystemd.git sd-varlink: decrement connection counters on failure Previously, sd_varlink_server_add_connection_pair() did not decrement the connection counters when json_stream_attach_fds() failed. Set the ucred before calling json_stream_attach_fds() so that sd_varlink_close() also decrements the counters when it fails. --- diff --git a/src/libsystemd/sd-varlink/sd-varlink.c b/src/libsystemd/sd-varlink/sd-varlink.c index cb8864635ea..f7de8b8f436 100644 --- a/src/libsystemd/sd-varlink/sd-varlink.c +++ b/src/libsystemd/sd-varlink/sd-varlink.c @@ -3438,9 +3438,14 @@ _public_ int sd_varlink_server_add_connection_pair( v->server = sd_varlink_server_ref(server); sd_varlink_ref(v); + if (ucred_acquired) + json_stream_set_peer_ucred(&v->stream, &ucred); + r = json_stream_attach_fds(&v->stream, input_fd, output_fd); - if (r < 0) + if (r < 0) { + sd_varlink_close(v); return r; + } if (server->flags & SD_VARLINK_SERVER_INHERIT_USERDATA) v->userdata = server->userdata; @@ -3450,9 +3455,6 @@ _public_ int sd_varlink_server_add_connection_pair( if (FLAGS_SET(server->flags, SD_VARLINK_SERVER_UPGRADABLE)) json_stream_set_flags(&v->stream, JSON_STREAM_BOUNDED_READS, true); - if (ucred_acquired) - json_stream_set_peer_ucred(&v->stream, &ucred); - _cleanup_free_ char *desc = NULL; if (asprintf(&desc, "%s-%i-%i", varlink_server_description(server), input_fd, output_fd) >= 0) json_stream_set_description(&v->stream, desc); diff --git a/src/libsystemd/sd-varlink/test-varlink.c b/src/libsystemd/sd-varlink/test-varlink.c index 73b63c45d72..41d5f53deb2 100644 --- a/src/libsystemd/sd-varlink/test-varlink.c +++ b/src/libsystemd/sd-varlink/test-varlink.c @@ -1504,4 +1504,33 @@ TEST(ctrunc) { ASSERT_OK(r); } +TEST(add_connection_failure_cleanup) { + _cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL; + _cleanup_close_pair_ int fds[2] = EBADF_PAIR; + const struct ucred ucred = { + .pid = getpid(), + .uid = getuid(), + .gid = getgid(), + }; + + ASSERT_OK(sd_varlink_server_new(&s, SD_VARLINK_SERVER_ACCOUNT_UID)); + ASSERT_OK(sd_varlink_server_set_connections_per_uid_max(s, 1)); + ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds)); + + int bad_fd = ASSERT_OK(memfd_new("closed-fd")); + ASSERT_OK_ERRNO(close(bad_fd)); + + ASSERT_ERROR(sd_varlink_server_add_connection_pair(s, fds[0], bad_fd, &ucred, /* ret= */ NULL), EBADF); + ASSERT_EQ(sd_varlink_server_current_connections(s), 0U); + + sd_varlink *v = NULL; + ASSERT_OK(sd_varlink_server_add_connection(s, fds[0], &v)); + TAKE_FD(fds[0]); + ASSERT_NOT_NULL(v); + ASSERT_EQ(sd_varlink_server_current_connections(s), 1U); + + ASSERT_OK_POSITIVE(sd_varlink_close(v)); + ASSERT_EQ(sd_varlink_server_current_connections(s), 0U); +} + DEFINE_TEST_MAIN(LOG_DEBUG);