Re: [PATCH net] ppp: annotate data races in ppp_generic

Qingfang Deng <[email protected]> Thu, 23 Jul 2026 14:24:00 +0800
Newsgroups gmane.linux.network,gmane.linux.ppp
Message-ID <[email protected]>
Hi,

On 2026/7/22 18:16, Eric Dumazet wrote:
> diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
> index ef54e0a0462a175bb989db8dda895e9ae755965f..cacc4c3a37d2cda0aea2e176e5d0638f959e18a3 100644
> --- a/drivers/net/ppp/ppp_generic.c
> +++ b/drivers/net/ppp/ppp_generic.c
> @@ -866,16 +870,16 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>   		break;
>   
>   	case PPPIOCGIDLE32:
> -                idle32.xmit_idle = (jiffies - ppp->last_xmit) / HZ;
> -                idle32.recv_idle = (jiffies - ppp->last_recv) / HZ;
> -                if (copy_to_user(argp, &idle32, sizeof(idle32)))
> +		idle32.xmit_idle = max(0L, (long)(jiffies - READ_ONCE(ppp->last_xmit))) / HZ;
> +		idle32.recv_idle = max(0L, (long)(jiffies - READ_ONCE(ppp->last_recv))) / HZ;
In the original code, the difference will wrap around on a 32-bit kernel 
with HZ=1000 if the session sits idle for 4,294,967.295 seconds 
(approximately 49.7 days). With this change, as the difference is cast 
to a long, it will be negative after 2,147,483.647 seconds 
(approximately 24.9 days) and then clamped to zero by max(), making the 
situation worse.
> +		if (copy_to_user(argp, &idle32, sizeof(idle32)))
>   			break;
>   		err = 0;
>   		break;
>   
>   	case PPPIOCGIDLE64:
> -		idle64.xmit_idle = (jiffies - ppp->last_xmit) / HZ;
> -		idle64.recv_idle = (jiffies - ppp->last_recv) / HZ;
> +		idle64.xmit_idle = max(0L, (long)(jiffies - READ_ONCE(ppp->last_xmit))) / HZ;
> +		idle64.recv_idle = max(0L, (long)(jiffies - READ_ONCE(ppp->last_recv))) / HZ;
>   		if (copy_to_user(argp, &idle64, sizeof(idle64)))
>   			break;
>   		err = 0;