CRITICAL Introduced in 3.9
sunrpc XdrBuf Underflow
CVE-2026-89551
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
KernelScan AI9.8CRITICAL
01Description
In the Linux kernel, the following vulnerability has been resolved: SUNRPC: xdr_buf_trim: clamp buf->len to avoid underflow xdr_buf_trim() trims `len` bytes from the tail of an xdr_buf by walking the tail, pages, and head iovecs. Each per-section step uses min_t() so it never removes more bytes than that section holds, but the final accounting at the fix_len label subtracts the total bytes actually consumed from buf->len without any clamp: fix_len: buf->len -= (len - trim); When the caller has set buf->len to a value smaller than the sum of the iov_lens, (len - trim) can exceed buf->len and the unsigned subtraction wraps to near UINT_MAX. gss_krb5_unwrap_v2() reaches xdr_buf_trim() in exactly that state: buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip; buf->len = len - (GSS_KRB5_TOK_HDR_LEN + headskip); xdr_buf_trim(buf, ec + GSS_KRB5_TOK_HDR_LEN + tailskip); buf->len is a small wire-derived value while the iov_lens are at page scale, so the per-section loops legitimately consume far more bytes than buf->len records. The wrapped buf->len then propagates as the authoritative stream bound into every downstream XDR decoder. Fix by clamping the decrement so buf->len bottoms out at zero: buf->len -= min_t(unsigned int, buf->len, len - trim); On the normal path where the iov_lens sum to buf->len, (len - trim) is always <= buf->len and the result is identical to before. No callers change behavior outside the underflow case.
02KernelScan AI Analysis
Risk summary
A network attacker can send a crafted RPC message with a malformed Kerberos GSS token to any host running NFS or other RPC services with RPCSEC_GSS Kerberos authentication, triggering an unsigned integer underflow in the XDR buffer length. The corrupted length propagates into downstream XDR decoders as a near-UINT_MAX bound, enabling out-of-bounds memory access that can leak kernel memory, corrupt data, or crash the kernel. No authentication or privileges are required because the bug fires during token unwrapping before auth completes.
Vulnerability analysis
When an RPC message protected by Kerberos GSS privacy or integrity is received, the unwrap routine sets the XDR buffer length to a small wire-derived value while the underlying I/O vectors remain at page scale. The buffer-trimming helper then subtracts the total bytes it consumed from that small length without any clamp, causing the unsigned result to wrap to near UINT_MAX. This enormous corrupted length becomes the authoritative stream bound for every downstream XDR decoder, allowing out-of-bounds reads and potential further corruption. The fix clamps the subtraction so the buffer length never drops below zero, leaving all normal code paths unchanged. Any network attacker who can deliver an RPC message to a host running NFS or another RPC service with RPCSEC_GSS Kerberos authentication can trigger this; no credentials or local access are required because the underflow occurs during token unwrapping before authentication completes.
Lifecycle
03Fix Versions
| Branch | Introduced | Fixed in | Patch commit |
|---|---|---|---|
| 5.10 | 3.9 | 5.10.270 | a3d77bcd974b |
| 5.15 | 3.9 | 5.15.221 | fa16bbe987b4 |
| 6.1 | 3.9 | 6.1.188 | a924ac4c78af |
| 6.12 | 3.9 | 6.12.109 | e6267cccd7b0 |
| 6.18 | 3.9 | 6.18.50 | ad0cce80d4af |
| 6.6 | 3.9 | 6.6.157 | 4bf59cb0ea5b |
| 7.2 | 3.9 | 7.2.4 | 85e9602650e9 |
| mainline | 3.9 | 7.3 | 3f491306dcb6 |
| cip/5.10 | 3.9 | 5.10.271-cip78 | a3d77bcd974b |
| cip/6.1 | 3.9 | 6.1.189-cip61 | a924ac4c78af |
| cip/6.1-rt | 3.9 | 6.1.189-cip61-rt32 | a924ac4c78af |
| cip/6.12 | 3.9 | 6.12.111-cip32 | e6267cccd7b0 |
04CIP Kernels
State of the newest release of each Civil Infrastructure Platform SLTS tree, from CIP's own fix records.
| CIP tree | State |
|---|---|
| cip/6.12 | Fixed in 6.12.111-cip32 |
| cip/6.1 | Fixed in 6.1.189-cip61 |
| cip/6.1-rt | Fixed in 6.1.189-cip61-rt32 |
| cip/5.10 | Fixed in 5.10.271-cip78 |
| cip/5.10-rt | Affected — no CIP fix yet (latest 5.10.268-cip77-rt34) |
| cip/4.19 | Affected — no CIP fix yet (latest 4.19.325-cip136) |
| cip/4.19-rt | Affected — no CIP fix yet (latest 4.19.325-cip136-rt50) |
| cip/4.4 | Affected — no CIP fix yet (latest 4.4.302-cip115) |
| cip/4.4-rt | Affected — no CIP fix yet (latest 4.4.302-cip115-rt63) |