Skip to content

Commit c31a0fa

Browse files
f6bvpgregkh
authored andcommitted
rose: drop CALL_REQUEST in loopback timer when device is not running
commit cf5567a2652e44866eae8987dff4c1ea507680df upstream. When ax25stop brings down rose0 while the loopback timer has pending CALL_REQUEST frames, rose_loopback_timer() calls rose_dev_get() and finds the device still registered (unregister_netdevice waits for refs to drop), then calls rose_rx_call_request() which takes a netdev_hold() for the new socket. But NETDEV_DOWN fires only once: rose_kill_by_device() already ran before this timer tick, so the new socket is never cleaned up. The stuck reference prevents unregister_netdevice from completing, and the orphan socket's timers eventually fire on freed memory (KASAN slab-use-after-free in __run_timers). The kernel clears IFF_UP via dev_close() before sending NETDEV_DOWN, so checking netif_running() after rose_dev_get() is sufficient: if the device is no longer running, the CALL_REQUEST is silently dropped and no socket is created. This closes the race without touching the module-exit path (which already stops the timer via loopback_stopping). Tested: unregister_netdevice completes immediately after ax25stop with active loopback connections; no ref_tracker warnings, no KASAN. Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 74cbe94 commit c31a0fa

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

net/rose/rose_loopback.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ static void rose_loopback_timer(struct timer_list *unused)
118118
kfree_skb(skb);
119119
continue;
120120
}
121+
/* rose_kill_by_device() runs on NETDEV_DOWN (IFF_UP cleared)
122+
* before the device is unregistered. If we create a new
123+
* socket here after that cleanup, the ref never gets released
124+
* because NETDEV_DOWN fires only once. Drop the call instead.
125+
*/
126+
if (!netif_running(dev)) {
127+
dev_put(dev);
128+
kfree_skb(skb);
129+
continue;
130+
}
121131

122132
if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0)
123133
kfree_skb(skb);

0 commit comments

Comments
 (0)