CVE-2026-89551: SUNRPC: xdr_buf_trim: clamp buf->len to avoid underflow
In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: xdrbuftrim: clamp buf->len to avoid underflow
xdrbuftrim() trims len bytes from the tail of an xdrbuf by walking the tail, pages, and head iovecs. Each per-section step uses mint() so it never removes more bytes than that section holds, but the final accounting at the fixlen label subtracts the total bytes actually consumed from buf->len without any clamp:
fixlen: buf->len -= (len - trim);
When the caller has set buf->len to a value smaller than the sum of the iovlens, (len - trim) can exceed buf->len and the unsigned subtraction wraps to near UINTMAX. gsskrb5unwrapv2() reaches xdrbuftrim() in exactly that state:
buf->head[0].iovlen -= GSSKRB5TOKHDRLEN + headskip; buf->len = len - (GSSKRB5TOKHDRLEN + headskip); xdrbuftrim(buf, ec + GSSKRB5TOKHDRLEN + tailskip);
buf->len is a small wire-derived value while the iovlens 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 -= mint(unsigned int, buf->len, len - trim);
On the normal path where the iovlens 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.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
Apply the Linux kernel fix for SUNRPC xdr_buf_trim so buf->len is clamped to avoid unsigned underflow when (len - trim) exceeds buf->len (i.e., ensure buf->len never wraps and downstream accounting uses bounded subtraction).
Linux kernel (SUNRPC: xdr_buf_trim) buf->len clamping to prevent unsigned underflow = Clamp buf->len so that the decrement cannot underflow; ensure calculations subtract at most the available bytes (e.g., use min_t(...) style bounding)
Event History
Frequently Asked Questions
Which kernel processing path is identified as reaching the vulnerable state?
The gss_krb5_unwrap_v2() path reaches xdr_buf_trim() with buf->len set to a small wire-derived value while the associated iov lengths can be page-scale. Systems that exercise this Kerberos GSS unwrap path are the specifically identified exposure case.
What condition causes the length accounting to wrap?
Wrapping occurs when xdr_buf_trim() consumes more bytes across the tail, pages, and head iovecs than are recorded in buf->len. The final unsigned subtraction can then underflow and produce a value near UINT_MAX.
What happens after buf->len wraps?
The wrapped value becomes the authoritative stream bound passed to downstream XDR decoders. This causes those decoders to operate with an incorrectly large length bound.