DragonFlyBSD Kernel Audit
DF-0484 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -86,6 +86,7 @@
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/in_cksum.h>
+#include <sys/spinlock2.h>
 
 #include <sys/msgport2.h>
 #include <net/netmsg2.h>
@@ -1356,6 +1357,7 @@
 static int tcp_msstab[] = { 0, 536, 1460, 8960 };
 
 static MD5_CTX syn_ctx;
+static struct spinlock syncookie_sl = SPINLOCK_INITIALIZER(0, 0);
 
 #define MD5Add(v)	MD5Update(&syn_ctx, (u_char *)&v, sizeof(v))
 
@@ -1393,6 +1395,7 @@
 #endif
 
 	idx = ((ticks << SYNCOOKIE_TIMESHIFT) / hz) & SYNCOOKIE_WNDMASK;
+	spin_lock(&syncookie_sl);
 	if (tcp_secret[idx].ts_expire < ticks) {
 		for (i = 0; i < 4; i++)
 			tcp_secret[idx].ts_secbits[i] = karc4random();
@@ -1421,6 +1424,7 @@
 	add.secbits[3] = tcp_secret[idx].ts_secbits[3];
 	MD5Add(add);
 	MD5Final((u_char *)&md5_buffer, &syn_ctx);
+	spin_unlock(&syncookie_sl);
 	data ^= (md5_buffer[0] & ~SYNCOOKIE_WNDMASK);
 	return (data);
 }
@@ -1436,9 +1440,12 @@
 
 	data = (th->th_ack - 1) ^ (th->th_seq - 1);	/* remove ISS */
 	idx = data & SYNCOOKIE_WNDMASK;
+	spin_lock(&syncookie_sl);
 	if (tcp_secret[idx].ts_expire < ticks ||
-	    sototcpcb(so)->ts_recent + SYNCOOKIE_TIMEOUT < ticks)
+	    sototcpcb(so)->ts_recent + SYNCOOKIE_TIMEOUT < ticks) {
+		spin_unlock(&syncookie_sl);
 		return (NULL);
+	}
 	MD5Init(&syn_ctx);
 #ifdef INET6
 	if (inc->inc_isipv6) {
@@ -1460,6 +1467,7 @@
 	add.secbits[3] = tcp_secret[idx].ts_secbits[3];
 	MD5Add(add);
 	MD5Final((u_char *)&md5_buffer, &syn_ctx);
+	spin_unlock(&syncookie_sl);
 	data ^= md5_buffer[0];
 	if (data & ~SYNCOOKIE_DATAMASK)
 		return (NULL);