Fedora Account System
Red Hat Associate
Red Hat Customer
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