CVE-2026-89329: Device-mapper-multipath: local denial of service via blocking ipc send operations
A flaw was found in multipathd. A local attacker with access to the multipathd UNIX control socket can exploit this vulnerability by sending valid commands and then ceasing to read replies. This action can cause the multipathd listener thread to block, leading to a Denial of Service (DoS) where legitimate Inter-Process Communication (IPC) operations may hang or time out. This issue does not result in privilege escalation, arbitrary code execution, or impact data confidentiality or integrity.
Other sources
AIONLYREPORT package: device-mapper-multipath-0.9.9-18.el10 ------ Summary: Local Denial of Service via Blocking IPC Send Operations: multipathd can block its IPC listener thread when replying on a blocking client socket to a local client that stops reading responses. Requirements to exploit: Local access to the multipathd UNIX control socket, the ability to issue an allowed IPC command, and the ability to keep the connection open without reading replies until the daemon blocks in send(). Component affected: device-mapper-multipath-0.9.9-18.el10, primarily multipathd/uxlsnr.c (newclient() and clientstatemachine() in CLTSEND), with socket reachability influenced by libmpathutil/uxsock.c Version affected: device-mapper-multipath-0.9.9-18.el10 when multipathd is running and its local IPC socket is reachable to the attacking user Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - 5.5 (MEDIUM) AV:L - exploitation requires local access to the UNIX domain control socket. AC:L - the attack is straightforward: send valid IPC commands and stop reading replies until the socket send buffer is exhausted. PR:N - no prior privileges are required where the control socket is exposed to unprivileged local users. UI:N - no user interaction is required. S:U - the impact remains within the daemon's own security scope. C:N - no confidentiality impact was established. I:N - no integrity impact was established. A:H - legitimate IPC operations can hang or time out once the listener thread blocks. Impact: Moderate. This issue can let a local user deny availability of the multipathd IPC control path in deployments where the daemon's socket is reachable to that user. The available evidence does not show privilege escalation, code execution, or direct confidentiality or integrity impact, and the effect appears limited to the daemon's control interface rather than full system compromise. Under Red Hat's severity guidance, that makes Moderate more appropriate than Important or Critical, while still exceeding Low because the condition appears practically reachable in default-style local IPC exposure. Embargo: no Reason: the issue is a local-only denial of service with no demonstrated confidentiality, integrity, or code-execution impact, and exposure can be reduced through local access controls on the IPC interface. Acknowledgement: Aisle Research Vulnerability Details: Accepted client sockets are left in blocking mode, and the reply path uses blocking send() operations. A local client that sends a valid command and then stops reading can cause the listener thread to block once the kernel send buffer fills. Because the listener loop continues processing clients already in CLTSEND, this can stall subsequent IPC servicing for other clients. c static void newclient(int uxsock) { ... fd = accept(uxsock, &addr, &len); ... c->fd = fd; / blocking accepted socket / c->state = CLTRECV; } c case CLTSEND: if (c->cmdlen == 0) { sizet len = getstrbuflen(&c->reply) + 1; if (send(c->fd, &len, sizeof(len), MSGNOSIGNAL) != sizeof(len)) c->error = -ECONNRESET; c->cmdlen = len; return STMBREAK; } if (c->len < c->cmdlen) { const char buf = getstrbufstr(&c->reply); n = send(c->fd, buf + c->len, c->cmdlen - c->len, MSGNOSIGNAL); ... } The available code also indicates that non-root clients are restricted to list commands, but those still produce replies and appear sufficient to exercise this condition where the socket is accessible: c if (name[0] != '@' && chmod(name, SIRUSR | SIWUSR | SIRGRP | SIWGRP | SIROTH | SIWOTH) == -1) ... The precise time needed to trigger the blockage depends on runtime reply sizes and socket buffering, but the issue appears reachable by repeatedly issuing valid reply-generating commands on a connection that never consumes responses. Steps to reproduce: 1. Start multipathd with its normal IPC listener enabled. 2. Connect to the local control socket from an unprivileged local account where access is permitted. 3. Send a valid command such as list daemon and do not read the reply. 4. Continue sending valid commands on the same connection until the server-side socket buffer is saturated. 5. From another terminal, issue a normal IPC command and observe that it hangs or times out while the listener is blocked in send(). Minimal PoC client: python #!/usr/bin/env python3 import socket, struct sock = socket.socket(socket.AFUNIX, socket.SOCKSTREAM) sock.connect("/run/multipathd.socket") # adjust if needed cmd = b"list daemon\x00" frame = struct.pack("=Q", len(cmd)) + cmd while True: sock.sendall(frame) # intentionally never read replies Mitigation: Restrict access to the multipathd IPC socket to trusted local administrators only, or otherwise prevent untrusted local users from reaching the control interface. Environments that do not expose the listener to unprivileged users substantially reduce the practical attack surface. Proposed Fix: Set accepted client sockets to non-blocking mode and avoid blocking in CLTSEND unless POLLOUT is present. The following minimal patch addresses both points. diff diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c index XXXXXXX..YYYYYYY 100644 — a/multipathd/uxlsnr.c +++ b/multipathd/uxlsnr.c @@ -123,6 +123,13 @@ static void newclient(int uxsock) fd = accept(uxsock, &addr, &len); if (fd == -1) return; + { + int flags = fcntl(fd, FGETFL, 0); + if (flags != -1) + (void)fcntl(fd, FSETFL, flags | ONONBLOCK); + } + c = (struct client )calloc(1, sizeof(c)); if (!c) { close(fd); @@ -551,6 +558,9 @@ static int clientstatemachine(struct client c, struct vectors vecs, case CLTSEND: + if (!(revents & POLLOUT)) + return STMBREAK; + if (getstrbuflen(&c->reply) == 0) defaultreply(c, c->error); @@ -558,13 +568,21 @@ static int clientstatemachine(struct client c, struct vectors vecs, if (send(c>fd, &len, sizeof(len), MSGNOSIGNAL) - != sizeof(len)) c>error = -ECONNRESET; + n = send(c->fd, &len, sizeof(len), + MSGNOSIGNAL | MSGDONTWAIT); + if (n == -1) { + if (!(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) + c->error = -ECONNRESET; + return STMBREAK; + } + if (n != (ssizet)sizeof(len)) + return STMBREAK; c->cmdlen = len; return STMBREAK; } if (c->len < c->cmdlen) { const char buf = getstrbufstr(&c->reply); n = send(c>fd, buf + c->len, c->cmdlen - c->len, MSGNOSIGNAL); + n = send(c->fd, buf + c->len, c->cmdlen - c->len, + MSGNOSIGNAL | MSGDONTWAIT); if (n == -1) { - if (!(errno == EAGAIN || errno == EINTR)) + if (!(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) c->error = -ECONNRESET; } else c->len += n; ------ This report was generated using AI technology. Always review AI-generated content prior to use
— Red Hat
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
In new_client()/client_state_machine IPC path, set accepted client sockets to non-blocking mode to avoid blocking CLT_SEND reply handling (issue observed when blocking accepted socket is left in blocking mode and reply path uses blocking send()).
multipathd IPC listener (multipathd/uxlsnr.c) accepted client sockets mode (fd after accept) = non-blocking - Compensating control
Restrict access to the `multipathd` UNIX control socket (e.g., allow only trusted local administrators/unprivileged exclusion) so untrusted local users cannot reach the IPC interface.
Event History
Frequently Asked Questions
Who is exposed to this denial-of-service condition?
Systems running multipathd are exposed only to local clients that can access its UNIX control socket. Exploitation also requires the client to be able to issue an allowed IPC command and keep its connection open.
What must an attacker do to trigger the issue?
The attacker sends valid commands through the multipathd UNIX control socket, then stops reading the daemon's replies while leaving the connection open. This can cause multipathd to block in send(), preventing the listener thread from servicing legitimate IPC requests.
What is the expected impact?
Legitimate multipathd IPC operations may hang or time out, resulting in a local denial of service. The reported issue does not provide privilege escalation, arbitrary code execution, or confidentiality or integrity impact.