From a7ba64356aa641014921bb899c64c28c0d67c5c3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Aug 2026 01:15:21 +0900 Subject: [PATCH 1/8] journal: update comments The Manager object was renamed from Server. Maybe we forget to update these comments at that time. --- src/journal/journald-manager.c | 4 ++-- src/journal/journald-stream.c | 6 +++--- src/journal/journald-varlink.c | 5 +++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/journal/journald-manager.c b/src/journal/journald-manager.c index be3532f1ed..a0fc0d8c9b 100644 --- a/src/journal/journald-manager.c +++ b/src/journal/journald-manager.c @@ -1873,7 +1873,7 @@ static int manager_schedule_sync(Manager *m, int priority) { } if (!m->event || sd_event_get_state(m->event) == SD_EVENT_FINISHED) { - /* Shutting down the server? Let's sync immediately. */ + /* Shutting down the manager? Let's sync immediately. */ manager_sync(m, /* wait= */ false); return 0; } @@ -2133,7 +2133,7 @@ int manager_unlink_seqnum_file(Manager *m, const char *fname) { static bool manager_is_idle(Manager *m) { assert(m); - /* The server for the main namespace is never idle */ + /* The manager for the main namespace is never idle */ if (!m->namespace) return false; diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index ee903755cf..8a93b2ef79 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -687,7 +687,7 @@ static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revent if (revents != EPOLLIN) return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Got invalid event from epoll for stdout server fd: %" PRIx32, + "Got invalid event from epoll for stdout fd: %" PRIx32, revents); fd = accept4(m->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); @@ -926,11 +926,11 @@ int manager_open_stdout_socket(Manager *m, const char *stdout_socket) { r = sd_event_add_io(m->event, &m->stdout_event_source, m->stdout_fd, EPOLLIN, stdout_stream_new, m); if (r < 0) - return log_error_errno(r, "Failed to add stdout server fd to event source: %m"); + return log_error_errno(r, "Failed to add stdout fd to event source: %m"); r = sd_event_source_set_priority(m->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+5); if (r < 0) - return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m"); + return log_error_errno(r, "Failed to adjust priority of stdout event source: %m"); return 0; } diff --git a/src/journal/journald-varlink.c b/src/journal/journald-varlink.c index 674f2524eb..fb0d463c4f 100644 --- a/src/journal/journald-varlink.c +++ b/src/journal/journald-varlink.c @@ -168,10 +168,11 @@ static void vl_disconnect(sd_varlink_server *server, sd_varlink *link, void *use void *u = sd_varlink_get_userdata(link); if (u != m) { - /* If this is a Varlink connection that does not have the Server object as userdata, then it has a SyncReq object instead. Let's finish it. */ + /* If this is a Varlink connection that does not have the Manager object as userdata, then + * it has a SyncReq object instead. Let's finish it. */ SyncReq *req = u; - sd_varlink_set_userdata(link, m); /* reinstall server object */ + sd_varlink_set_userdata(link, m); /* reinstall the manager object */ sync_req_free(req); } From 0566d7aa3535bb14cd7c869c31b06027668bf647 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Aug 2026 01:16:25 +0900 Subject: [PATCH 2/8] journal: coding style fix --- src/journal/journald-sync.c | 2 +- src/journal/journald-sync.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/journal/journald-sync.c b/src/journal/journald-sync.c index 4722cfa9a3..45bb84fd83 100644 --- a/src/journal/journald-sync.c +++ b/src/journal/journald-sync.c @@ -17,7 +17,7 @@ #include "socket-netlink.h" #include "time-util.h" -StreamSyncReq *stream_sync_req_free(StreamSyncReq *ssr) { +StreamSyncReq* stream_sync_req_free(StreamSyncReq *ssr) { if (!ssr) return NULL; diff --git a/src/journal/journald-sync.h b/src/journal/journald-sync.h index e1172611e9..9ce77f9d1c 100644 --- a/src/journal/journald-sync.h +++ b/src/journal/journald-sync.h @@ -37,7 +37,7 @@ typedef struct SyncReq { unsigned boottime_prioq_idx; } SyncReq; -StreamSyncReq *stream_sync_req_free(StreamSyncReq *ssr); +StreamSyncReq* stream_sync_req_free(StreamSyncReq *ssr); DEFINE_TRIVIAL_CLEANUP_FUNC(StreamSyncReq*, stream_sync_req_free); void stream_sync_req_advance_revalidate(StreamSyncReq *ssr, size_t p); From c2806a8c1d6b775fb73516ef62b9f66e7cc00310 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Aug 2026 01:22:52 +0900 Subject: [PATCH 3/8] journal: do not accept multiple requests to sync journal per varlink connection Otherwise, previously allocated SyncReq object will be leaked, and the latest SyncReq object will be freed multiple times. --- src/journal/journald-varlink.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/journal/journald-varlink.c b/src/journal/journald-varlink.c index fb0d463c4f..cbadbca777 100644 --- a/src/journal/journald-varlink.c +++ b/src/journal/journald-varlink.c @@ -40,11 +40,17 @@ static int vl_method_synchronize(sd_varlink *link, sd_json_variant *parameters, {} }; - Manager *m = ASSERT_PTR(userdata); int r; assert(link); + /* Here, userdata may not be a pointer to the Manager object. Obtain the manager from the server. */ + Manager *m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(link))); + + /* The varlink connection already requested to sync journals. Refusing. */ + if (sd_varlink_get_userdata(link) != m) + return -EBUSY; + r = sd_varlink_dispatch(link, parameters, dispatch_table, &offline); if (r != 0) return r; From 54253d2a9c9020a9a8b946a18997af6acb149187 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Aug 2026 01:28:12 +0900 Subject: [PATCH 4/8] journalctl: do not accept multiple requests to get journal entries with following mode Otherwise, the previously attached FollowState object will be leaked, and the latest object will be freed multiple times. --- src/journal/journalctl-varlink-server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/journal/journalctl-varlink-server.c b/src/journal/journalctl-varlink-server.c index 8c662211a9..e1e2705a69 100644 --- a/src/journal/journalctl-varlink-server.c +++ b/src/journal/journalctl-varlink-server.c @@ -142,6 +142,10 @@ static int follow_state_setup(sd_varlink *link, sd_journal *_j /* donated! */) { assert(link); assert(j); + /* The varlink connection already requested the follow mode. Refusing. */ + if (sd_varlink_get_userdata(link)) + return -EBUSY; + sd_varlink_server *server = ASSERT_PTR(sd_varlink_get_server(link)); sd_event *event = ASSERT_PTR(sd_varlink_server_get_event(server)); From 112e4fe00aaa7c07e030a67af88ac81658e1799f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Aug 2026 01:37:13 +0900 Subject: [PATCH 5/8] mute-console: refuse multiple requests per connection Otherwise, that triggers memory leak and multiple free on the same object. --- src/mute-console/mute-console.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mute-console/mute-console.c b/src/mute-console/mute-console.c index 7ea1fcf17b..0a5ef85ec2 100644 --- a/src/mute-console/mute-console.c +++ b/src/mute-console/mute-console.c @@ -236,6 +236,10 @@ static int vl_method_mute( assert(link); assert(FLAGS_SET(flags, SD_VARLINK_METHOD_MORE)); + /* Refuse multiple requests per connection. */ + if (sd_varlink_get_userdata(link)) + return -EBUSY; + _cleanup_free_ Context *nc = new(Context, 1); if (!nc) return -ENOMEM; From b52f89e53b7d92254603202d4585febd5fd3d7ea Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Aug 2026 01:42:41 +0900 Subject: [PATCH 6/8] repart: refuse multiple requests with subscribe mode Otherwise, that triggers memory leak and double free. --- src/repart/repart-list-candidate-devices.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/repart/repart-list-candidate-devices.c b/src/repart/repart-list-candidate-devices.c index f4f5a8aa2c..550064cb64 100644 --- a/src/repart/repart-list-candidate-devices.c +++ b/src/repart/repart-list-candidate-devices.c @@ -169,6 +169,10 @@ int vl_method_list_candidate_devices( _cleanup_(list_candidate_devices_context_freep) ListCandidateDevicesContext *c = NULL; if (p.subscribe) { + /* Refuse multiple requests per connection. */ + if (sd_varlink_get_userdata(link)) + return -EBUSY; + /* Start the monitor *before* the initial enumeration so we don't lose events that fire * during the enumeration window. Duplicate add events for the same device are * legitimate and documented; clients upsert by identifier. */ From 515121f7b3939516cf463e32c192de6050787676 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Aug 2026 01:50:59 +0900 Subject: [PATCH 7/8] resolve: refuse multiple requests Otherwise, that triggers memory leak and double free. --- src/resolve/resolved-dns-browse-services.c | 41 +++++++++++++--------- src/resolve/resolved-varlink.c | 12 +++++++ 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/resolve/resolved-dns-browse-services.c b/src/resolve/resolved-dns-browse-services.c index 445ab974f1..c25180d99b 100644 --- a/src/resolve/resolved-dns-browse-services.c +++ b/src/resolve/resolved-dns-browse-services.c @@ -726,27 +726,30 @@ static int mdns_next_query_schedule(sd_event_source *s, uint64_t usec, void *use assert(userdata); assert_se(sb = dns_service_browser_ref(userdata)); - /* Enable the answer from the cache for the very first query */ - if (sb->delay == 0) - SET_FLAG(sb->flags, SD_RESOLVED_NO_CACHE, false); + /* If the varlink connection has a userdata, then that means the previous query has not been finished. */ + if (!sd_varlink_get_userdata(sb->link)) { - /* Set the flag indicating that the query is continuous. - * RFC 6762 Section 5.2 outlines timing requirements for continuous queries. - */ - sb->flags |= SD_RESOLVED_QUERY_CONTINUOUS; + /* Enable the answer from the cache for the very first query */ + if (sb->delay == 0) + SET_FLAG(sb->flags, SD_RESOLVED_NO_CACHE, false); - r = dns_query_new(sb->manager, &q, sb->question_utf8, sb->question_idna, NULL, sb->ifindex, sb->flags); - if (r < 0) - return log_error_errno(r, "Failed to create new DNS query: %m"); + /* Set the flag indicating that the query is continuous. + * RFC 6762 Section 5.2 outlines timing requirements for continuous queries. */ + sb->flags |= SD_RESOLVED_QUERY_CONTINUOUS; - q->complete = mdns_browse_service_query_complete; - q->service_browser_request = dns_service_browser_ref(sb); - q->varlink_request = sd_varlink_ref(sb->link); - sd_varlink_set_userdata(sb->link, q); + r = dns_query_new(sb->manager, &q, sb->question_utf8, sb->question_idna, NULL, sb->ifindex, sb->flags); + if (r < 0) + return log_error_errno(r, "Failed to create new DNS query: %m"); - r = dns_query_go(q); - if (r < 0) - return log_error_errno(r, "Failed to send DNS query: %m"); + q->complete = mdns_browse_service_query_complete; + q->service_browser_request = dns_service_browser_ref(sb); + q->varlink_request = sd_varlink_ref(sb->link); + sd_varlink_set_userdata(sb->link, q); + + r = dns_query_go(q); + if (r < 0) + return log_error_errno(r, "Failed to send DNS query: %m"); + } /* Calculate the next query delay */ sb->delay = mdns_calculate_next_query_delay(sb->delay); @@ -811,6 +814,10 @@ int dns_subscribe_browse_service( assert(m); assert(link); + /* Refuse multiple requests. */ + if (hashmap_contains(m->dns_service_browsers, link)) + return -EBUSY; + if (ifindex < 0) return sd_varlink_error_invalid_parameter_name(link, "ifindex"); diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c index 2617b62775..1ef4e2591d 100644 --- a/src/resolve/resolved-varlink.c +++ b/src/resolve/resolved-varlink.c @@ -363,6 +363,9 @@ static int vl_method_resolve_hostname(sd_varlink *link, sd_json_variant *paramet assert(link); + if (sd_varlink_get_userdata(link)) + return -EBUSY; + m = sd_varlink_server_get_userdata(sd_varlink_get_server(link)); assert(m); @@ -490,6 +493,9 @@ static int vl_method_resolve_address(sd_varlink *link, sd_json_variant *paramete assert(link); + if (sd_varlink_get_userdata(link)) + return -EBUSY; + m = sd_varlink_server_get_userdata(sd_varlink_get_server(link)); assert(m); @@ -973,6 +979,9 @@ static int vl_method_resolve_service(sd_varlink* link, sd_json_variant* paramete assert(link); + if (sd_varlink_get_userdata(link)) + return -EBUSY; + m = sd_varlink_server_get_userdata(sd_varlink_get_server(link)); assert(m); @@ -1124,6 +1133,9 @@ static int vl_method_resolve_record(sd_varlink *link, sd_json_variant *parameter assert(link); + if (sd_varlink_get_userdata(link)) + return -EBUSY; + m = ASSERT_PTR(sd_varlink_server_get_userdata(sd_varlink_get_server(link))); if (FLAGS_SET(flags, SD_VARLINK_METHOD_ONEWAY)) From 4430adbd768fd8a3812836bc5dbbbdb1825a5911 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Aug 2026 01:56:38 +0900 Subject: [PATCH 8/8] sysinstall: refuse multiple requests Otherwise, that triggers memory leak and double free. --- src/sysinstall/sysinstall.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sysinstall/sysinstall.c b/src/sysinstall/sysinstall.c index bfeb0f475c..d981be03d0 100644 --- a/src/sysinstall/sysinstall.c +++ b/src/sysinstall/sysinstall.c @@ -1822,6 +1822,10 @@ static int vl_method_list_candidate_devices( assert(link); + /* Refuse multiple requests */ + if (sd_varlink_get_userdata(link)) + return -EBUSY; + sd_varlink_server *varlink_server = sd_varlink_get_server(link); sd_event *event = sd_varlink_server_get_event(varlink_server); Hashmap **polkit_registry = ASSERT_PTR(sd_varlink_server_get_userdata(varlink_server));