There is no synchronization between the two timers, rose_t0timer_expiry and rose_timer_expiry. rose_timer_expiry() puts the neighbor when the rose state is ROSE_STATE_2. However, rose_t0timer_expiry() does initiate a restart request on the neighbor. When rose_t0timer_expiry() accesses the released neighbor member digipeat, a UAF is triggered. To avoid this uaf, when rose_timer_expiry() puts the neighbor, the base member digipeat is set to NULL. syzbot reported a slab-use-after-free Read in ax25_find_cb. BUG: KASAN: slab-use-after-free in ax25_find_cb+0x3b8/0x3f0 net/ax25/af_ax25.c:237 Read of size 1 at addr ffff888059c704c0 by task syz.6.2733/17200 Call Trace: ax25_find_cb+0x3b8/0x3f0 net/ax25/af_ax25.c:237 ax25_send_frame+0x157/0xb60 net/ax25/ax25_out.c:55 rose_send_frame+0xcc/0x2c0 net/rose/rose_link.c:106 rose_transmit_restart_request+0x1b8/0x240 net/rose/rose_link.c:198 rose_t0timer_expiry+0x1d/0x150 net/rose/rose_link.c:83 Freed by task 17183: kfree+0x2b8/0x6d0 mm/slub.c:6826 rose_neigh_put include/net/rose.h:165 [inline] rose_timer_expiry+0x537/0x630 net/rose/rose_timer.c:183 call_timer_fn+0x19a/0x620 kernel/time/timer.c:1747 Fixes: dcb34659028f ("net: rose: split remove and free operations in rose_remove_neigh()") Reported-by: syzbot+caa052a0958a9146870d@syzkaller.appspotmail.com Signed-off-by: Lizhi Xu --- include/net/rose.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/net/rose.h b/include/net/rose.h index 2b5491bbf39a..9b0dc81a9589 100644 --- a/include/net/rose.h +++ b/include/net/rose.h @@ -163,6 +163,7 @@ static inline void rose_neigh_put(struct rose_neigh *rose_neigh) if (rose_neigh->ax25) ax25_cb_put(rose_neigh->ax25); kfree(rose_neigh->digipeat); + rose_neigh->digipeat = NULL; kfree(rose_neigh); } } -- 2.43.0