Network File System Vulnerability In The Linux Kernel
Vulnerability Summary
| Field | Value |
|---|---|
| CVE ID | CVE-2026-31402 |
| CVSS Score | Not disclosed (record awaiting NVD analysis) |
| CVSS Vector | Not disclosed (record awaiting NVD analysis) |
| Vulnerability Type | Heap (slab) out-of-bounds write |
| Affected Software | Linux kernel, nfsd subsystem |
| Affected Versions | Not disclosed |
| Patch Status | Patched |
| PoC Publicly Available | Not disclosed |
Context
CVE-2026-31402
is a heap overflow in the Linux kernel’s NFS server (nfsd), specifically in
the NFSv4.0
replay cache. The NVD record describes it as remotely exploitable by an unauthenticated
attacker. That combination, a memory corruption bug reachable without credentials over
the network, puts this in a category that warrants immediate attention from anyone
running an NFS server exposed to untrusted clients.
The NVD record was published on 2026-04-03 and last updated on 2026-04-07. As of this writing, NVD has not completed its enrichment analysis, so no CVSS score or vector has been assigned. The absence of a score doesn’t reduce the practical severity here; the primitive being offered to an attacker is an out-of-bounds write of up to 944 bytes into adjacent heap memory.
Technical Detail
The NFSv4.0 protocol requires that servers maintain a
replay cache: a record of recent operation responses that can be
retransmitted if the client resends a request it believes was lost. Each
NFSv4.0
state owner (a
stateowner
structure in nfsd) holds a small inline buffer,
rp_ibuf[NFSD4_REPLAY_ISIZE], that stores the encoded response for replay.
According to the NVD description,
NFSD4_REPLAY_ISIZE
is 112 bytes.
That size was chosen based on the encoded size of OPEN
operation responses. The problem is that LOCK operation responses are
structurally different. When a LOCK request is denied because it conflicts
with an existing lock, the denial response includes the
conflicting LOCK
owner
as a variable-length opaque field. The NVD record states that this field can be up to
1024 bytes, governed by the constant
NFS4_OPAQUE_LIMIT.
The vulnerability manifests inside
nfsd4_encode_operation(). When encoding a LOCK
denial, the function calls read_bytes_from_xdr_buf() to copy the full
encoded response into rp_ibuf. There is no bounds check against
NFSD4_REPLAY_ISIZE
before this copy. If the conflicting
LOCK
owner is large, the copy writes past the end of the 112-byte buffer. The NVD record
states that this can overflow by up to 944 bytes (1024 minus the 80 bytes already
consumed by other LOCK denial fields), corrupting adjacent heap memory
allocated to neighboring slab objects.
The fix, as described in the NVD record, does not resize
NFSD4_REPLAY_ISIZE. Increasing it to accommodate a full
NFS4_OPAQUE_LIMIT-sized owner would inflate every
stateowner
allocation, even though most LOCK
owners are short. Instead, the fix adds a length check before the copy: if the encoded
response exceeds NFSD4_REPLAY_ISIZE, the function sets
rp_buflen
to 0, skipping the payload cache entirely for that response. The client’s reply status
is still recorded in the cache, so the protocol contract is maintained. The client
already received the correct full response on the original request; only the replayed
payload is omitted on subsequent duplicate requests.
Because the patch diff content was unavailable at time of writing, no code hunks are
included here. The six commits linked in the source references represent backports
across multiple stable kernel branches. The most representative upstream fix can be
found at the commit URLs listed in the References section once
git.kernel.org
access is restored.
Impact
According to the NVD record, this vulnerability can be triggered remotely by an
unauthenticated attacker using two cooperating
NFSv4.0
clients. The attack sequence is:
-
The first client establishes a
LOCKon a file with a large owner string, up to the 1024-byteNFS4_OPAQUE_LIMIT. -
The second client requests a conflicting
LOCKon the same file, causing the server to generate a denial response that includes the large owner string. -
The server’s
nfsd4_encode_operation()copies the full response into the undersizedrp_ibuf, writing up to 944 bytes of attacker-influenced data past the end of the buffer into adjacent heap memory.
The NVD record does not state whether this primitive leads to remote code execution, privilege escalation, or denial of service in practice. Based on the nature of the primitive (a slab out-of-bounds write of up to 944 bytes with partial attacker control over content), the potential for further exploitation exists, but I won’t claim more than the source supports.
Any Linux system with nfsd running and
NFSv4.0
enabled is potentially affected if it can receive connections from untrusted
NFSv4.0
clients.
Mitigation
The NVD record does not list formal mitigations. The following steps reduce exposure without eliminating the vulnerability. None of them substitute for patching.
Restrict NFS server access at the network layer.
Limit which hosts can reach the NFS server using firewall rules. NFS typically uses
TCP/UDP port 2049. For example, on a system using
nftables:
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ip saddr @trusted_nfs_clients tcp dport 2049 accept
ip saddr @trusted_nfs_clients udp dport 2049 accept
}
}
This restricts who can send crafted LOCK requests. It does not prevent
exploitation by a trusted client that is itself compromised.
Disable NFSv4.0 if NFSv4.1 or later is sufficient.
NFSv4.1 and NFSv4.2 have a different session model and do not use the same replay cache
mechanism described here. If your clients support a newer minor version, you can
restrict the server to it. In /etc/nfs.conf:
[nfsd]
vers4.0=n
Then restart the NFS server:
systemctl restart nfs-server
This prevents NFSv4.0 negotiation entirely. The mechanism is that the
vulnerable code path in
nfsd4_encode_operation()
is only exercised for
NFSv4.0
compound operations. Disabling NFSv4.0
at the server removes that path from reachability. Verify that all clients can negotiate
NFSv4.1 or later before applying this in production.
Remediation
Apply the kernel patch that introduces the bounds check in
nfsd4_encode_operation()
before the
read_bytes_from_xdr_buf()
call. The NVD record references six commits across multiple stable kernel branches.
Check your distribution’s security advisories for the package version that includes the
fix, then update using your package manager.
On Debian/Ubuntu-based systems:
sudo apt update && sudo apt upgrade linux-image-$(uname -r)
On RHEL/Fedora-based systems:
sudo dnf update kernel
After updating, reboot to load the patched kernel:
sudo reboot
The fix is a targeted change: it does not alter
NFSD4_REPLAY_ISIZE
or the stateowner layout. The only behavioral change for the fixed kernel
is that
LOCK
denial responses with large conflicting
LOCK
owners will not have their payload cached for replay. This is a safe trade-off because
the client already holds the correct response from the original request.
Verification
After rebooting into the updated kernel, confirm the running version:
uname -r
Compare the output against your distribution’s patched kernel version listed in the relevant security advisory. The exact version number depends on your distribution and the backport timeline; consult your vendor’s advisory for the specific version string.
To confirm that NFSv4.0 is disabled (if you applied that mitigation):
cat /proc/fs/nfsd/versions
A server with NFSv4.0 disabled will show +4
or similar for supported versions but will not list +4.0 as an
independently negotiated minor version, depending on kernel version and configuration.
Cross-reference the output against your
/etc/nfs.conf
settings.
To confirm the NFS server is running the updated binary after the kernel update:
systemctl status nfs-server
The output should show the service as active (running)
and the process start time should reflect the post-reboot state.