Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Nov 2019 20:49:56 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354477 - in head/sys: netinet netinet6
Message-ID:  <201911072049.xA7Knu4I072521@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Thu Nov  7 20:49:56 2019
New Revision: 354477
URL: https://svnweb.freebsd.org/changeset/base/354477

Log:
  Since r353292 on input path we are always in network epoch, when
  we lookup PCBs.  Thus, do not enter epoch recursively in
  in_pcblookup_hash() and in6_pcblookup_hash().  Same applies to
  tcp_ctlinput() and tcp6_ctlinput().
  
  This leaves several sysctl(9) handlers that return PCB credentials
  unprotected.  Add epoch enter/exit to all of them.
  
  Differential Revision:	https://reviews.freebsd.org/D22197

Modified:
  head/sys/netinet/in_pcb.c
  head/sys/netinet/tcp_subr.c
  head/sys/netinet/udp_usrreq.c
  head/sys/netinet6/in6_pcb.c
  head/sys/netinet6/udp6_usrreq.c

Modified: head/sys/netinet/in_pcb.c
==============================================================================
--- head/sys/netinet/in_pcb.c	Thu Nov  7 20:44:34 2019	(r354476)
+++ head/sys/netinet/in_pcb.c	Thu Nov  7 20:49:56 2019	(r354477)
@@ -2252,12 +2252,10 @@ in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, st
 	struct inpcb *inp, *tmpinp;
 	u_short fport = fport_arg, lport = lport_arg;
 
-#ifdef INVARIANTS
 	KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
 	    ("%s: invalid lookup flags %d", __func__, lookupflags));
-	if (!mtx_owned(&pcbinfo->ipi_hash_lock))
-		MPASS(in_epoch_verbose(net_epoch_preempt, 1));
-#endif
+	INP_HASH_LOCK_ASSERT(pcbinfo);
+
 	/*
 	 * First look for an exact match.
 	 */
@@ -2384,7 +2382,6 @@ in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in
 {
 	struct inpcb *inp;
 
-	INP_HASH_RLOCK(pcbinfo);
 	inp = in_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport,
 	    (lookupflags & ~(INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)), ifp);
 	if (inp != NULL) {
@@ -2411,7 +2408,7 @@ in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in
 		}
 #endif
 	}
-	INP_HASH_RUNLOCK(pcbinfo);
+
 	return (inp);
 }
 

