Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: gnome-remote-desktop-49.3-1.el10 ------ Summary: Missing Connection Throttling in System-Mode RDP Server: unauthenticated flooding of the system-mode RDP listener can accumulate accepted sockets and asynchronous routing-token peek work until timeout, degrading or denying legitimate RDP access. Requirements to exploit: The `gnome-remote-desktop` system-mode daemon must be running with RDP enabled and its RDP listener reachable from the attacker. No authentication or user interaction is required; the attacker only needs to open many parallel TCP connections and keep them open briefly or send partial handshake data. Component affected: `gnome-remote-desktop` RDP ingress handling in `src/grd-rdp-server.c` and asynchronous routing-token peeking in `src/grd-rdp-routing-token.c`. Version affected: `gnome-remote-desktop-49.3-1.el10`, when run in `--system` mode with RDP enabled and the RDP listener reachable by an attacker. Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: This report is the initial private notification. CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The vulnerable path is reachable over the network through the RDP listener when system mode is exposed. AC:L - The attack is a straightforward connection flood against a pre-auth code path; no special race or unusual precondition beyond service exposure is required. PR:N - The vulnerable behavior occurs before authentication. UI:N - No user interaction is required. S:U - The impact is confined to the `gnome-remote-desktop` service boundary. C:N - No confidentiality impact is demonstrated. I:N - No integrity impact is demonstrated. A:H - Repeated parallel connections can keep accepted sockets and async peek work outstanding until timeout, materially degrading or denying legitimate RDP service. Impact: Important. This aligns with Red Hat's Important rating because it allows unauthenticated remote users to cause denial of service against a network-facing service. It is not Critical because the demonstrated impact is availability loss rather than system compromise, and reachability depends on the system-mode RDP service being enabled and exposed. The listener backlog and two-second peek timeout reduce peak pressure but do not eliminate sustained pre-auth flooding. Embargo: no Reason: The demonstrated impact is limited to service availability in a configuration-dependent deployment, with no shown confidentiality, integrity, or code-execution impact. Immediate operational mitigations are available by disabling system-mode RDP or restricting network reachability. Acknowledgement: Aisle Research Vulnerability Details: In `grd_rdp_server_start()`, `GRD_RUNTIME_MODE_SYSTEM` connects the `incoming` signal to `on_incoming_as_system_headless()`, while non-system modes use `on_incoming()`. The two handlers differ in a way that matters for pre-auth resource control: ```c static gboolean on_incoming_as_system_headless (GSocketService *service, GSocketConnection *connection) { GrdRdpServer *rdp_server = GRD_RDP_SERVER (service); grd_routing_token_peek_async (rdp_server, connection, rdp_server->cancellable, on_routing_token_peeked); return TRUE; } static gboolean on_incoming (GSocketService *service, GSocketConnection *connection) { GrdRdpServer *rdp_server = GRD_RDP_SERVER (service); grd_throttler_handle_connection (rdp_server->throttler, connection); return TRUE; } ``` `grd_routing_token_peek_async()` retains the accepted socket in a per-connection context, schedules the peek asynchronously, and only aborts after `MAX_PEEK_TIME_MS`: ```c void grd_routing_token_peek_async (GrdRdpServer *rdp_server, GSocketConnection *connection, GCancellable *cancellable, GAsyncReadyCallback on_finished_callback) { RoutingTokenContext *routing_token_context; GTask *task; routing_token_context = g_new0 (RoutingTokenContext, 1); routing_token_context->rdp_server = rdp_server; routing_token_context->connection = g_object_ref (connection); routing_token_context->cancellable = g_cancellable_new (); routing_token_context->server_cancellable = g_object_ref (cancellable); task = g_task_new (NULL, NULL, on_finished_callback, NULL); g_task_set_task_data (task, routing_token_context, clear_routing_token_context); g_task_run_in_thread (task, peek_routing_token_in_thread); g_object_unref (task); routing_token_context->abort_peek_source_id = g_timeout_add (MAX_PEEK_TIME_MS, abort_peek_routing_token, routing_token_context); } ``` Because the system-mode path bypasses `grd_throttler_handle_connection()`, attacker-controlled parallel pre-auth connections can accumulate accepted sockets and outstanding peek operations until completion or timeout. The existing `RDP_SERVER_SOCKET_BACKLOG_COUNT = 5` and `MAX_PEEK_TIME_MS = 2000` limit each wave, but they do not prevent repeated flooding from keeping the RDP service under resource pressure and denying legitimate connections. Steps to reproduce: 1. Start the daemon in system mode with RDP enabled. 2. From another host, open many parallel TCP connections to the RDP port (default `3389`) and keep them open briefly, or send partial handshake bytes and stop. 3. While the flood is in progress, observe a high count of connections to port `3389`, repeated routing-token peek warnings or timeouts, and degraded acceptance of legitimate RDP connections. 4. Stop the flood and observe recovery after the timeout window expires. Mitigation: Until a fix is available, disable system-mode RDP where it is not required or restrict the RDP listener to trusted management networks using host or network firewall rules. The existing backlog and peek timeout only reduce per-wave pressure, and `--max-parallel-connections` does not address this path because system-mode ingress bypasses the throttler. Proposed Fix: Route system-mode incoming sockets through the existing throttler, then branch inside `allow_connection_cb()` so system mode still performs routing-token peeking after throttler admission. ```diff diff --git a/src/grd-rdp-server.c b/src/grd-rdp-server.c @@ static gboolean on_incoming_as_system_headless (GSocketService *service, GSocketConnection *connection) { GrdRdpServer *rdp_server = GRD_RDP_SERVER (service); - grd_routing_token_peek_async (rdp_server, connection, rdp_server->cancellable, on_routing_token_peeked); - + grd_throttler_handle_connection (rdp_server->throttler, connection); return TRUE; } @@ static void allow_connection_cb (GrdThrottler *throttler, GSocketConnection *connection, gpointer user_data) { GrdRdpServer *rdp_server = GRD_RDP_SERVER (user_data); + GrdRuntimeMode runtime_mode = + grd_context_get_runtime_mode (rdp_server->context); GrdSessionRdp *session_rdp; + if (runtime_mode == GRD_RUNTIME_MODE_SYSTEM) + { + grd_routing_token_peek_async (rdp_server, + connection, + rdp_server->cancellable, + on_routing_token_peeked); + return; + } + g_debug ("Creating new RDP session"); ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use
Tracker filed for rhel-10.3: https://issues.redhat.com/browse/RHEL-189219