Date: Sat, 22 Jan 2000 03:48:01 -0800 From: Don Lewis <Don.Lewis@tsc.tdk.com> To: Warner Losh <imp@village.org> Cc: security@FreeBSD.ORG Subject: Re: stream.c worst-case kernel paths Message-ID: <200001221148.DAA16946@salsa.gv.tsc.tdk.com> In-Reply-To: <200001220659.WAA15977@salsa.gv.tsc.tdk.com> References: <200001220659.WAA15977@salsa.gv.tsc.tdk.com>
index | next in thread | previous in thread | raw e-mail
On Jan 21, 10:59pm, Don Lewis wrote:
} Subject: Re: stream.c worst-case kernel paths
} On Jan 21, 11:09pm, Warner Losh wrote:
} } Subject: Re: stream.c worst-case kernel paths
} } In message <200001220551.VAA15775@salsa.gv.tsc.tdk.com> Don Lewis writes:
} } : (b) still needs to be generalized to cover other paths that generate
} } : RST packets.
} }
} } Matt has a patch for (b).
}
} Which is why I didn't implement (b). I figured his implementation
} would be better than mine.
}
} } You two might want to merge the two.
}
} That sounds good to me.
Ok, I haven't seen Matt's patch for (b), so I just moved the exiting
ICMP_BANDLIM code down to the dropwithreset code. I also made the
part of optimization to the wildcard test that Brett and I discussed.
This patch compiled OK for me , and function correctly when I did some
simple testing. Now it really needs a good thrashing.
*** tcp_input.c.orig Fri Jan 21 09:04:37 2000
--- tcp_input.c Sat Jan 22 03:40:05 2000
***************
*** 381,386 ****
--- 381,387 ----
struct tcpopt to; /* options in this segment */
struct rmxp_tao *taop; /* pointer to our TAO cache entry */
struct rmxp_tao tao_noncached; /* in case there's no cached entry */
+ int wildcard = 0;
#ifdef TCPDEBUG
short ostate = 0;
#endif
***************
*** 511,518 ****
drop_hdrlen = off0 + off;
/*
! * Locate pcb for segment.
*/
findpcb:
#ifdef IPFIREWALL_FORWARD
if (ip_fw_fwd_addr != NULL
--- 512,528 ----
drop_hdrlen = off0 + off;
/*
! * Locate pcb for segment. If this is not a SYN segment, don't
! * bother searching for the pcb of a listening socket with a
! * wildcard address.
! *
! * Checking TH_RST isn't strictly necessary here, but it doesn't
! * cost anything, saves a hash lookup, takes a shorter path to
! * dropwithreset (which will drop the packet), and allows a test
! * to be removed from the TCPS_LISTEN case.
*/
+ if ((thflags & (TH_ACK|TH_SYN|TH_RST)) == TH_SYN)
+ wildcard = 1;
findpcb:
#ifdef IPFIREWALL_FORWARD
if (ip_fw_fwd_addr != NULL
***************
*** 533,544 ****
if (!ip_fw_fwd_addr->sin_port) {
inp = in_pcblookup_hash(&tcbinfo, ip->ip_src,
th->th_sport, ip_fw_fwd_addr->sin_addr,
! th->th_dport, 1, m->m_pkthdr.rcvif);
} else {
inp = in_pcblookup_hash(&tcbinfo,
ip->ip_src, th->th_sport,
ip_fw_fwd_addr->sin_addr,
! ntohs(ip_fw_fwd_addr->sin_port), 1,
m->m_pkthdr.rcvif);
}
}
--- 543,554 ----
if (!ip_fw_fwd_addr->sin_port) {
inp = in_pcblookup_hash(&tcbinfo, ip->ip_src,
th->th_sport, ip_fw_fwd_addr->sin_addr,
! th->th_dport, wildcard, m->m_pkthdr.rcvif);
} else {
inp = in_pcblookup_hash(&tcbinfo,
ip->ip_src, th->th_sport,
ip_fw_fwd_addr->sin_addr,
! ntohs(ip_fw_fwd_addr->sin_port), wildcard,
m->m_pkthdr.rcvif);
}
}
***************
*** 549,560 ****
#ifdef INET6
if (isipv6)
inp = in6_pcblookup_hash(&tcbinfo, &ip6->ip6_src, th->th_sport,
! &ip6->ip6_dst, th->th_dport, 1,
m->m_pkthdr.rcvif);
else
#endif /* INET6 */
inp = in_pcblookup_hash(&tcbinfo, ip->ip_src, th->th_sport,
! ip->ip_dst, th->th_dport, 1, m->m_pkthdr.rcvif);
}
#ifdef IPSEC
--- 559,570 ----
#ifdef INET6
if (isipv6)
inp = in6_pcblookup_hash(&tcbinfo, &ip6->ip6_src, th->th_sport,
! &ip6->ip6_dst, th->th_dport, wildcard,
m->m_pkthdr.rcvif);
else
#endif /* INET6 */
inp = in_pcblookup_hash(&tcbinfo, ip->ip_src, th->th_sport,
! ip->ip_dst, th->th_dport, wildcard, m->m_pkthdr.rcvif);
}
#ifdef IPSEC
***************
*** 615,624 ****
break;
}
}
- #ifdef ICMP_BANDLIM
- if (badport_bandlim(1) < 0)
- goto drop;
- #endif
if (blackhole) {
switch (blackhole) {
case 1:
--- 625,630 ----
***************
*** 996,1001 ****
--- 1002,1013 ----
register struct sockaddr_in6 *sin6;
#endif
+ /*
+ * XXX - the following three tests should no longer be
+ * necessary because of the "wildcard" test added
+ * above. These should probably be changed to assertions
+ * until the code is thoroughly shaked out.
+ */
if (thflags & TH_RST)
goto drop;
if (thflags & TH_ACK)
***************
*** 1017,1032 ****
* 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.
*/
if (m->m_flags & (M_BCAST|M_MCAST))
goto drop;
#ifdef INET6
if (isipv6) {
! if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
goto drop;
} else
#endif
! if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)))
goto drop;
#ifdef INET6
if (isipv6) {
--- 1029,1050 ----
* 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) ||
! IN6_IS_ADDR_MULTICAST(&ip6->ip6_src))
goto drop;
} else
#endif
! if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
! IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
! IN_EXPERIMENTAL(ntohl(ip->ip_src.s_addr)))
goto drop;
#ifdef INET6
if (isipv6) {
***************
*** 2217,2229 ****
goto drop;
#ifdef INET6
if (isipv6) {
! if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
goto drop;
} else
#endif /* INET6 */
! if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)))
goto drop;
/* IPv6 anycast check is done at tcp6_input() */
#ifdef TCPDEBUG
if (tp == 0 || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen,
--- 2235,2254 ----
goto drop;
#ifdef INET6
if (isipv6) {
! 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)) ||
! IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
! IN_EXPERIMENTAL(ntohl(ip->ip_src.s_addr)))
goto drop;
/* IPv6 anycast check is done at tcp6_input() */
+ #ifdef ICMP_BANDLIM
+ if (badport_bandlim(1) < 0)
+ goto drop;
+ #endif
#ifdef TCPDEBUG
if (tp == 0 || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen,
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200001221148.DAA16946>
