lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<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

Powered by Openwall GNU/*/Linux Powered by OpenVZ