Mitigate the stream.c attacks
o Drop all broadcast and multicast source addresses in tcp_input. o Enable ICMP_BANDLIM in GENERIC. o Change default to 200/s from 100/s. This will still stop the attack, but is conservative enough to do this close to code freeze. This is not the optimal patch for the problem, but is likely the least intrusive patch that can be made for this. Obtained from: Don Lewis and Matt Dillon. Reviewed by: freebsd-security
This commit is contained in:
parent
f8e48f511e
commit
9d11326d86
@ -59,6 +59,7 @@ options KTRACE #ktrace(1) syscall trace support
|
||||
options SYSVSHM #SYSV-style shared memory
|
||||
options SYSVMSG #SYSV-style message queues
|
||||
options SYSVSEM #SYSV-style semaphores
|
||||
options ICMP_BANDLIM # Rate limit bad replies
|
||||
|
||||
# Standard busses
|
||||
device isa
|
||||
|
@ -59,6 +59,7 @@ options KTRACE #ktrace(1) syscall trace support
|
||||
options SYSVSHM #SYSV-style shared memory
|
||||
options SYSVMSG #SYSV-style message queues
|
||||
options SYSVSEM #SYSV-style semaphores
|
||||
options ICMP_BANDLIM # Rate limit bad replies
|
||||
|
||||
# Standard busses
|
||||
device isa
|
||||
|
@ -51,6 +51,7 @@ options SYSVSEM #SYSV-style semaphores
|
||||
options P1003_1B #Posix P1003_1B real-time extentions
|
||||
options _KPOSIX_PRIORITY_SCHEDULING
|
||||
options _KPOSIX_VERSION=199309L
|
||||
options ICMP_BANDLIM # Rate limit bad replies
|
||||
|
||||
# To make an SMP kernel, the next two are needed
|
||||
#options SMP # Symmetric MultiProcessor Kernel
|
||||
|
@ -51,6 +51,7 @@ options SYSVSEM #SYSV-style semaphores
|
||||
options P1003_1B #Posix P1003_1B real-time extentions
|
||||
options _KPOSIX_PRIORITY_SCHEDULING
|
||||
options _KPOSIX_VERSION=199309L
|
||||
options ICMP_BANDLIM # Rate limit bad replies
|
||||
|
||||
# To make an SMP kernel, the next two are needed
|
||||
#options SMP # Symmetric MultiProcessor Kernel
|
||||
|
@ -96,7 +96,7 @@ SYSCTL_INT(_net_inet_icmp, OID_AUTO, log_redirect, CTLFLAG_RW,
|
||||
* variable content is -1 and read-only.
|
||||
*/
|
||||
|
||||
static int icmplim = 100;
|
||||
static int icmplim = 200;
|
||||
SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_RW,
|
||||
&icmplim, 0, "");
|
||||
#else
|
||||
|
@ -615,10 +615,6 @@ tcp_input(m, off0, proto)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef ICMP_BANDLIM
|
||||
if (badport_bandlim(1) < 0)
|
||||
goto drop;
|
||||
#endif
|
||||
if (blackhole) {
|
||||
switch (blackhole) {
|
||||
case 1:
|
||||
@ -631,11 +627,11 @@ tcp_input(m, off0, proto)
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
}
|
||||
tp = intotcpcb(inp);
|
||||
if (tp == 0)
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
if (tp->t_state == TCPS_CLOSED)
|
||||
goto drop;
|
||||
|
||||
@ -695,7 +691,7 @@ tcp_input(m, off0, proto)
|
||||
*/
|
||||
if (thflags & TH_ACK) {
|
||||
tcpstat.tcps_badsyn++;
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
}
|
||||
goto drop;
|
||||
}
|
||||
@ -772,7 +768,7 @@ tcp_input(m, off0, proto)
|
||||
*/
|
||||
if (thflags & TH_ACK) {
|
||||
tcpstat.tcps_badsyn++;
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
}
|
||||
goto drop;
|
||||
}
|
||||
@ -999,7 +995,7 @@ tcp_input(m, off0, proto)
|
||||
if (thflags & TH_RST)
|
||||
goto drop;
|
||||
if (thflags & TH_ACK)
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
if ((thflags & TH_SYN) == 0)
|
||||
goto drop;
|
||||
if (th->th_dport == th->th_sport) {
|
||||
@ -1017,16 +1013,22 @@ tcp_input(m, off0, proto)
|
||||
* RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
|
||||
* in_broadcast() should never return true on a received
|
||||
* packet with M_BCAST not set.
|
||||
*
|
||||
* Packets with a multicast source address should also
|
||||
* be discarded.
|
||||
*/
|
||||
if (m->m_flags & (M_BCAST|M_MCAST))
|
||||
goto drop;
|
||||
#ifdef INET6
|
||||
if (isipv6) {
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
|
||||
IN6_IS_ADDR_MULTICAST(&ip6->ip6_src))
|
||||
goto drop;
|
||||
} else
|
||||
#endif
|
||||
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)))
|
||||
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
|
||||
IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
|
||||
ip->ip_src.s_addr == htonl(INADDR_BROADCAST))
|
||||
goto drop;
|
||||
#ifdef INET6
|
||||
if (isipv6) {
|
||||
@ -1187,7 +1189,7 @@ tcp_input(m, off0, proto)
|
||||
if ((thflags & TH_ACK) &&
|
||||
(SEQ_LEQ(th->th_ack, tp->snd_una) ||
|
||||
SEQ_GT(th->th_ack, tp->snd_max)))
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -1529,7 +1531,7 @@ tcp_input(m, off0, proto)
|
||||
* for the "LAND" DoS attack.
|
||||
*/
|
||||
if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs))
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
|
||||
todrop = tp->rcv_nxt - th->th_seq;
|
||||
if (todrop > 0) {
|
||||
@ -2192,7 +2194,7 @@ tcp_input(m, off0, proto)
|
||||
if (tp->t_state == TCPS_SYN_RECEIVED && (thflags & TH_ACK) &&
|
||||
(SEQ_GT(tp->snd_una, th->th_ack) ||
|
||||
SEQ_GT(th->th_ack, tp->snd_max)) )
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
#ifdef TCPDEBUG
|
||||
if (so->so_options & SO_DEBUG)
|
||||
tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen,
|
||||
@ -2203,6 +2205,17 @@ tcp_input(m, off0, proto)
|
||||
(void) tcp_output(tp);
|
||||
return;
|
||||
|
||||
|
||||
/*
|
||||
* Conditionally drop with reset or just drop depending on whether
|
||||
* we think we are under attack or not.
|
||||
*/
|
||||
maybedropwithreset:
|
||||
#ifdef ICMP_BANDLIM
|
||||
if (badport_bandlim(1) < 0)
|
||||
goto drop;
|
||||
#endif
|
||||
/* fall through */
|
||||
dropwithreset:
|
||||
#ifdef TCP_RESTRICT_RST
|
||||
if (restrict_rst)
|
||||
@ -2217,11 +2230,14 @@ tcp_input(m, off0, proto)
|
||||
goto drop;
|
||||
#ifdef INET6
|
||||
if (isipv6) {
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
|
||||
IN6_IS_ADDR_MULTICAST(&ip6->ip6_src))
|
||||
goto drop;
|
||||
} else
|
||||
#endif /* INET6 */
|
||||
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)))
|
||||
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
|
||||
IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
|
||||
ip->ip_src.s_addr == htonl(INADDR_BROADCAST))
|
||||
goto drop;
|
||||
/* IPv6 anycast check is done at tcp6_input() */
|
||||
#ifdef TCPDEBUG
|
||||
|
@ -615,10 +615,6 @@ tcp_input(m, off0, proto)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef ICMP_BANDLIM
|
||||
if (badport_bandlim(1) < 0)
|
||||
goto drop;
|
||||
#endif
|
||||
if (blackhole) {
|
||||
switch (blackhole) {
|
||||
case 1:
|
||||
@ -631,11 +627,11 @@ tcp_input(m, off0, proto)
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
}
|
||||
tp = intotcpcb(inp);
|
||||
if (tp == 0)
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
if (tp->t_state == TCPS_CLOSED)
|
||||
goto drop;
|
||||
|
||||
@ -695,7 +691,7 @@ tcp_input(m, off0, proto)
|
||||
*/
|
||||
if (thflags & TH_ACK) {
|
||||
tcpstat.tcps_badsyn++;
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
}
|
||||
goto drop;
|
||||
}
|
||||
@ -772,7 +768,7 @@ tcp_input(m, off0, proto)
|
||||
*/
|
||||
if (thflags & TH_ACK) {
|
||||
tcpstat.tcps_badsyn++;
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
}
|
||||
goto drop;
|
||||
}
|
||||
@ -999,7 +995,7 @@ tcp_input(m, off0, proto)
|
||||
if (thflags & TH_RST)
|
||||
goto drop;
|
||||
if (thflags & TH_ACK)
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
if ((thflags & TH_SYN) == 0)
|
||||
goto drop;
|
||||
if (th->th_dport == th->th_sport) {
|
||||
@ -1017,16 +1013,22 @@ tcp_input(m, off0, proto)
|
||||
* RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
|
||||
* in_broadcast() should never return true on a received
|
||||
* packet with M_BCAST not set.
|
||||
*
|
||||
* Packets with a multicast source address should also
|
||||
* be discarded.
|
||||
*/
|
||||
if (m->m_flags & (M_BCAST|M_MCAST))
|
||||
goto drop;
|
||||
#ifdef INET6
|
||||
if (isipv6) {
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
|
||||
IN6_IS_ADDR_MULTICAST(&ip6->ip6_src))
|
||||
goto drop;
|
||||
} else
|
||||
#endif
|
||||
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)))
|
||||
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
|
||||
IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
|
||||
ip->ip_src.s_addr == htonl(INADDR_BROADCAST))
|
||||
goto drop;
|
||||
#ifdef INET6
|
||||
if (isipv6) {
|
||||
@ -1187,7 +1189,7 @@ tcp_input(m, off0, proto)
|
||||
if ((thflags & TH_ACK) &&
|
||||
(SEQ_LEQ(th->th_ack, tp->snd_una) ||
|
||||
SEQ_GT(th->th_ack, tp->snd_max)))
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -1529,7 +1531,7 @@ tcp_input(m, off0, proto)
|
||||
* for the "LAND" DoS attack.
|
||||
*/
|
||||
if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs))
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
|
||||
todrop = tp->rcv_nxt - th->th_seq;
|
||||
if (todrop > 0) {
|
||||
@ -2192,7 +2194,7 @@ tcp_input(m, off0, proto)
|
||||
if (tp->t_state == TCPS_SYN_RECEIVED && (thflags & TH_ACK) &&
|
||||
(SEQ_GT(tp->snd_una, th->th_ack) ||
|
||||
SEQ_GT(th->th_ack, tp->snd_max)) )
|
||||
goto dropwithreset;
|
||||
goto maybedropwithreset;
|
||||
#ifdef TCPDEBUG
|
||||
if (so->so_options & SO_DEBUG)
|
||||
tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen,
|
||||
@ -2203,6 +2205,17 @@ tcp_input(m, off0, proto)
|
||||
(void) tcp_output(tp);
|
||||
return;
|
||||
|
||||
|
||||
/*
|
||||
* Conditionally drop with reset or just drop depending on whether
|
||||
* we think we are under attack or not.
|
||||
*/
|
||||
maybedropwithreset:
|
||||
#ifdef ICMP_BANDLIM
|
||||
if (badport_bandlim(1) < 0)
|
||||
goto drop;
|
||||
#endif
|
||||
/* fall through */
|
||||
dropwithreset:
|
||||
#ifdef TCP_RESTRICT_RST
|
||||
if (restrict_rst)
|
||||
@ -2217,11 +2230,14 @@ tcp_input(m, off0, proto)
|
||||
goto drop;
|
||||
#ifdef INET6
|
||||
if (isipv6) {
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
|
||||
IN6_IS_ADDR_MULTICAST(&ip6->ip6_src))
|
||||
goto drop;
|
||||
} else
|
||||
#endif /* INET6 */
|
||||
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)))
|
||||
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
|
||||
IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
|
||||
ip->ip_src.s_addr == htonl(INADDR_BROADCAST))
|
||||
goto drop;
|
||||
/* IPv6 anycast check is done at tcp6_input() */
|
||||
#ifdef TCPDEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user