Commit 7231e52f authored by Chuck Lever's avatar Chuck Lever Committed by Li Lingfeng
Browse files

NFSD: Prevent a potential integer overflow

stable inclusion
from stable-v5.10.231
commit 3c5f545c9a1f8a1869246f6f3ae8c17289d6a841
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBDHG9
CVE: CVE-2024-53146

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=3c5f545c9a1f8a1869246f6f3ae8c17289d6a841



--------------------------------

commit 7f33b92e5b18e904a481e6e208486da43e4dc841 upstream.

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: default avatarDan Carpenter <dan.carpenter@linaro.org>
Cc: stable@vger.kernel.org
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarLi Lingfeng <lilingfeng3@huawei.com>
parent 908c8608
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -286,17 +286,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;