mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Merge branch 's390-ctcm-fix-timer-corruption-and-use-after-free'
Nagamani says: ==================== s390/ctcm: Fix timer corruption and use-after-free Fix two bugs in drivers/s390/net/fsm.c and drivers/s390/net/ctcm_main.c found by Sashiko AI code review. Patch 1 fixes timer list corruption when fsm_addtimer() is called on an already-pending timer - timer_setup() re-initializes the timer list_head while it is still enqueued in the wheel. Patch 2 fixes a use-after-free in channel_remove(). For MPC channels the teardown has a circular dependency: the ch->timer callback can schedule ch_disc_tasklet via mpc_action_go_inop(), ch_tasklet can re-arm sweep_timer, and sweep_timer's callback re-arms ch->timer. Fix by shutting down both MPC timers with timer_shutdown_sync() first (sweep_timer before ch->timer), then killing both tasklets. This breaks all three re-arm paths before freeing channel resources. ==================== Link: https://patch.msgid.link/20260930070234.569500-1-nagamani@linux.ibm.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
94085db4a1
|
|
@ -211,9 +211,14 @@ static void channel_remove(struct channel *ch)
|
|||
while (*c) {
|
||||
if (*c == ch) {
|
||||
*c = ch->next;
|
||||
fsm_deltimer(&ch->timer);
|
||||
if (IS_MPC(ch))
|
||||
fsm_deltimer(&ch->sweep_timer);
|
||||
timer_shutdown_sync(&ch->sweep_timer.tl);
|
||||
timer_shutdown_sync(&ch->timer.tl);
|
||||
if (IS_MPC(ch)) {
|
||||
tasklet_kill(&ch->ch_tasklet);
|
||||
tasklet_kill(&ch->ch_disc_tasklet);
|
||||
kfree(ch->discontact_th);
|
||||
}
|
||||
|
||||
kfree_fsm(ch->fsm);
|
||||
clear_normalized_cda(&ch->ccw[4]);
|
||||
|
|
@ -221,11 +226,6 @@ static void channel_remove(struct channel *ch)
|
|||
clear_normalized_cda(&ch->ccw[1]);
|
||||
dev_kfree_skb_any(ch->trans_skb);
|
||||
}
|
||||
if (IS_MPC(ch)) {
|
||||
tasklet_kill(&ch->ch_tasklet);
|
||||
tasklet_kill(&ch->ch_disc_tasklet);
|
||||
kfree(ch->discontact_th);
|
||||
}
|
||||
kfree(ch->ccw);
|
||||
kfree(ch->irb);
|
||||
kfree(ch);
|
||||
|
|
|
|||
|
|
@ -171,11 +171,9 @@ fsm_addtimer(fsm_timer *this, int millisec, int event, void *arg)
|
|||
this->fi->name, this, millisec);
|
||||
#endif
|
||||
|
||||
timer_setup(&this->tl, fsm_expire_timer, 0);
|
||||
this->expire_event = event;
|
||||
this->event_arg = arg;
|
||||
this->tl.expires = jiffies + (millisec * HZ) / 1000;
|
||||
add_timer(&this->tl);
|
||||
mod_timer(&this->tl, jiffies + msecs_to_jiffies(millisec));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -189,12 +187,9 @@ fsm_modtimer(fsm_timer *this, int millisec, int event, void *arg)
|
|||
this->fi->name, this, millisec);
|
||||
#endif
|
||||
|
||||
timer_delete(&this->tl);
|
||||
timer_setup(&this->tl, fsm_expire_timer, 0);
|
||||
this->expire_event = event;
|
||||
this->event_arg = arg;
|
||||
this->tl.expires = jiffies + (millisec * HZ) / 1000;
|
||||
add_timer(&this->tl);
|
||||
mod_timer(&this->tl, jiffies + msecs_to_jiffies(millisec));
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(init_fsm);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user