Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/freebsd/freebsd-src.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2022-11-08 21:24:39 +0300
committerGleb Smirnoff <glebius@FreeBSD.org>2022-11-08 21:24:39 +0300
commitf71cb9f74808facc9d3e6854f96da2afbed8a1e3 (patch)
tree3672f8a8dd2b8f1ada9c27d8df4f32cc4e0c05c8 /sys
parentada90cb978e14fdb539fb7c3557f1e9e4f9acdcb (diff)
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
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/tcp_input.c2
-rw-r--r--sys/netinet/tcp_subr.c177
-rw-r--r--sys/netinet/tcp_timer.c2
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);