Re: [syzbot] [sctp?] WARNING: refcount bug in sctp_transport_put (6)

From: David Laight

Date: Tue Sep 01 2026 - 11:14:47 EST


On Tue, 1 Sep 2026 09:45:42 -0400
Xin Long <lucien.xin@xxxxxxxxx> wrote:

> On Mon, Aug 31, 2026 at 11:47 PM xietangxin <xietangxin@xxxxxxxxxxxxxx> wrote:
> >
> > Hi,
> >
> > I have analyzed this issue and successfully reproduced locally.
> > The race occurs between the timer callback (`sctp_generate_heartbeat_event`) and
> > the transport cleanup path (`sctp_transport_free`):
> >
> > Task 1(Timer Softirq) Task 2(sctp_transport_free)
> > ========================== ===============================
> > sctp_generate_heartbeat_event()
> > refcnt = 2
> >
> > bh_lock_sock(sk)
> > sock_owned_by_user(sk)
> > mod_timer(&hb_timer) -> returns 0
> > sctp_transport_free()
> > transport->dead = 1
> > del_timer(&hb_timer) -> returns 1!
> > sctp_transport_put() (2 -> 1)
> > sctp_transport_put() (1 -> 0)
> > sctp_transport_destroy()
> >
> > sctp_transport_hold()
> > -> refcnt is 0, increment fails
>
> This should not be 0, as the transport must hold a refcnt to start the
> hb_timer.

Isn't there one hold sctp_generate_heartbeat_event() and a second for
whatever 'task 2' is doing.
When hb_timer is started it is given another hold (does it actually need one??).
So when hb_timer is deleted it's hold is removed.
But the del_timer() is happening before the the extra hold is obtained.

The RHS (task 2) would need to hold bh_lock_sock().

Try giving sctp_generate_heartbeat_event() two holds.

David


>
> Also, the delay below is under bh_lock_sock(), so it should not be the
> real cause of the issue.
>
> Could you share the PoC for this issue?
>
> Thanks.
>
> > out_unlock:
> > sctp_transport_put() (0 -> -1)
> > -> refcount underflow warning!
> >
> >
> >
> > Adding a small delay after `mod_timer()` increases the reproduction rate:
> >
> > --- a/net/sctp/sm_sideeffect.c
> > +++ b/net/sctp/sm_sideeffect.c
> > @@ -373,8 +373,10 @@ void sctp_generate_heartbeat_event(struct timer_list *t)
> > pr_debug("%s: sock is busy\n", __func__);
> >
> > /* Try again later. */
> > - if (!mod_timer(&transport->hb_timer, jiffies + (HZ/20)))
> > + if (!mod_timer(&transport->hb_timer, jiffies + (HZ/20))) {
> > + mdelay(1);
> > sctp_transport_hold(transport);
> > + }
> > goto out_unlock;
> > }
> >
> > Any feedback or guidance would be greatly appreciated.
> >
> > --
> > Best regards,
> > Tangxin Xie
> >
>