CVE-2026-89700 Overview
CVE-2026-89700 is an out-of-bounds read vulnerability in the Linux kernel NFS server (nfsd) netlink interface. The flaw resides in the nfsd_sock_nl_policy definition, where NFSD_A_SOCK_ADDR is declared as a bare NLA_BINARY attribute with no minimum length. A local caller holding CAP_NET_ADMIN can submit a 16-byte NFSD_A_SOCK_ADDR with sa_family set to AF_INET6, triggering a 12-byte out-of-bounds read across rpc_cmp_addr_port, svc_find_listener, and kernel_bind. The maintainers resolved the issue by adding an nfsd_nl_validate_listeners() helper that validates sockaddr length per address family before any state changes occur.
Critical Impact
A privileged local caller with CAP_NET_ADMIN can trigger a 12-byte kernel out-of-bounds read through the NFSD netlink listener_set path, potentially leaking adjacent kernel memory.
Affected Products
- Linux kernel versions containing the nfsd netlink listener_set interface prior to the referenced stable commits
- Linux distributions shipping vulnerable upstream kernel builds with NFSD enabled
- Systems exposing the NFSD netlink family to processes with CAP_NET_ADMIN
Discovery Timeline
- 2026-09-11 - CVE-2026-89700 published to NVD
- 2026-09-11 - Last updated in NVD database
Technical Details for CVE-2026-89700
Vulnerability Analysis
The vulnerability affects nfsd_nl_listener_set_doit(), the netlink handler that configures NFS server listeners. The netlink policy nfsd_sock_nl_policy declares the NFSD_A_SOCK_ADDR attribute as NLA_BINARY without enforcing a minimum length. As a result, the kernel accepts sockaddr payloads shorter than the structure required for the declared address family.
When a caller submits a 16-byte payload with sa_family = AF_INET6, downstream consumers treat the buffer as a full struct sockaddr_in6 (28 bytes). The functions rpc_cmp_addr_port, svc_find_listener, and kernel_bind then read 12 bytes beyond the allocated attribute, producing an out-of-bounds read of adjacent kernel memory.
A secondary issue compounded the flaw. nfsd_nl_listener_set_doit() parsed and validated each listener entry inline across two loops interleaved with mutations to the running listener configuration. The open-coded nla_len < sizeof(struct sockaddr) check was too short for AF_INET6, and malformed entries were handled inconsistently depending on which loop detected them.
Root Cause
The root cause is missing per-family length validation on a netlink binary attribute. The NLA_BINARY policy entry does not encode the minimum size required for the largest supported sockaddr variant, and the manual length check used sizeof(struct sockaddr) rather than the family-specific sizeof(struct sockaddr_in6). This is an input validation defect that maps to out-of-bounds read behavior.
Attack Vector
Exploitation requires a local process with CAP_NET_ADMIN in the initial user namespace to send a crafted netlink message to the NFSD generic netlink family. The malformed message contains a truncated NFSD_A_SOCK_ADDR attribute with sa_family set to AF_INET6. Because validation was interleaved with state mutation, a malformed entry could also leave partial listener state behind depending on where the failure was detected. The upstream fix introduces nfsd_nl_validate_listeners(), which walks the entire list once, confirms each entry parses, carries both an address and a transport name, and meets the correct per-family length (sizeof(struct sockaddr_in) for AF_INET, sizeof(struct sockaddr_in6) for AF_INET6, -EAFNOSUPPORT otherwise). Validation runs before acquiring nfsd_mutex or creating the serv, so a malformed request fails cleanly with no side effects.
No public proof-of-concept exploit code is available. See the kernel commit implementing the fix for the reference implementation.
Detection Methods for CVE-2026-89700
Indicators of Compromise
- Unexpected netlink messages targeting the NFSD generic netlink family from non-administrative service accounts
- Kernel log entries referencing nfsd_nl_listener_set_doit, svc_find_listener, or kernel_bind errors following listener reconfiguration attempts
- Inconsistent NFSD listener state after a failed listener_set operation
Detection Strategies
- Audit processes granted CAP_NET_ADMIN and correlate their use of netlink sockets against expected operational baselines
- Enable kernel auditing (auditd) for capset and sendmsg operations tied to the NFSD netlink family
- Monitor for KASAN or slab warnings referencing out-of-bounds reads in nfsd code paths on kernels with debug builds
Monitoring Recommendations
- Track kernel version inventory to identify hosts still running builds that predate the fix commits
- Alert on unexpected changes to NFSD listener configuration in production environments
- Forward kernel ring buffer messages to a central log store for retention and query, and correlate with process ancestry
How to Mitigate CVE-2026-89700
Immediate Actions Required
- Apply the upstream Linux kernel patches referenced in the stable git tree and reboot affected systems
- Restrict CAP_NET_ADMIN to only the service accounts and containers that operationally require it
- Where NFSD is not required, unload the nfsd module and disable the service
Patch Information
The fix is available in the mainline Linux kernel through three stable commits: 22d0e4752ca8, 2aca70c18c5f, and bdcc85c2b05a. The patch introduces nfsd_nl_validate_listeners(), which performs a single validation pass enforcing per-family sockaddr length requirements before any listener state changes. Distribution maintainers should backport these commits to supported long-term support kernel branches.
Workarounds
- Remove CAP_NET_ADMIN from unprivileged containers and workloads that do not require network administration
- Disable the NFSD service on hosts that do not export NFS shares using systemctl disable --now nfs-server
- Use seccomp or Landlock policies to block netlink socket creation for workloads that should never issue netlink configuration commands
# Verify running kernel and check for the fix commits
uname -r
# Disable and stop the NFS server where not required
sudo systemctl disable --now nfs-server
# Remove CAP_NET_ADMIN from a systemd service unit
# Add the following under [Service]:
# CapabilityBoundingSet=~CAP_NET_ADMIN
# AmbientCapabilities=
sudo systemctl daemon-reload
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.