mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 16:10:02 +02:00
sctp: fix a TOCTOU race in SCTP_CMD_TIMER_START
The SCTP_CMD_TIMER_START handler checks timer_pending() before calling
timer_reduce(). The timer can expire and detach between these operations,
causing timer_reduce() to rearm the timer without taking the association
reference required for the newly armed timer.
The timer callback later unconditionally drops its association reference,
which can leave the association reference count unbalanced and result in
use-after-free during association teardown.
Use the return value of timer_reduce() to determine whether the timer was
actually armed. Take the association reference only when timer_reduce()
successfully starts a new timer, closing the race between checking the
timer state and rearming it.
This issue was reported by Nico Yip (@_cyeaa_) working with TrendAI Zero
Day Initiative.
Fixes: 20a785aa52 ("sctp: Don't add the shutdown timer if its already been added")
Reported-by: Zero Day Initiative <zdi-disclosures@trendmicro.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/9d8f1b5c50329d5ea7c642128d35681abaa9ed20.1787773744.git.lucien.xin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
b84cc38f3f
commit
2188569e7e
|
|
@ -1545,17 +1545,8 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type,
|
|||
timeout = asoc->timeouts[cmd->obj.to];
|
||||
BUG_ON(!timeout);
|
||||
|
||||
/*
|
||||
* SCTP has a hard time with timer starts. Because we process
|
||||
* timer starts as side effects, it can be hard to tell if we
|
||||
* have already started a timer or not, which leads to BUG
|
||||
* halts when we call add_timer. So here, instead of just starting
|
||||
* a timer, if the timer is already started, and just mod
|
||||
* the timer with the shorter of the two expiration times
|
||||
*/
|
||||
if (!timer_pending(timer))
|
||||
if (!timer_reduce(timer, jiffies + timeout))
|
||||
sctp_association_hold(asoc);
|
||||
timer_reduce(timer, jiffies + timeout);
|
||||
break;
|
||||
|
||||
case SCTP_CMD_TIMER_RESTART:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user