DF-0484 / fix.diff
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); |