ng_l2tp: Fix callout synchronization in the rexmit timeout handler
A received control packet may cause the transmit queue to be flushed, in which case ng_l2tp_seq_recv_nr() cancels the transmit timeout handler. The handler checks to see if it was cancelled before doing anything, but did so before acquiring the node lock, so a small race window could cause ng_l2tp_seq_rack_timeout() to attempt to flush an empty queue, ultimately causing a null pointer dereference. PR: 241133 Reviewed by: bz, glebius, Lutz Donnerhacke MFC after: 3 days Sponsored by: Rubicon Communications, LLC (Netgate) Differential Revision: https://reviews.freebsd.org/D26548
This commit is contained in:
parent
f9f298a2f4
commit
e62e4b8594
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=366167
@ -1453,15 +1453,17 @@ ng_l2tp_seq_rack_timeout(node_p node, hook_p hook, void *arg1, int arg2)
|
|||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
u_int delay;
|
u_int delay;
|
||||||
|
|
||||||
/* Make sure callout is still active before doing anything */
|
|
||||||
if (callout_pending(&seq->rack_timer) ||
|
|
||||||
(!callout_active(&seq->rack_timer)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
L2TP_SEQ_CHECK(seq);
|
L2TP_SEQ_CHECK(seq);
|
||||||
|
|
||||||
mtx_lock(&seq->mtx);
|
mtx_lock(&seq->mtx);
|
||||||
|
/* Make sure callout is still active before doing anything */
|
||||||
|
if (callout_pending(&seq->rack_timer) ||
|
||||||
|
!callout_active(&seq->rack_timer)) {
|
||||||
|
mtx_unlock(&seq->mtx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
priv->stats.xmitRetransmits++;
|
priv->stats.xmitRetransmits++;
|
||||||
|
|
||||||
/* Have we reached the retransmit limit? If so, notify owner. */
|
/* Have we reached the retransmit limit? If so, notify owner. */
|
||||||
|
Loading…
Reference in New Issue
Block a user