In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: svcauth_gss: enforce krb5 token minimum length
svcauth_gss_unwrap_priv() validates only an upper bound on the
wire-supplied opaque length before handing the buffer to
gss_unwrap():
<pre>
if (len > xdr_stream_remaining(xdr))
goto unwrap_failed;
offset = xdr_stream_pos(xdr);
...
maj_stat = gss_unwrap(ctx, offset, offset + len, buf);
</pre>
The wire value len flows unchanged as the upper bound into the
krb5 unwrap path, so a len in [0, 16] passes this check and is
handed to gss_unwrap(). For a krb5 v2 context that lands in
gss_krb5_unwrap_v2(), which reads the 16-byte RFC 4121 token
header fields at ptr+4 and ptr+6 and then calls rotate_left()
before any integrity check. With a sub-header length the header
reads run past the token, and _rotate_left()'s shift %= buf->len
path can divide by zero when buf->len has been driven to zero by
the truncated token. A header-only token (len == 16) is equally
invalid: with a non-zero RRC field and the opaque blob ending at
the XDR buffer boundary, rotate_left() builds a zero-length
subbuffer, reaching the same division.
Reject the token at the server entry point before it reaches the
krb5 unwrap core. A valid sealed RFC 4121 token must contain
the 16-byte header plus at least some encrypted payload.
Fix by adding a minimum-length check immediately after the
existing upper-bound check:
<pre>
if (len <= GSS_KRB5_TOK_HDR_LEN)
goto unwrap_failed;
</pre>
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVSS Score: 9.8
AV:N - svcauth_gss_unwrap_priv() is reached from in-kernel nfsd over TCP/2049 (svc_authenticate → svcauth_gss_accept) and from the NFSv4.0 RPC_AUTH_GSS callback service, so a remote RPCSEC_GSS peer delivers the short krb5 wrap token over the network.
AC:L - A single RPCSEC_GSS DATA Call with gc_svc=PRIVACY and opaque length in [0, 16] plus a non-zero RRC in the cleartext RFC 4121 header deterministically hits gss_krb5_unwrap_v2() rotate_left() u32 wrap and shift%=0; no race or attacker-uncontrollable layout is required.
PR:N - A malicious NFS server that already shares a krb5p GSS context can send a crafted NFSv4.0 GSS callback into the client's svcauth_gss_unwrap_priv() with no account or capability on the victim. That peer path is the highest-severity reachability.
UI:N - nfsd unwraps the Call in the service thread with no local user action. On the client, the NFSv4.0 GSS callback path runs from the callback service thread once an NFS/RPCSEC_GSS mount exists; no additional mount, click, or open is required at attack time.
S:U - The out-of-bounds accesses, divide-by-zero, and underflowed memmove corrupt host kernel SUNRPC/GSS state on the machine processing the RPC. This is ordinary same-host kernel impact, not a VM escape, IOMMU bypass, or other changed-scope boundary.
C:H - Short tokens make gss_krb5_unwrap_v2() read EC/RRC past the token, and the dead BUG_ON lets unsigned movelen underflow into a ~UINT_MAX-byte memmove that copies kernel memory beyond the receive head; that unbounded read is C:H per kernel CNA memory-corruption guidance.
I:H - The same underflowed memmove() writes near 4GiB through the RPC receive head, an out-of-bounds write exploitable for control-flow hijack. rotate_left() also ignores xdr_buf_subsegment() failure after u32 wrap and then writes through a subbuf whose length has wrapped.
A:H - _rotate_left() does shift %= buf->len on a zero-length subbuffer (header-only token at the XDR boundary), a divide-by-zero oops/panic; the UINT_MAX memmove and wrapped-length rotate loop hang or oops nfsd/callback threads, and the attacker can repeat the RPC to deny service.
| Attack Vector |
Network |
Scope |
Unchanged |
| Attack Complexity |
Low |
Confidentiality Impact |
High |
| Privileges Required |
None |
Integrity Impact |
High |
| User Interaction |
None |
Availability Impact |
High |
AV:N - svcauth_gss_unwrap_priv() is reached from in-kernel nfsd over TCP/2049 (svc_authenticate → svcauth_gss_accept) and from the NFSv4.0 RPC_AUTH_GSS callback service, so a remote RPCSEC_GSS peer delivers the short krb5 wrap token over the network.
AC:L - A single RPCSEC_GSS DATA Call with gc_svc=PRIVACY and opaque length in [0, 16] plus a non-zero RRC in the cleartext RFC 4121 header deterministically hits gss_krb5_unwrap_v2() rotate_left() u32 wrap and shift%=0; no race or attacker-uncontrollable layout is required.
PR:N - A malicious NFS server that already shares a krb5p GSS context can send a crafted NFSv4.0 GSS callback into the client's svcauth_gss_unwrap_priv() with no account or capability on the victim. That peer path is the highest-severity reachability.
UI:N - nfsd unwraps the Call in the service thread with no local user action. On the client, the NFSv4.0 GSS callback path runs from the callback service thread once an NFS/RPCSEC_GSS mount exists; no additional mount, click, or open is required at attack time.
S:U - The out-of-bounds accesses, divide-by-zero, and underflowed memmove corrupt host kernel SUNRPC/GSS state on the machine processing the RPC. This is ordinary same-host kernel impact, not a VM escape, IOMMU bypass, or other changed-scope boundary.
C:H - Short tokens make gss_krb5_unwrap_v2() read EC/RRC past the token, and the dead BUG_ON lets unsigned movelen underflow into a ~UINT_MAX-byte memmove that copies kernel memory beyond the receive head; that unbounded read is C:H per kernel CNA memory-corruption guidance.
I:H - The same underflowed memmove() writes near 4GiB through the RPC receive head, an out-of-bounds write exploitable for control-flow hijack. rotate_left() also ignores xdr_buf_subsegment() failure after u32 wrap and then writes through a subbuf whose length has wrapped.
A:H - _rotate_left() does shift %= buf->len on a zero-length subbuffer (header-only token at the XDR boundary), a divide-by-zero oops/panic; the UINT_MAX memmove and wrapped-length rotate loop hang or oops nfsd/callback threads, and the attacker can repeat the RPC to deny service.
CVSS 3.1