git: f71cb9f74808 - main - tcp: inp_socket is valid through the lifetime of a TCP inpcb
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 08 Nov 2022 18:24:56 UTC
The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=f71cb9f74808facc9d3e6854f96da2afbed8a1e3 commit f71cb9f74808facc9d3e6854f96da2afbed8a1e3 Author: Gleb Smirnoff <glebius@FreeBSD.org> AuthorDate: 2022-11-08 18:24:39 +0000 Commit: Gleb Smirnoff <glebius@FreeBSD.org> CommitDate: 2022-11-08 18:24:39 +0000 tcp: inp_socket is valid through the lifetime of a TCP inpcb The inp_socket is cleared only in in_pcbdetach(), which for TCP is always accompanied with inp_pcbfree(). An inpcb that went through in_pcbfree() shall never be returned by any kind of pcb lookup. Reviewed by: tuexen Differential revision: https://reviews.freebsd.org/D37062 --- sys/netinet/tcp_input.c | 2 +- sys/netinet/tcp_subr.c | 177 ++++++++++++++++++++++-------------------------- sys/netinet/tcp_timer.c | 2 + 3 files changed, 83 insertions(+), 98 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index eeed49681ec6..ad399b9042e2 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -940,7 +940,7 @@ findpcb: if ((inp->inp_flowtype == M_HASHTYPE_NONE) && (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) && - ((inp->inp_socket == NULL) || !SOLISTENING(inp->inp_socket))) { + !SOLISTENING(inp->inp_socket)) { inp->inp_flowid = m->m_pkthdr.flowid; inp->inp_flowtype = M_HASHTYPE_GET(m); } diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 999f52c9a339..e159bf81208b 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -2730,8 +2730,6 @@ tcp_getcred(SYSCTL_HANDLER_ARGS) addrs[0].sin_addr, addrs[0].sin_port, INPLOOKUP_RLOCKPCB, NULL); NET_EPOCH_EXIT(et); if (inp != NULL) { - if (inp->inp_socket == NULL) - error = ENOENT; if (error == 0) error = cr_canseeinpcb(req->td->td_ucred, inp); if (error == 0) @@ -2798,8 +2796,6 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS) INPLOOKUP_RLOCKPCB, NULL); NET_EPOCH_EXIT(et); if (inp != NULL) { - if (inp->inp_socket == NULL) - error = ENOENT; if (error == 0) error = cr_canseeinpcb(req->td->td_ucred, inp); if (error == 0) @@ -2875,47 +2871,44 @@ tcp_ctlinput_with_port(struct icmp *icp, uint16_t port) inp = in_pcblookup(&V_tcbinfo, ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport, INPLOOKUP_WLOCKPCB, NULL); if (inp != NULL) { - if (inp->inp_socket != NULL) { - tp = intotcpcb(inp); + tp = intotcpcb(inp); #ifdef TCP_OFFLOAD - if (tp->t_flags & TF_TOE && errno == EMSGSIZE) { + if (tp->t_flags & TF_TOE && errno == EMSGSIZE) { + /* + * MTU discovery for offloaded connections. Let + * the TOE driver verify seq# and process it. + */ + mtu = tcp_next_pmtu(icp, ip); + tcp_offload_pmtu_update(tp, icmp_tcp_seq, mtu); + goto out; + } +#endif + if (tp->t_port != port) + goto out; + if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) && + SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) { + if (errno == EMSGSIZE) { /* - * MTU discovery for offloaded connections. Let - * the TOE driver verify seq# and process it. + * MTU discovery: we got a needfrag and + * will potentially try a lower MTU. */ mtu = tcp_next_pmtu(icp, ip); - tcp_offload_pmtu_update(tp, icmp_tcp_seq, mtu); - goto out; - } -#endif - if (tp->t_port != port) { - goto out; - } - if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) && - SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) { - if (errno == EMSGSIZE) { - /* - * MTU discovery: we got a needfrag and - * will potentially try a lower MTU. - */ - mtu = tcp_next_pmtu(icp, ip); - - /* - * Only process the offered MTU if it - * is smaller than the current one. - */ - if (mtu < tp->t_maxseg + - sizeof(struct tcpiphdr)) { - bzero(&inc, sizeof(inc)); - inc.inc_faddr = ip->ip_dst; - inc.inc_fibnum = - inp->inp_inc.inc_fibnum; - tcp_hc_updatemtu(&inc, mtu); - inp = tcp_mtudisc(inp, mtu); - } - } else - inp = (*notify)(inp, errno); - } + + /* + * Only process the offered MTU if it + * is smaller than the current one. + */ + if (mtu < tp->t_maxseg + + sizeof(struct tcpiphdr)) { + bzero(&inc, sizeof(inc)); + inc.inc_faddr = ip->ip_dst; + inc.inc_fibnum = + inp->inp_inc.inc_fibnum; + tcp_hc_updatemtu(&inc, mtu); + inp = tcp_mtudisc(inp, mtu); + } + } else + inp = (*notify)(inp, errno); } } else { bzero(&inc, sizeof(inc)); @@ -3067,51 +3060,48 @@ tcp6_ctlinput_with_port(struct ip6ctlparam *ip6cp, uint16_t port) } m_copydata(m, off, sizeof(tcp_seq), (caddr_t)&icmp_tcp_seq); if (inp != NULL) { - if (inp->inp_socket != NULL) { - tp = intotcpcb(inp); + tp = intotcpcb(inp); #ifdef TCP_OFFLOAD - if (tp->t_flags & TF_TOE && errno == EMSGSIZE) { - /* MTU discovery for offloaded connections. */ - mtu = tcp6_next_pmtu(icmp6); - tcp_offload_pmtu_update(tp, icmp_tcp_seq, mtu); - goto out; - } + if (tp->t_flags & TF_TOE && errno == EMSGSIZE) { + /* MTU discovery for offloaded connections. */ + mtu = tcp6_next_pmtu(icmp6); + tcp_offload_pmtu_update(tp, icmp_tcp_seq, mtu); + goto out; + } #endif - if (tp->t_port != port) { - goto out; - } - if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) && - SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) { - if (errno == EMSGSIZE) { - /* - * MTU discovery: - * If we got a needfrag set the MTU - * in the route to the suggested new - * value (if given) and then notify. - */ - mtu = tcp6_next_pmtu(icmp6); + if (tp->t_port != port) + goto out; + if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) && + SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) { + if (errno == EMSGSIZE) { + /* + * MTU discovery: + * If we got a needfrag set the MTU + * in the route to the suggested new + * value (if given) and then notify. + */ + mtu = tcp6_next_pmtu(icmp6); - bzero(&inc, sizeof(inc)); - inc.inc_fibnum = M_GETFIB(m); - inc.inc_flags |= INC_ISIPV6; - inc.inc6_faddr = *dst; - if (in6_setscope(&inc.inc6_faddr, - m->m_pkthdr.rcvif, NULL)) - goto out; - /* - * Only process the offered MTU if it - * is smaller than the current one. - */ - if (mtu < tp->t_maxseg + - sizeof (struct tcphdr) + - sizeof (struct ip6_hdr)) { - tcp_hc_updatemtu(&inc, mtu); - tcp_mtudisc(inp, mtu); - ICMP6STAT_INC(icp6s_pmtuchg); - } - } else - inp = (*notify)(inp, errno); - } + bzero(&inc, sizeof(inc)); + inc.inc_fibnum = M_GETFIB(m); + inc.inc_flags |= INC_ISIPV6; + inc.inc6_faddr = *dst; + if (in6_setscope(&inc.inc6_faddr, + m->m_pkthdr.rcvif, NULL)) + goto out; + /* + * Only process the offered MTU if it + * is smaller than the current one. + */ + if (mtu < tp->t_maxseg + + sizeof (struct tcphdr) + + sizeof (struct ip6_hdr)) { + tcp_hc_updatemtu(&inc, mtu); + tcp_mtudisc(inp, mtu); + ICMP6STAT_INC(icp6s_pmtuchg); + } + } else + inp = (*notify)(inp, errno); } } else { bzero(&inc, sizeof(inc)); @@ -3806,19 +3796,14 @@ sysctl_switch_tls(SYSCTL_HANDLER_ARGS) } NET_EPOCH_EXIT(et); if (inp != NULL) { - if (inp->inp_socket == NULL) { - error = ECONNRESET; - INP_WUNLOCK(inp); - } else { - struct socket *so; + struct socket *so; - so = inp->inp_socket; - soref(so); - error = ktls_set_tx_mode(so, - arg2 == 0 ? TCP_TLS_MODE_SW : TCP_TLS_MODE_IFNET); - INP_WUNLOCK(inp); - sorele(so); - } + so = inp->inp_socket; + soref(so); + error = ktls_set_tx_mode(so, + arg2 == 0 ? TCP_TLS_MODE_SW : TCP_TLS_MODE_IFNET); + INP_WUNLOCK(inp); + sorele(so); } else error = ESRCH; return (error); @@ -4025,8 +4010,6 @@ tcp_inptoxtp(const struct inpcb *inp, struct xtcpcb *xt) xt->xt_len = sizeof(struct xtcpcb); in_pcbtoxinpcb(inp, &xt->xt_inp); - if (inp->inp_socket == NULL) - xt->xt_inp.xi_socket.xso_protocol = IPPROTO_TCP; } void diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 391b9dfdbc05..bbf5331c1d7d 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -351,6 +351,8 @@ tcp_timer_2msl(void *xtp) * If fastrecycle of FIN_WAIT_2, in FIN_WAIT_2 and receiver has closed, * there's no point in hanging onto FIN_WAIT_2 socket. Just close it. * Ignore fact that there were recent incoming segments. + * + * XXXGL: check if inp_socket shall always be !NULL here? */ if (tp->t_state == TCPS_TIME_WAIT) { tcp_timer_close(tp);