Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

SUNRPC: Fix ("SUNRPC: Add "@len" parameter to gss_unwrap()")

Braino when converting "buf->len -=" to "buf->len = len -".

The result is under-estimation of the ralign and rslack values. On
krb5p mounts, this has caused READDIR to fail with EIO, and KASAN
splats when decoding READLINK replies.

As a result of fixing this oversight, the gss_unwrap method now
returns a buf->len that can be shorter than priv_len for small
RPC messages. The additional adjustment done in unwrap_priv_data()
can underflow buf->len. This causes the nfsd_request_too_large
check to fail during some NFSv3 operations.

Reported-by: Marian Rainer-Harbach
Reported-by: Pierre Sauter <pierre.sauter@stwm.de>
BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1886277
Fixes: 31c9590ae468 ("SUNRPC: Add "@len" parameter to gss_unwrap()")
Reviewed-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

+1 -2
+1 -1
net/sunrpc/auth_gss/gss_krb5_wrap.c
··· 584 584 buf->head[0].iov_len); 585 585 memmove(ptr, ptr + GSS_KRB5_TOK_HDR_LEN + headskip, movelen); 586 586 buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip; 587 - buf->len = len - GSS_KRB5_TOK_HDR_LEN + headskip; 587 + buf->len = len - (GSS_KRB5_TOK_HDR_LEN + headskip); 588 588 589 589 /* Trim off the trailing "extra count" and checksum blob */ 590 590 xdr_buf_trim(buf, ec + GSS_KRB5_TOK_HDR_LEN + tailskip);
-1
net/sunrpc/auth_gss/svcauth_gss.c
··· 990 990 991 991 maj_stat = gss_unwrap(ctx, 0, priv_len, buf); 992 992 pad = priv_len - buf->len; 993 - buf->len -= pad; 994 993 /* The upper layers assume the buffer is aligned on 4-byte boundaries. 995 994 * In the krb5p case, at least, the data ends up offset, so we need to 996 995 * move it around. */