DragonFlyBSD Kernel Audit
DF-0492 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netgraph/l2tp/ng_l2tp.c b/sys/netgraph/l2tp/ng_l2tp.c
--- a/sys/netgraph/l2tp/ng_l2tp.c
+++ b/sys/netgraph/l2tp/ng_l2tp.c
@@ -61,6 +61,7 @@
 #include <netgraph/ng_message.h>
 #include <netgraph/netgraph.h>
 #include <netgraph/ng_parse.h>
+#include <sys/spinlock2.h>
 #include "ng_l2tp.h"
 
 #ifdef NG_SEPARATE_MALLOC
@@ -121,6 +122,7 @@
 	u_int16_t		ns;		/* next xmit seq we send */
 	u_int16_t		nr;		/* next recv seq we expect */
 	u_int16_t		rack;		/* last 'nr' we rec'd */
+	struct spinlock		seq_lock;	/* protects seq state (DF-0492) */
 	u_int16_t		xack;		/* last 'nr' we sent */
 	u_int16_t		wmax;		/* peer's max recv window */
 	u_int16_t		cwnd;		/* current congestion window */
@@ -1131,11 +1133,16 @@
 	int nack;
 	int i;
 
+	spin_lock(&seq->seq_lock);
+
 	/* Verify peer's ACK is in range */
-	if ((nack = L2TP_SEQ_DIFF(nr, seq->rack)) <= 0)
+	if ((nack = L2TP_SEQ_DIFF(nr, seq->rack)) <= 0) {
+		spin_unlock(&seq->seq_lock);
 		return;				/* duplicate ack */
+	}
 	if (L2TP_SEQ_DIFF(nr, seq->ns) > 0) {
 		priv->stats.recvBadAcks++;	/* ack for packet not sent */
+		spin_unlock(&seq->seq_lock);
 		return;
 	}
 	KASSERT(nack <= L2TP_MAX_XWIN,