svn commit: r354477 - in head/sys: netinet netinet6
Gleb Smirnoff
glebius at FreeBSD.org
Thu Nov 7 20:49:57 UTC 2019
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)
More information about the svn-src-all
mailing list