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)); 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-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); diff --git a/src/journal/journald-varlink.c b/src/journal/journald-varlink.c index 674f2524eb..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; @@ -168,10 +174,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); } 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; 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. */ 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)) 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));