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>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200001221148.DAA16946>