From: Arjan van de Ven Date: Wed, 29 Apr 2026 08:09:49 -0700 Subject: [PATCH] atm: lec: cancel lec_arp_work before lec_arp_init on reattach This patch is based on a WARNING as reported by syzbot at https://lore.kernel.org/r/69f16c26.170a0220.34e5b8.0013.GAE@google.com. lec_atm_close() clears priv->lecd to NULL via rcu_assign_pointer() and synchronize_rcu(), then calls lec_arp_destroy() to cancel priv->lec_arp_work. Because lec_atm_close() does not hold lec_mutex, there is a race window between the NULL assignment and the work cancellation. A concurrent lecd_attach(), which holds lec_mutex, can enter the else-branch during this window: priv->lecd is NULL so the -EADDRINUSE guard passes, but lec_arp_work is still active from the previous attach/close cycle. lecd_attach() then calls lec_arp_init(priv), which calls INIT_DELAYED_WORK(&priv->lec_arp_work, ...) on an active timer_list. This triggers an ODEBUG: init active WARNING inside __debug_object_init(). This crash only occurs when CONFIG_DEBUG_OBJECTS_TIMERS is enabled. Add cancel_delayed_work_sync(&priv->lec_arp_work) in the else-branch of lecd_attach(), before the lec_arp_init() call. Any in-flight work from a prior close cycle is fully drained before the delayed_work is reinitialized. If lec_arp_destroy() in the concurrent lec_atm_close() has already cancelled the work, the call is a no-op. lec_arp_check_expire(), the work callback, only acquires priv->lec_arp_lock and never acquires lec_mutex, so calling cancel_delayed_work_sync() from within a lec_mutex-held context is deadlock-safe. Reported-by: syzbot+ca9d5686d06994c6547c@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/69f16c26.170a0220.34e5b8.0013.GAE@google.com Link: https://syzkaller.appspot.com/bug?extid=ca9d5686d06994c6547c Oops-Analysis: http://oops.fenrus.org/reports/lkml/69f16c26.170a0220.34e5b8.0013.GAE@google.com/report.html Fixes: d13a3824bfd2 ("net: atm: add lec_mutex") Assisted-by: linux-kernel-oops:claude-sonnet-4.6 linux-kernel-oops. Signed-off-by: Arjan van de Ven Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- net/atm/lec.c | 1 + 1 file changed, 1 insertion(+) --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -776,6 +776,7 @@ static int lecd_attach(struct atm_vcc *vcc, int arg) } else { priv = netdev_priv(dev_lec[i]); if (rcu_access_pointer(priv->lecd)) return -EADDRINUSE; + cancel_delayed_work_sync(&priv->lec_arp_work); } lec_arp_init(priv);