[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-id: <175879467124.1696783.15457248781908326257@noble.neil.brown.name>
Date: Thu, 25 Sep 2025 20:04:31 +1000
From: NeilBrown <neilb@...mail.net>
To: "Alexandr Sapozhnkiov" <alsp705@...il.com>
Cc: "Chuck Lever" <chuck.lever@...cle.com>, "Jeff Layton" <jlayton@...nel.org>,
"Olga Kornievskaia" <kolga@...app.com>, "Dai Ngo" <Dai.Ngo@...cle.com>,
"Tom Talpey" <tom@...pey.com>, linux-nfs@...r.kernel.org,
linux-kernel@...r.kernel.org, "Alexandr Sapozhnikov" <alsp705@...il.com>,
lvc-project@...uxtesting.org
Subject:
Re: [PATCH] nfsd: fix arithmetic expression overflow in decode_saddr()
On Thu, 25 Sep 2025, Alexandr Sapozhnkiov wrote:
> From: Alexandr Sapozhnikov <alsp705@...il.com>
>
> The value of an arithmetic expression 'tmp1 * NSEC_PER_USEC'
> is a subject to overflow because its operands are not cast
> to a larger data type before performing arithmetic
>
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
Does this matter? What will break if tv_nsec is greater than
999,999,999 ??
>
> Signed-off-by: Alexandr Sapozhnikov <alsp705@...il.com>
> ---
> fs/nfsd/nfsxdr.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
> index 5777f40c7353..df62ed5099de 100644
> --- a/fs/nfsd/nfsxdr.c
> +++ b/fs/nfsd/nfsxdr.c
> @@ -172,6 +172,8 @@ svcxdr_decode_sattr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
> tmp1 = be32_to_cpup(p++);
> tmp2 = be32_to_cpup(p++);
> if (tmp1 != (u32)-1 && tmp2 != (u32)-1) {
> + if (tmp2 > 1000000)
> + tmp2 = 1000000;
1000000 isn't a valud value is it?
> iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
> iap->ia_atime.tv_sec = tmp1;
> iap->ia_atime.tv_nsec = tmp2 * NSEC_PER_USEC;
> @@ -180,6 +182,8 @@ svcxdr_decode_sattr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
> tmp1 = be32_to_cpup(p++);
> tmp2 = be32_to_cpup(p++);
> if (tmp1 != (u32)-1 && tmp2 != (u32)-1) {
> + if (tmp2 > 1000000)
> + tmp2 = 999999;
This is even more weird. 1000001 will become 999999, but 1000000 will
stay as it is.
Why is it even different?
NeilBrown
> iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
> iap->ia_mtime.tv_sec = tmp1;
> iap->ia_mtime.tv_nsec = tmp2 * NSEC_PER_USEC;
> --
> 2.43.0
>
>
>
Powered by blists - more mailing lists