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

Eric Dumazet <[email protected]> Thu, 23 Jul 2026 08:48:06 +0200
Newsgroups org.kernel.vger.linux-ppp,org.kernel.vger.netdev
Message-ID <CANn89i+E=JBRGj3cK+6mfVEX+PUjYrpkkWk1dB3VswnW4X_KGw@mail.gmail.com>
On Thu, Jul 23, 2026 at 8:24=E2=80=AFAM Qingfang Deng <qingfang.deng@linux.=
dev> wrote:
>
> Hi,
>
> On 2026/7/22 18:16, Eric Dumazet wrote:
> > diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generi=
c.c
> > index ef54e0a0462a175bb989db8dda895e9ae755965f..cacc4c3a37d2cda0aea2e17=
6e5d0638f959e18a3 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 =3D (jiffies - ppp->last_xmit) / HZ;
> > -                idle32.recv_idle =3D (jiffies - ppp->last_recv) / HZ;
> > -                if (copy_to_user(argp, &idle32, sizeof(idle32)))
> > +             idle32.xmit_idle =3D max(0L, (long)(jiffies - READ_ONCE(p=
pp->last_xmit))) / HZ;
> > +             idle32.recv_idle =3D max(0L, (long)(jiffies - READ_ONCE(p=
pp->last_recv))) / HZ;
> In the original code, the difference will wrap around on a 32-bit kernel
> with HZ=3D1000 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.

I do not think the code was ready to handle long idle sessions to begin wit=
h.

Can you elaborate on the 'worse' part, because I do not get it,

We perform a max(0L, delta) quite often in the kernel, in lockless contexts=
.

delta =3D jiffies - ppp->last_recv ; can be ~0UL if another cpu was able
to update last_recv to (jiffies+1).

We prefer in this case returning 0 instead of ~infinity.