doc/share/security/patches/SA-03:03/syncookie.patch
Bjoern A. Zeeb 3571e53040 Import FreeBSD Security Advisories and Errata Notices, as well as their
patches for easier mirroring, to eliminate a special copy, to make
www.freebsd.org/security a full copy of security.freebsd.org and be
eventually be the same.

For now files are just sitting there.   The symlinks are missing.

Discussed on:	www (repository location)
Discussed with:	simon (so)
2012-08-15 06:19:40 +00:00

217 lines
6.5 KiB
Diff

Index: sys/netinet/tcp_syncache.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_syncache.c,v
retrieving revision 1.5.2.8
diff -c -r1.5.2.8 tcp_syncache.c
*** sys/netinet/tcp_syncache.c 18 Aug 2002 22:04:47 -0000 1.5.2.8
--- sys/netinet/tcp_syncache.c 23 Feb 2003 14:38:20 -0000
***************
*** 1222,1243 ****
/*
* The values below are chosen to minimize the size of the tcp_secret
! * table, as well as providing roughly a 4 second lifetime for the cookie.
*/
! #define SYNCOOKIE_HASHSHIFT 2 /* log2(# of 32bit words from hash) */
! #define SYNCOOKIE_WNDBITS 7 /* exposed bits for window indexing */
! #define SYNCOOKIE_TIMESHIFT 5 /* scale ticks to window time units */
- #define SYNCOOKIE_HASHMASK ((1 << SYNCOOKIE_HASHSHIFT) - 1)
#define SYNCOOKIE_WNDMASK ((1 << SYNCOOKIE_WNDBITS) - 1)
! #define SYNCOOKIE_NSECRETS (1 << (SYNCOOKIE_WNDBITS - SYNCOOKIE_HASHSHIFT))
#define SYNCOOKIE_TIMEOUT \
(hz * (1 << SYNCOOKIE_WNDBITS) / (1 << SYNCOOKIE_TIMESHIFT))
#define SYNCOOKIE_DATAMASK ((3 << SYNCOOKIE_WNDBITS) | SYNCOOKIE_WNDMASK)
static struct {
! u_int32_t ts_secbits;
u_int ts_expire;
} tcp_secret[SYNCOOKIE_NSECRETS];
--- 1222,1241 ----
/*
* The values below are chosen to minimize the size of the tcp_secret
! * table, as well as providing roughly a 16 second lifetime for the cookie.
*/
! #define SYNCOOKIE_WNDBITS 5 /* exposed bits for window indexing */
! #define SYNCOOKIE_TIMESHIFT 1 /* scale ticks to window time units */
#define SYNCOOKIE_WNDMASK ((1 << SYNCOOKIE_WNDBITS) - 1)
! #define SYNCOOKIE_NSECRETS (1 << SYNCOOKIE_WNDBITS)
#define SYNCOOKIE_TIMEOUT \
(hz * (1 << SYNCOOKIE_WNDBITS) / (1 << SYNCOOKIE_TIMESHIFT))
#define SYNCOOKIE_DATAMASK ((3 << SYNCOOKIE_WNDBITS) | SYNCOOKIE_WNDMASK)
static struct {
! u_int32_t ts_secbits[4];
u_int ts_expire;
} tcp_secret[SYNCOOKIE_NSECRETS];
***************
*** 1247,1252 ****
--- 1245,1260 ----
#define MD5Add(v) MD5Update(&syn_ctx, (u_char *)&v, sizeof(v))
+ struct md5_add {
+ u_int32_t laddr, faddr;
+ u_int32_t secbits[4];
+ u_int16_t lport, fport;
+ };
+
+ #ifdef CTASSERT
+ CTASSERT(sizeof(struct md5_add) == 28);
+ #endif
+
/*
* Consider the problem of a recreated (and retransmitted) cookie. If the
* original SYN was accepted, the connection is established. The second
***************
*** 1262,1296 ****
{
u_int32_t md5_buffer[4];
u_int32_t data;
! int wnd, idx;
! wnd = ((ticks << SYNCOOKIE_TIMESHIFT) / hz) & SYNCOOKIE_WNDMASK;
! idx = wnd >> SYNCOOKIE_HASHSHIFT;
if (tcp_secret[idx].ts_expire < ticks) {
! tcp_secret[idx].ts_secbits = arc4random();
tcp_secret[idx].ts_expire = ticks + SYNCOOKIE_TIMEOUT;
}
for (data = sizeof(tcp_msstab) / sizeof(int) - 1; data > 0; data--)
if (tcp_msstab[data] <= sc->sc_peer_mss)
break;
! data = (data << SYNCOOKIE_WNDBITS) | wnd;
data ^= sc->sc_irs; /* peer's iss */
MD5Init(&syn_ctx);
#ifdef INET6
if (sc->sc_inc.inc_isipv6) {
MD5Add(sc->sc_inc.inc6_laddr);
MD5Add(sc->sc_inc.inc6_faddr);
} else
#endif
{
! MD5Add(sc->sc_inc.inc_laddr);
! MD5Add(sc->sc_inc.inc_faddr);
}
! MD5Add(sc->sc_inc.inc_lport);
! MD5Add(sc->sc_inc.inc_fport);
! MD5Add(tcp_secret[idx].ts_secbits);
MD5Final((u_char *)&md5_buffer, &syn_ctx);
! data ^= (md5_buffer[wnd & SYNCOOKIE_HASHMASK] & ~SYNCOOKIE_WNDMASK);
return (data);
}
--- 1270,1311 ----
{
u_int32_t md5_buffer[4];
u_int32_t data;
! int idx, i;
! struct md5_add add;
! idx = ((ticks << SYNCOOKIE_TIMESHIFT) / hz) & SYNCOOKIE_WNDMASK;
if (tcp_secret[idx].ts_expire < ticks) {
! for (i = 0; i < 4; i++)
! tcp_secret[idx].ts_secbits[i] = arc4random();
tcp_secret[idx].ts_expire = ticks + SYNCOOKIE_TIMEOUT;
}
for (data = sizeof(tcp_msstab) / sizeof(int) - 1; data > 0; data--)
if (tcp_msstab[data] <= sc->sc_peer_mss)
break;
! data = (data << SYNCOOKIE_WNDBITS) | idx;
data ^= sc->sc_irs; /* peer's iss */
MD5Init(&syn_ctx);
#ifdef INET6
if (sc->sc_inc.inc_isipv6) {
MD5Add(sc->sc_inc.inc6_laddr);
MD5Add(sc->sc_inc.inc6_faddr);
+ add.laddr = 0;
+ add.faddr = 0;
} else
#endif
{
! add.laddr = sc->sc_inc.inc_laddr.s_addr;
! add.faddr = sc->sc_inc.inc_faddr.s_addr;
}
! add.lport = sc->sc_inc.inc_lport;
! add.fport = sc->sc_inc.inc_fport;
! add.secbits[0] = tcp_secret[idx].ts_secbits[0];
! add.secbits[1] = tcp_secret[idx].ts_secbits[1];
! add.secbits[2] = tcp_secret[idx].ts_secbits[2];
! add.secbits[3] = tcp_secret[idx].ts_secbits[3];
! MD5Add(add);
MD5Final((u_char *)&md5_buffer, &syn_ctx);
! data ^= (md5_buffer[0] & ~SYNCOOKIE_WNDMASK);
return (data);
}
***************
*** 1304,1313 ****
struct syncache *sc;
u_int32_t data;
int wnd, idx;
data = (th->th_ack - 1) ^ (th->th_seq - 1); /* remove ISS */
! wnd = data & SYNCOOKIE_WNDMASK;
! idx = wnd >> SYNCOOKIE_HASHSHIFT;
if (tcp_secret[idx].ts_expire < ticks ||
sototcpcb(so)->ts_recent + SYNCOOKIE_TIMEOUT < ticks)
return (NULL);
--- 1319,1328 ----
struct syncache *sc;
u_int32_t data;
int wnd, idx;
+ struct md5_add add;
data = (th->th_ack - 1) ^ (th->th_seq - 1); /* remove ISS */
! idx = data & SYNCOOKIE_WNDMASK;
if (tcp_secret[idx].ts_expire < ticks ||
sototcpcb(so)->ts_recent + SYNCOOKIE_TIMEOUT < ticks)
return (NULL);
***************
*** 1316,1332 ****
if (inc->inc_isipv6) {
MD5Add(inc->inc6_laddr);
MD5Add(inc->inc6_faddr);
} else
#endif
{
! MD5Add(inc->inc_laddr);
! MD5Add(inc->inc_faddr);
}
! MD5Add(inc->inc_lport);
! MD5Add(inc->inc_fport);
! MD5Add(tcp_secret[idx].ts_secbits);
MD5Final((u_char *)&md5_buffer, &syn_ctx);
! data ^= md5_buffer[wnd & SYNCOOKIE_HASHMASK];
if ((data & ~SYNCOOKIE_DATAMASK) != 0)
return (NULL);
data = data >> SYNCOOKIE_WNDBITS;
--- 1331,1353 ----
if (inc->inc_isipv6) {
MD5Add(inc->inc6_laddr);
MD5Add(inc->inc6_faddr);
+ add.laddr = 0;
+ add.faddr = 0;
} else
#endif
{
! add.laddr = inc->inc_laddr.s_addr;
! add.faddr = inc->inc_faddr.s_addr;
}
! add.lport = inc->inc_lport;
! add.fport = inc->inc_fport;
! add.secbits[0] = tcp_secret[idx].ts_secbits[0];
! add.secbits[1] = tcp_secret[idx].ts_secbits[1];
! add.secbits[2] = tcp_secret[idx].ts_secbits[2];
! add.secbits[3] = tcp_secret[idx].ts_secbits[3];
! MD5Add(add);
MD5Final((u_char *)&md5_buffer, &syn_ctx);
! data ^= md5_buffer[0];
if ((data & ~SYNCOOKIE_DATAMASK) != 0)
return (NULL);
data = data >> SYNCOOKIE_WNDBITS;