Bug 2469511 (CVE-2026-89098)

Summary: CVE-2026-89098 nfs-utils: nfs-utils: Denial of Service via assertion failure in fsidd
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security <prodsec-ir-bot>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: akhatavk, aos-team-art-private, asdas, dpaolell, jdelft, jupierce, lgarciaa, mbiarnes, ppalepu, ppostler, prdhamdh, rhel-process-autobot, security-response-team, sghai, sidsharm, suppawar, vlaad, watson-tool-maintainers
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in nfs-utils. The fsidd daemon improperly handles input received over its local domain socket by relying on program assertions to verify command arguments. A local user can exploit this vulnerability by sending a malformed request lacking the required arguments to trigger an assertion failure. This causes the daemon to crash, resulting in a Denial of Service (DoS) for filesystem identifier lookup services until restarted.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 2554300    
Bug Blocks:    

Description OSIDB Bzimport 2026-05-11 20:31:37 UTC
AI_ONLY_REPORT
package: nfs-utils-2.8.3-5.el10_2
------
Summary: Local DoS in fsidd via Reachable assert() on Empty Command  
Arguments: a local unprivileged user can terminate `fsidd` by sending a  
malformed command containing only a valid command prefix and trailing  
space, causing a denial of service for reexport FSID lookups until the  
daemon is restarted.
Requirements to exploit: Local access to a system where `fsidd` is running  
for reexport functionality, with the ability to connect to its abstract  
UNIX domain socket and send a crafted request.
Component affected: `nfs-utils`; `support/reexport/fsidd.c`; `client_cb()`
Version affected: `nfs-utils-2.8.3-5.el10_2`, when `fsidd` is present and  
in use for reexport workflows
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 host and access to the  
`fsidd` UNIX socket.
AC:L - A single malformed request is sufficient to reach the failing  
assertion.
PR:N - No protocol-level authentication is required before the request  
is parsed.
UI:N - No user interaction is needed once local access is available.
S:U - The impact is limited to the vulnerable service itself.
C:N - No confidentiality impact was established.
I:N - No integrity impact was established.
A:H - Successful exploitation aborts `fsidd`, disrupting FSID lookup  
handling for reexport use until restart.
Impact: Moderate. This issue enables a reliable local denial of service  
against `fsidd`, but the impact is limited to availability and depends on a  
deployment that actually uses `fsidd` for reexport handling. Under Red  
Hat's severity guidance, this is more appropriately Moderate than Important  
because it is not a remote flaw, does not expose confidentiality or  
integrity, and affects a configuration-dependent service path rather than a  
broadly reachable default remote attack surface.
Embargo: no
Reason: This is a local, configuration-dependent denial of service with  
straightforward mitigation and no demonstrated confidentiality, integrity,  
or privilege-escalation impact.
Acknowledgement: Aisle Research
Vulnerability Details: In `client_cb()`, `fsidd` parses several commands  
received over its local socket and relies on `assert()` to enforce that an  
argument is present after the command prefix. The following exact checks  
are reachable from untrusted input:
```c
if (strncmp(buf, "get_fsidnum ", strlen("get_fsidnum ")) == 0) {
char *req_path = buf + strlen("get_fsidnum ");
...
assert(req_path < buf + n );
}
...
} else if (strncmp(buf, "get_or_create_fsidnum ",  
strlen("get_or_create_fsidnum ")) == 0) {
char *req_path = buf + strlen("get_or_create_fsidnum ");
...
assert(req_path < buf + n );
}
...
} else if (strncmp(buf, "get_path ", strlen("get_path ")) == 0) {
char *req_fsidnum = buf + strlen("get_path ");
...
assert(req_fsidnum < buf + n );
}
```
If a request is exactly the command prefix plus a trailing space, such as  
`get_fsidnum `, then the parsed argument pointer is equal to `buf + n` and  
the assertion fails. In an assertion-enabled build, this causes `fsidd` to  
abort.
The default socket name is defined as an abstract UNIX socket:
```c
#define FSID_SOCKET_NAME "@/run/fsid.sock"
```
Based on the available code and report evidence, `fsidd` processes requests  
on this socket without checking peer credentials first, so local socket  
access is sufficient to reach the vulnerable path. The operational effect  
is a local denial of service against `fsidd`, which can interrupt reexport  
FSID lookup handling until the service is restarted.
Steps to reproduce:
1. Use a system where `fsidd` is running for reexport handling.
2. Verify that the service is active.
```bash
systemctl status fsidd
```
3. Send a malformed command containing a valid command name, trailing  
space, and no argument to the abstract UNIX seqpacket socket.
```bash
python3 - <<'PY'
import socket
s = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
s.connect("\0/run/fsid.sock")
s.sendall(b"get_fsidnum ")
PY
```
4. Observe that `fsidd` terminates with an assertion failure or `SIGABRT`,  
for example in the service journal.
```bash
journalctl -u fsidd -n 20 --no-pager
```
5. Confirm that reexport FSID lookup operations fail until `fsidd` is  
restarted.
Mitigation: Where reexport support is not required, disable the affected  
`fsidd` usage path. Otherwise, restrict untrusted local access to the host  
and apply input validation so malformed requests are rejected instead of  
reaching `assert()`. A service restart policy may reduce outage duration,  
but it does not prevent the crash condition.
Proposed Fix: Replace the reachable assertions with explicit  
malformed-input handling and return an error to the client.
```diff
diff --git a/support/reexport/fsidd.c b/support/reexport/fsidd.c
— a/support/reexport/fsidd.c
+++ b/support/reexport/fsidd.c
@@ -48,7 +48,12 @@ static void client_cb(evutil_socket_t cl, short ev, void  
*d)
char *answer = NULL;
bool found;
-		assert(req_path < buf + n );
+		if (req_path >= buf + n) {
+			char answer[] = "- Command failed: Bad input";
+			(void)send(cl, answer, strlen(answer), 0);
+			return;
+		}
@@ -70,7 +75,12 @@ static void client_cb(evutil_socket_t cl, short ev, void  
*d)
char *answer = NULL;
bool found;
-		assert(req_path < buf + n );
+		if (req_path >= buf + n) {
+			char answer[] = "- Command failed: Bad input";
+			(void)send(cl, answer, strlen(answer), 0);
+			return;
+		}
@@ -94,7 +104,12 @@ static void client_cb(evutil_socket_t cl, short ev,  
void *d)
uint32_t fsidnum;
bool found;
-		assert(req_fsidnum < buf + n );
+		if (req_fsidnum >= buf + n) {
+			char answer[] = "- Command failed: Bad input";
+			(void)send(cl, answer, strlen(answer), 0);
+			return;
+		}
```
------
This report was generated using AI technology. Always review AI-generated  
content prior to use