Syzbot reported a warning at `add_timer`, which is called from the `atm_mpoa_mpoad_attach` function The reason for warning is that in the first call to the ioctl, if there is no MPOA client created yet (mpcs is the linked list for these MPOA clients) we do a `mpc_timer_refresh` to arm the timer. Later on, if the `alloc_mpc` fails (which on success will also initialize mpcs if it's first MPOA client created) and we didn't have any MPOA client yet, we return without the timer de-armed If the same ioctl is called again, since we don't have any MPOA clients yet we again arm the timer, which might already be left armed by the previous call to this ioctl in which `alloc_mpc` failed Hence, de-arm the timer in the event that `alloc_mpc` fails and we don't have any other MPOA client (that is, `mpcs` is NULL) Do a `timer_delete_sync` instead of `timer_delete`, since the timer callback can arm it back again This does not need to be done at the early return in case of `mpc->mpoad_vcc`, or a control channel to MPOAD already exists. The timer should remain there to periodically process caches Reported-by: syzbot+07b635b9c111c566af8b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=07b635b9c111c566af8b Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Deepak Sharma --- v2: - Improved commit message - Fix the faulty condition check to disarm the timer - Use `timer_delete_sync` instead to avoid re-arming of timer v1: - Disarm the timer using `timer_delete` in case `alloc_mpc` fails` net/atm/mpc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/atm/mpc.c b/net/atm/mpc.c index f6b447bba329..4f67ad1d6bef 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -804,7 +804,7 @@ static int atm_mpoa_mpoad_attach(struct atm_vcc *vcc, int arg) /* This lets us now how our LECs are doing */ err = register_netdevice_notifier(&mpoa_notifier); if (err < 0) { - timer_delete(&mpc_timer); + timer_delete_sync(&mpc_timer); return err; } } @@ -813,8 +813,10 @@ static int atm_mpoa_mpoad_attach(struct atm_vcc *vcc, int arg) if (mpc == NULL) { dprintk("allocating new mpc for itf %d\n", arg); mpc = alloc_mpc(); - if (mpc == NULL) + if (!mpcs) { + timer_delete_sync(&mpc_timer); return -ENOMEM; + } mpc->dev_num = arg; mpc->dev = find_lec_by_itfnum(arg); /* NULL if there was no lec */ -- 2.51.0