Modified: head/sys/netinet/tcp_subr.c
==============================================================================
--- head/sys/netinet/tcp_subr.c	Thu Nov  7 20:44:34 2019	(r354476)
+++ head/sys/netinet/tcp_subr.c	Thu Nov  7 20:49:56 2019	(r354477)
@@ -2257,6 +2257,7 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
 {
 	struct xucred xuc;
 	struct sockaddr_in addrs[2];
+	struct epoch_tracker et;
 	struct inpcb *inp;
 	int error;
 
@@ -2266,8 +2267,10 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
 	error = SYSCTL_IN(req, addrs, sizeof(addrs));
 	if (error)
 		return (error);
+	NET_EPOCH_ENTER(et);
 	inp = in_pcblookup(&V_tcbinfo, addrs[1].sin_addr, addrs[1].sin_port,
 	    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;
@@ -2292,6 +2295,7 @@ SYSCTL_PROC(_net_inet_tcp, OID_AUTO, getcred,
 static int
 tcp6_getcred(SYSCTL_HANDLER_ARGS)
 {
+	struct epoch_tracker et;
 	struct xucred xuc;
 	struct sockaddr_in6 addrs[2];
 	struct inpcb *inp;
@@ -2319,6 +2323,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
 			return (EINVAL);
 	}
 
+	NET_EPOCH_ENTER(et);
 #ifdef INET
 	if (mapped == 1)
 		inp = in_pcblookup(&V_tcbinfo,
@@ -2332,6 +2337,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
 			&addrs[1].sin6_addr, addrs[1].sin6_port,
 			&addrs[0].sin6_addr, addrs[0].sin6_port,
 			INPLOOKUP_RLOCKPCB, NULL);
+	NET_EPOCH_EXIT(et);
 	if (inp != NULL) {
 		if (inp->inp_socket == NULL)
 			error = ENOENT;
@@ -2365,7 +2371,6 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 	struct inpcb *(*notify)(struct inpcb *, int) = tcp_notify;
 	struct icmp *icp;
 	struct in_conninfo inc;
-	struct epoch_tracker et;
 	tcp_seq icmp_tcp_seq;
 	int mtu;
 
@@ -2397,7 +2402,6 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 
 	icp = (struct icmp *)((caddr_t)ip - offsetof(struct icmp, icmp_ip));
 	th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
-	INP_INFO_RLOCK_ET(&V_tcbinfo, et);
 	inp = in_pcblookup(&V_tcbinfo, faddr, th->th_dport, ip->ip_src,
 	    th->th_sport, INPLOOKUP_WLOCKPCB, NULL);
 	if (inp != NULL && PRC_IS_REDIRECT(cmd)) {
@@ -2462,7 +2466,6 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 out:
 	if (inp != NULL)
 		INP_WUNLOCK(inp);
-	INP_INFO_RUNLOCK_ET(&V_tcbinfo, et);
 }
 #endif /* INET */
 
@@ -2480,7 +2483,6 @@ tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
 	struct ip6ctlparam *ip6cp = NULL;
 	const struct sockaddr_in6 *sa6_src = NULL;
 	struct in_conninfo inc;
-	struct epoch_tracker et;
 	struct tcp_ports {
 		uint16_t th_sport;
 		uint16_t th_dport;
@@ -2542,7 +2544,6 @@ tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
 	}
 	bzero(&t_ports, sizeof(struct tcp_ports));
 	m_copydata(m, off, sizeof(struct tcp_ports), (caddr_t)&t_ports);
-	INP_INFO_RLOCK_ET(&V_tcbinfo, et);
 	inp = in6_pcblookup(&V_tcbinfo, &ip6->ip6_dst, t_ports.th_dport,
 	    &ip6->ip6_src, t_ports.th_sport, INPLOOKUP_WLOCKPCB, NULL);
 	if (inp != NULL && PRC_IS_REDIRECT(cmd)) {
@@ -2614,7 +2615,6 @@ tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
 out:
 	if (inp != NULL)
 		INP_WUNLOCK(inp);
-	INP_INFO_RUNLOCK_ET(&V_tcbinfo, et);
 }
 #endif /* INET6 */
 

Modified: head/sys/netinet/udp_usrreq.c
==============================================================================
--- head/sys/netinet/udp_usrreq.c	Thu Nov  7 20:44:34 2019	(r354476)
+++ head/sys/netinet/udp_usrreq.c	Thu Nov  7 20:49:56 2019	(r354477)
@@ -963,6 +963,7 @@ udp_getcred(SYSCTL_HANDLER_ARGS)
 {
 	struct xucred xuc;
 	struct sockaddr_in addrs[2];
+	struct epoch_tracker et;
 	struct inpcb *inp;
 	int error;
 
@@ -972,9 +973,11 @@ udp_getcred(SYSCTL_HANDLER_ARGS)
 	error = SYSCTL_IN(req, addrs, sizeof(addrs));
 	if (error)
 		return (error);
+	NET_EPOCH_ENTER(et);
 	inp = in_pcblookup(&V_udbinfo, addrs[1].sin_addr, addrs[1].sin_port,
 	    addrs[0].sin_addr, addrs[0].sin_port,
 	    INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL);
+	NET_EPOCH_EXIT(et);
 	if (inp != NULL) {
 		INP_RLOCK_ASSERT(inp);
 		if (inp->inp_socket == NULL)

Modified: head/sys/netinet6/in6_pcb.c
==============================================================================
--- head/sys/netinet6/in6_pcb.c	Thu Nov  7 20:44:34 2019	(r354476)
+++ head/sys/netinet6/in6_pcb.c	Thu Nov  7 20:49:56 2019	(r354477)
@@ -1245,7 +1245,6 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct i
 {
 	struct inpcb *inp;
 
-	INP_HASH_RLOCK(pcbinfo);
 	inp = in6_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport,
 	    (lookupflags & ~(INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)), ifp);
 	if (inp != NULL) {
@@ -1272,7 +1271,6 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct i
 		}
 #endif
 	}
-	INP_HASH_RUNLOCK(pcbinfo);
 	return (inp);
 }
 

Modified: head/sys/netinet6/udp6_usrreq.c
==============================================================================
--- head/sys/netinet6/udp6_usrreq.c	Thu Nov  7 20:44:34 2019	(r354476)
+++ head/sys/netinet6/udp6_usrreq.c	Thu Nov  7 20:49:56 2019	(r354477)
@@ -634,6 +634,7 @@ udp6_getcred(SYSCTL_HANDLER_ARGS)
 {
 	struct xucred xuc;
 	struct sockaddr_in6 addrs[2];
+	struct epoch_tracker et;
 	struct inpcb *inp;
 	int error;
 
@@ -652,9 +653,11 @@ udp6_getcred(SYSCTL_HANDLER_ARGS)
 	    (error = sa6_embedscope(&addrs[1], V_ip6_use_defzone)) != 0) {
 		return (error);
 	}
+	NET_EPOCH_ENTER(et);
 	inp = in6_pcblookup(&V_udbinfo, &addrs[1].sin6_addr,
 	    addrs[1].sin6_port, &addrs[0].sin6_addr, addrs[0].sin6_port,
 	    INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL);
+	NET_EPOCH_EXIT(et);
 	if (inp != NULL) {
 		INP_RLOCK_ASSERT(inp);
 		if (inp->inp_socket == NULL)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911072049.xA7Knu4I072521>