summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2000-01-28 06:13:09 +0000
committerimp <imp@FreeBSD.org>2000-01-28 06:13:09 +0000
commit9d11326d8605120adbea532fa69211355d967edf (patch)
treeeb7ddca9067c455c52a591ee0e9e14f4d82c1f1b /sys
parentf8e48f511e5de002b13eb638515c1422d6ca1173 (diff)
downloadFreeBSD-src-9d11326d8605120adbea532fa69211355d967edf.zip
FreeBSD-src-9d11326d8605120adbea532fa69211355d967edf.tar.gz
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
Diffstat (limited to 'sys')
-rw-r--r--sys/alpha/conf/GENERIC1
-rw-r--r--sys/alpha/conf/NOTES1
-rw-r--r--sys/amd64/conf/GENERIC1
-rw-r--r--sys/i386/conf/GENERIC1
-rw-r--r--sys/netinet/ip_icmp.c2
-rw-r--r--sys/netinet/tcp_input.c48
-rw-r--r--sys/netinet/tcp_reass.c48
7 files changed, 69 insertions, 33 deletions
diff --git a/sys/alpha/conf/GENERIC b/sys/alpha/conf/GENERIC
index 94c108b..b019739 100644
--- a/sys/alpha/conf/GENERIC
+++ b/sys/alpha/conf/GENERIC
@@ -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
diff --git a/sys/alpha/conf/NOTES b/sys/alpha/conf/NOTES
index 94c108b..b019739 100644
--- a/sys/alpha/conf/NOTES
+++ b/sys/alpha/conf/NOTES
@@ -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
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index ea60ce8..a668d6f 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -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
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index ea60ce8..a668d6f 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -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
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 76ff004..c2f464e 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -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
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 2a847e6..b802880 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -615,10 +615,6 @@ findpcb:
break;
}
}
-#ifdef ICMP_BANDLIM
- if (badport_bandlim(1) < 0)
- goto drop;
-#endif
if (blackhole) {
switch (blackhole) {
case 1:
@@ -631,11 +627,11 @@ findpcb:
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 @@ findpcb:
*/
if (thflags & TH_ACK) {
tcpstat.tcps_badsyn++;
- goto dropwithreset;
+ goto maybedropwithreset;
}
goto drop;
}
@@ -772,7 +768,7 @@ findpcb:
*/
if (thflags & TH_ACK) {
tcpstat.tcps_badsyn++;
- goto dropwithreset;
+ goto maybedropwithreset;
}
goto drop;
}
@@ -999,7 +995,7 @@ findpcb:
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 @@ findpcb:
* 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 @@ findpcb:
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 @@ trimthenstep6:
* 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 @@ dropafterack:
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 @@ dropafterack:
(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 @@ dropwithreset:
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
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 2a847e6..b802880 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -615,10 +615,6 @@ findpcb:
break;
}
}
-#ifdef ICMP_BANDLIM
- if (badport_bandlim(1) < 0)
- goto drop;
-#endif
if (blackhole) {
switch (blackhole) {
case 1:
@@ -631,11 +627,11 @@ findpcb:
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 @@ findpcb:
*/
if (thflags & TH_ACK) {
tcpstat.tcps_badsyn++;
- goto dropwithreset;
+ goto maybedropwithreset;
}
goto drop;
}
@@ -772,7 +768,7 @@ findpcb:
*/
if (thflags & TH_ACK) {
tcpstat.tcps_badsyn++;
- goto dropwithreset;
+ goto maybedropwithreset;
}
goto drop;
}
@@ -999,7 +995,7 @@ findpcb:
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 @@ findpcb:
* 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 @@ findpcb:
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 @@ trimthenstep6:
* 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 @@ dropafterack:
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 @@ dropafterack:
(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 @@ dropwithreset:
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
OpenPOWER on IntegriCloud