mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 04:06:26 +00:00
NFSD: Prevent a potential integer overflow
If the tag length is >= U32_MAX - 3 then the "length + 4" addition can result in an integer overflow. Address this by splitting the decoding into several steps so that decode_cb_compound4res() does not have to perform arithmetic on the unsafe length value. Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Cc: stable@vger.kernel.org Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
2d5404caa8
commit
7f33b92e5b
@ -287,17 +287,17 @@ static int decode_cb_compound4res(struct xdr_stream *xdr,
|
||||
u32 length;
|
||||
__be32 *p;
|
||||
|
||||
p = xdr_inline_decode(xdr, 4 + 4);
|
||||
p = xdr_inline_decode(xdr, XDR_UNIT);
|
||||
if (unlikely(p == NULL))
|
||||
goto out_overflow;
|
||||
hdr->status = be32_to_cpup(p++);
|
||||
hdr->status = be32_to_cpup(p);
|
||||
/* Ignore the tag */
|
||||
length = be32_to_cpup(p++);
|
||||
p = xdr_inline_decode(xdr, length + 4);
|
||||
if (unlikely(p == NULL))
|
||||
if (xdr_stream_decode_u32(xdr, &length) < 0)
|
||||
goto out_overflow;
|
||||
if (xdr_inline_decode(xdr, length) == NULL)
|
||||
goto out_overflow;
|
||||
if (xdr_stream_decode_u32(xdr, &hdr->nops) < 0)
|
||||
goto out_overflow;
|
||||
p += XDR_QUADLEN(length);
|
||||
hdr->nops = be32_to_cpup(p);
|
||||
return 0;
|
||||
out_overflow:
|
||||
return -EIO;
|
||||
|
Loading…
Reference in New Issue
Block a user