X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b0d623f7f2ae71ed96e60569f61f9a9a27016e80..c331a0bec715536613c8dd5f34a4e115d5b15824:/bsd/netinet/tcp_input.c?ds=inline diff --git a/bsd/netinet/tcp_input.c b/bsd/netinet/tcp_input.c index b642c4298..b65e9d5c6 100644 --- a/bsd/netinet/tcp_input.c +++ b/bsd/netinet/tcp_input.c @@ -1007,6 +1007,10 @@ findpcb: goto drop; #endif + /* Radar 7377561: Avoid processing packets while closing a listen socket */ + if (tp->t_state == TCPS_LISTEN && (so->so_options & SO_ACCEPTCONN) == 0) + goto drop; + if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) { #if TCPDEBUG if (so->so_options & SO_DEBUG) { @@ -1035,26 +1039,62 @@ findpcb: head_ifscope = (inp->inp_flags & INP_BOUND_IF) ? inp->inp_boundif : IFSCOPE_NONE; -#if !IPSEC /* - * Current IPsec implementation makes incorrect IPsec - * cache if this check is done here. - * So delay this until duplicated socket is created. + * If the state is LISTEN then ignore segment if it contains an RST. + * If the segment contains an ACK then it is bad and send a RST. + * If it does not contain a SYN then it is not interesting; drop it. + * If it is from this socket, drop it, it must be forged. */ if ((thflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) { - /* - * Note: dropwithreset makes sure we don't - * send a RST in response to a RST. - */ + if (thflags & TH_RST) { + goto drop; + } if (thflags & TH_ACK) { + tp = NULL; tcpstat.tcps_badsyn++; rstreason = BANDLIM_RST_OPENPORT; goto dropwithreset; } + + /* We come here if there is no SYN set */ + tcpstat.tcps_badsyn++; goto drop; } -#endif KERNEL_DEBUG(DBG_FNC_TCP_NEWCONN | DBG_FUNC_START,0,0,0,0,0); + if (th->th_dport == th->th_sport) { +#if INET6 + if (isipv6) { + if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, + &ip6->ip6_src)) + goto drop; + } else +#endif /* INET6 */ + if (ip->ip_dst.s_addr == ip->ip_src.s_addr) + goto drop; + } + /* + * 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; +#if 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)) || + ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || + in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) + goto drop; + #if INET6 /* @@ -1146,8 +1186,6 @@ findpcb: so = so2; tcp_lock(so, 1, 0); /* - * This is ugly, but .... - * * Mark socket as temporary until we're * committed to keeping it. The code at * ``drop'' and ``dropwithreset'' check the @@ -1155,9 +1193,10 @@ findpcb: * socket created here should be discarded. * We mark the socket as discardable until * we're committed to it below in TCPS_LISTEN. + * There are some error conditions in which we + * have to drop the temporary socket. */ dropsocket++; - /* * Inherit INP_BOUND_IF from listener; testing if * head_ifscope is non-zero is sufficient, since it @@ -1179,7 +1218,7 @@ findpcb: inp->inp_vflag &= ~INP_IPV6; inp->inp_vflag |= INP_IPV4; #endif /* INET6 */ - inp->inp_laddr = ip->ip_dst; + inp->inp_laddr = ip->ip_dst; #if INET6 } #endif /* INET6 */ @@ -1200,30 +1239,6 @@ findpcb: tcp_unlock(oso, 1, 0); goto drop; } -#if IPSEC - /* - * To avoid creating incorrectly cached IPsec - * association, this is need to be done here. - * - * Subject: (KAME-snap 748) - * From: Wayne Knowles - * ftp://ftp.kame.net/pub/mail-list/snap-users/748 - */ - if ((thflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) { - /* - * Note: dropwithreset makes sure we don't - * send a RST in response to a RST. - */ - tcp_lock(oso, 0, 0); /* release ref on parent */ - tcp_unlock(oso, 1, 0); - if (thflags & TH_ACK) { - tcpstat.tcps_badsyn++; - rstreason = BANDLIM_RST_OPENPORT; - goto dropwithreset; - } - goto drop; - } -#endif #if INET6 if (isipv6) { /* @@ -1285,7 +1300,6 @@ findpcb: KERNEL_DEBUG(DBG_FNC_TCP_NEWCONN | DBG_FUNC_END,0,0,0,0,0); } } - #if 1 lck_mtx_assert(((struct inpcb *)so->so_pcb)->inpcb_mtx, LCK_MTX_ASSERT_OWNED); #endif @@ -1358,7 +1372,7 @@ findpcb: } #if TRAFFIC_MGT - if (so->so_traffic_mgt_flags & TRAFFIC_MGT_SO_BACKGROUND) { + if (so->so_traffic_mgt_flags & TRAFFIC_MGT_SO_BG_REGULATE) { tcpstat.tcps_bg_rcvtotal++; /* Take snapshots of pkts recv; @@ -1664,12 +1678,7 @@ findpcb: switch (tp->t_state) { /* - * If the state is LISTEN then ignore segment if it contains an RST. - * If the segment contains an ACK then it is bad and send a RST. - * If it does not contain a SYN then it is not interesting; drop it. - * If it is from this socket, drop it, it must be forged. - * Don't bother responding if the destination was a broadcast. - * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial + * Initialize tp->rcv_nxt, and tp->irs, select an initial * tp->iss, and send a segment: * * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. @@ -1686,47 +1695,6 @@ findpcb: #if 1 lck_mtx_assert(((struct inpcb *)so->so_pcb)->inpcb_mtx, LCK_MTX_ASSERT_OWNED); #endif - if (thflags & TH_RST) - goto drop; - if (thflags & TH_ACK) { - rstreason = BANDLIM_RST_OPENPORT; - goto dropwithreset; - } - if ((thflags & TH_SYN) == 0) - goto drop; - if (th->th_dport == th->th_sport) { -#if INET6 - if (isipv6) { - if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, - &ip6->ip6_src)) - goto drop; - } else -#endif /* INET6 */ - if (ip->ip_dst.s_addr == ip->ip_src.s_addr) - goto drop; - } - /* - * 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; -#if 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)) || - ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || - in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) - goto drop; #if INET6 if (isipv6) { MALLOC(sin6, struct sockaddr_in6 *, sizeof *sin6,