[lvc-project] Re: [PATCH] nfsd: fix arithmetic expression overflow in decode_saddr()

NeilBrown neilb at ownmail.net
Thu Sep 25 13:04:31 MSK 2025


On Thu, 25 Sep 2025, Alexandr Sapozhnkiov wrote:
> From: Alexandr Sapozhnikov <alsp705 at gmail.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 at gmail.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
> 
> 
> 




More information about the lvc-project mailing list