svn commit: r184481 - in stable/7/sys: . contrib/pf/net netinet netinet6

Bjoern A. Zeeb bz at FreeBSD.org
Thu Oct 30 09:29:05 PDT 2008


Author: bz
Date: Thu Oct 30 16:29:04 2008
New Revision: 184481
URL: http://svn.freebsd.org/changeset/base/184481

Log:
  MFC: r183606, r183610
  
    Cache so_cred as inp_cred in the inpcb.
    This means that inp_cred is always there, even after the socket
    has gone away. It also means that it is constant for the lifetime
    of the inp.
    Both facts lead to simpler code and possibly less locking.
  
  Approved by:	re (gnn)

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/net/pf.c
  stable/7/sys/netinet/in_pcb.c
  stable/7/sys/netinet/in_pcb.h
  stable/7/sys/netinet/ip_fw2.c
  stable/7/sys/netinet/raw_ip.c
  stable/7/sys/netinet/tcp_subr.c
  stable/7/sys/netinet/udp_usrreq.c
  stable/7/sys/netinet6/in6_pcb.c
  stable/7/sys/netinet6/udp6_usrreq.c

Modified: stable/7/sys/contrib/pf/net/pf.c
==============================================================================
--- stable/7/sys/contrib/pf/net/pf.c	Thu Oct 30 16:22:04 2008	(r184480)
+++ stable/7/sys/contrib/pf/net/pf.c	Thu Oct 30 16:29:04 2008	(r184481)
@@ -2938,13 +2938,9 @@ pf_socket_lookup(int direction, struct p
 #ifdef __FreeBSD__
 	if (inp_arg != NULL) {
 		INP_LOCK_ASSERT(inp_arg);
-		if (inp_arg->inp_socket) {
-			pd->lookup.uid = inp_arg->inp_socket->so_cred->cr_uid;
-			pd->lookup.gid =
-			    inp_arg->inp_socket->so_cred->cr_groups[0];
-			return (1);
-		} else
-			return (-1);
+		pd->lookup.uid = inp_arg->inp_cred->cr_uid;
+		pd->lookup.gid = inp_arg->inp_cred->cr_groups[0];
+		return (1);
 	}
 #endif
 	switch (pd->proto) {
@@ -3040,15 +3036,9 @@ pf_socket_lookup(int direction, struct p
 		return (-1);
 	}
 #ifdef __FreeBSD__
-	INP_RLOCK(inp);
+	pd->lookup.uid = inp->inp_cred->cr_uid;
+	pd->lookup.gid = inp->inp_cred->cr_groups[0];
 	INP_INFO_RUNLOCK(pi);
-	if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) {
-		INP_RUNLOCK(inp);
-		return (-1);
-	}
-	pd->lookup.uid = inp->inp_socket->so_cred->cr_uid;
-	pd->lookup.gid = inp->inp_socket->so_cred->cr_groups[0];
-	INP_RUNLOCK(inp);
 #else
 	pd->lookup.uid = inp->inp_socket->so_euid;
 	pd->lookup.gid = inp->inp_socket->so_egid;

Modified: stable/7/sys/netinet/in_pcb.c
==============================================================================
--- stable/7/sys/netinet/in_pcb.c	Thu Oct 30 16:22:04 2008	(r184480)
+++ stable/7/sys/netinet/in_pcb.c	Thu Oct 30 16:29:04 2008	(r184481)
@@ -186,6 +186,7 @@ in_pcballoc(struct socket *so, struct in
 	bzero(inp, inp_zero_size);
 	inp->inp_pcbinfo = pcbinfo;
 	inp->inp_socket = so;
+	inp->inp_cred = crhold(so->so_cred);
 	inp->inp_inc.inc_fibnum = so->so_fibnum;
 #ifdef MAC
 	error = mac_init_inpcb(inp, M_NOWAIT);
@@ -224,8 +225,10 @@ in_pcballoc(struct socket *so, struct in
 
 #if defined(IPSEC) || defined(MAC)
 out:
-	if (error != 0)
+	if (error != 0) {
+		crfree(inp->inp_cred);
 		uma_zfree(pcbinfo->ipi_zone, inp);
+	}
 #endif
 	return (error);
 }
@@ -345,7 +348,7 @@ in_pcbbind_setup(struct inpcb *inp, stru
 			if (jailed(cred))
 				prison = 1;
 			if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) &&
-			    priv_check_cred(so->so_cred,
+			    priv_check_cred(inp->inp_cred,
 			    PRIV_NETINET_REUSEPORT, 0) != 0) {
 				t = in_pcblookup_local(pcbinfo, sin->sin_addr,
 				    lport, prison ? 0 : INPLOOKUP_WILDCARD,
@@ -362,8 +365,8 @@ in_pcbbind_setup(struct inpcb *inp, stru
 				     ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
 				     (t->inp_socket->so_options &
 					 SO_REUSEPORT) == 0) &&
-				    (so->so_cred->cr_uid !=
-				     t->inp_socket->so_cred->cr_uid))
+				    (inp->inp_cred->cr_uid !=
+				     t->inp_cred->cr_uid))
 					return (EADDRINUSE);
 			}
 			if (prison && prison_ip(cred, 0, &sin->sin_addr.s_addr))
@@ -745,6 +748,7 @@ in_pcbfree(struct inpcb *inp)
 	if (inp->inp_moptions != NULL)
 		inp_freemoptions(inp->inp_moptions);
 	inp->inp_vflag = 0;
+	crfree(inp->inp_cred);
 
 #ifdef MAC
 	mac_destroy_inpcb(inp);

Modified: stable/7/sys/netinet/in_pcb.h
==============================================================================
--- stable/7/sys/netinet/in_pcb.h	Thu Oct 30 16:22:04 2008	(r184480)
+++ stable/7/sys/netinet/in_pcb.h	Thu Oct 30 16:29:04 2008	(r184481)
@@ -169,7 +169,8 @@ struct inpcb {
 	u_char	inp_ip_p;		/* (c) protocol proto */
 	u_char	inp_ip_minttl;		/* (i) minimum TTL or drop */
 	uint32_t inp_ispare1;		/* (x) connection id / queue id */
-	void	*inp_pspare[2];		/* (x) rtentry / general use */
+	void	*inp_pspare;		/* (x) rtentry / general use */
+	struct	ucred	*inp_cred;	/* (c) cache of socket cred */
 
 	/* Local and foreign ports, local and foreign addr. */
 	struct	in_conninfo inp_inc;

Modified: stable/7/sys/netinet/ip_fw2.c
==============================================================================
--- stable/7/sys/netinet/ip_fw2.c	Thu Oct 30 16:22:04 2008	(r184480)
+++ stable/7/sys/netinet/ip_fw2.c	Thu Oct 30 16:29:04 2008	(r184481)
@@ -1962,15 +1962,11 @@ fill_ugid_cache(struct inpcb *inp, struc
 {
 	struct ucred *cr;
 
-	if (inp->inp_socket != NULL) {
-		cr = inp->inp_socket->so_cred;
-		ugp->fw_prid = jailed(cr) ?
-		    cr->cr_prison->pr_id : -1;
-		ugp->fw_uid = cr->cr_uid;
-		ugp->fw_ngroups = cr->cr_ngroups;
-		bcopy(cr->cr_groups, ugp->fw_groups,
-		    sizeof(ugp->fw_groups));
-	}
+	cr = inp->inp_cred;
+	ugp->fw_prid = jailed(cr) ? cr->cr_prison->pr_id : -1;
+	ugp->fw_uid = cr->cr_uid;
+	ugp->fw_ngroups = cr->cr_ngroups;
+	bcopy(cr->cr_groups, ugp->fw_groups, sizeof(ugp->fw_groups));
 }
 
 static int
@@ -2026,12 +2022,8 @@ check_uidgid(ipfw_insn_u32 *insn, int pr
 				dst_ip, htons(dst_port),
 				wildcard, NULL);
 		if (pcb != NULL) {
-			INP_RLOCK(pcb);
-			if (pcb->inp_socket != NULL) {
-				fill_ugid_cache(pcb, ugp);
-				*ugid_lookupp = 1;
-			}
-			INP_RUNLOCK(pcb);
+			fill_ugid_cache(pcb, ugp);
+			*ugid_lookupp = 1;
 		}
 		INP_INFO_RUNLOCK(pi);
 		if (*ugid_lookupp == 0) {

Modified: stable/7/sys/netinet/raw_ip.c
==============================================================================
--- stable/7/sys/netinet/raw_ip.c	Thu Oct 30 16:22:04 2008	(r184480)
+++ stable/7/sys/netinet/raw_ip.c	Thu Oct 30 16:29:04 2008	(r184481)
@@ -257,6 +257,7 @@ rip_input(struct mbuf *m, int off)
 		if (inp->inp_ip_p != proto)
 			continue;
 #ifdef INET6
+		/* XXX inp locking */
 		if ((inp->inp_vflag & INP_IPV4) == 0)
 			continue;
 #endif
@@ -264,11 +265,9 @@ rip_input(struct mbuf *m, int off)
 			continue;
 		if (inp->inp_faddr.s_addr != ip->ip_src.s_addr)
 			continue;
-		INP_RLOCK(inp);
-		if (jailed(inp->inp_socket->so_cred) &&
-		    (htonl(prison_getip(inp->inp_socket->so_cred)) !=
+		if (jailed(inp->inp_cred) &&
+		    (htonl(prison_getip(inp->inp_cred)) !=
 		    ip->ip_dst.s_addr)) {
-			INP_RUNLOCK(inp);
 			continue;
 		}
 		if (last) {
@@ -280,12 +279,14 @@ rip_input(struct mbuf *m, int off)
 			/* XXX count dropped packet */
 			INP_RUNLOCK(last);
 		}
+		INP_RLOCK(inp);
 		last = inp;
 	}
 	LIST_FOREACH(inp, &ripcbinfo.ipi_hashbase[0], inp_hash) {
 		if (inp->inp_ip_p && inp->inp_ip_p != proto)
 			continue;
 #ifdef INET6
+		/* XXX inp locking */
 		if ((inp->inp_vflag & INP_IPV4) == 0)
 			continue;
 #endif
@@ -295,11 +296,9 @@ rip_input(struct mbuf *m, int off)
 		if (inp->inp_faddr.s_addr &&
 		    inp->inp_faddr.s_addr != ip->ip_src.s_addr)
 			continue;
-		INP_RLOCK(inp);
-		if (jailed(inp->inp_socket->so_cred) &&
-		    (htonl(prison_getip(inp->inp_socket->so_cred)) !=
+		if (jailed(inp->inp_cred) &&
+		    (htonl(prison_getip(inp->inp_cred)) !=
 		    ip->ip_dst.s_addr)) {
-			INP_RUNLOCK(inp);
 			continue;
 		}
 		if (last) {
@@ -311,6 +310,7 @@ rip_input(struct mbuf *m, int off)
 			/* XXX count dropped packet */
 			INP_RUNLOCK(last);
 		}
+		INP_RLOCK(inp);
 		last = inp;
 	}
 	INP_INFO_RUNLOCK(&ripcbinfo);
@@ -360,9 +360,9 @@ rip_output(struct mbuf *m, struct socket
 			ip->ip_off = 0;
 		ip->ip_p = inp->inp_ip_p;
 		ip->ip_len = m->m_pkthdr.len;
-		if (jailed(inp->inp_socket->so_cred))
+		if (jailed(inp->inp_cred))
 			ip->ip_src.s_addr =
-			    htonl(prison_getip(inp->inp_socket->so_cred));
+			    htonl(prison_getip(inp->inp_cred));
 		else
 			ip->ip_src = inp->inp_laddr;
 		ip->ip_dst.s_addr = dst;
@@ -374,9 +374,9 @@ rip_output(struct mbuf *m, struct socket
 		}
 		INP_RLOCK(inp);
 		ip = mtod(m, struct ip *);
-		if (jailed(inp->inp_socket->so_cred)) {
+		if (jailed(inp->inp_cred)) {
 			if (ip->ip_src.s_addr !=
-			    htonl(prison_getip(inp->inp_socket->so_cred))) {
+			    htonl(prison_getip(inp->inp_cred))) {
 				INP_RUNLOCK(inp);
 				m_freem(m);
 				return (EPERM);

Modified: stable/7/sys/netinet/tcp_subr.c
==============================================================================
--- stable/7/sys/netinet/tcp_subr.c	Thu Oct 30 16:22:04 2008	(r184480)
+++ stable/7/sys/netinet/tcp_subr.c	Thu Oct 30 16:29:04 2008	(r184481)
@@ -1047,7 +1047,7 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
 			error = cr_canseesocket(req->td->td_ucred,
 			    inp->inp_socket);
 		if (error == 0)
-			cru2x(inp->inp_socket->so_cred, &xuc);
+			cru2x(inp->inp_cred, &xuc);
 		INP_RUNLOCK(inp);
 	} else {
 		INP_INFO_RUNLOCK(&tcbinfo);
@@ -1109,7 +1109,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
 			error = cr_canseesocket(req->td->td_ucred,
 			    inp->inp_socket);
 		if (error == 0)
-			cru2x(inp->inp_socket->so_cred, &xuc);
+			cru2x(inp->inp_cred, &xuc);
 		INP_RUNLOCK(inp);
 	} else {
 		INP_INFO_RUNLOCK(&tcbinfo);

Modified: stable/7/sys/netinet/udp_usrreq.c
==============================================================================
--- stable/7/sys/netinet/udp_usrreq.c	Thu Oct 30 16:22:04 2008	(r184480)
+++ stable/7/sys/netinet/udp_usrreq.c	Thu Oct 30 16:29:04 2008	(r184481)
@@ -768,7 +768,7 @@ udp_getcred(SYSCTL_HANDLER_ARGS)
 			error = cr_canseesocket(req->td->td_ucred,
 			    inp->inp_socket);
 		if (error == 0)
-			cru2x(inp->inp_socket->so_cred, &xuc);
+			cru2x(inp->inp_cred, &xuc);
 		INP_RUNLOCK(inp);
 	} else {
 		INP_INFO_RUNLOCK(&udbinfo);

Modified: stable/7/sys/netinet6/in6_pcb.c
==============================================================================
--- stable/7/sys/netinet6/in6_pcb.c	Thu Oct 30 16:22:04 2008	(r184480)
+++ stable/7/sys/netinet6/in6_pcb.c	Thu Oct 30 16:29:04 2008	(r184481)
@@ -185,7 +185,7 @@ in6_pcbbind(register struct inpcb *inp, 
 			    0))
 				return (EACCES);
 			if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) &&
-			    priv_check_cred(so->so_cred,
+			    priv_check_cred(inp->inp_cred,
 			    PRIV_NETINET_REUSEPORT, 0) != 0) {
 				t = in6_pcblookup_local(pcbinfo,
 				    &sin6->sin6_addr, lport,
@@ -197,8 +197,8 @@ in6_pcbbind(register struct inpcb *inp, 
 				    (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
 				     !IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) ||
 				     (t->inp_socket->so_options & SO_REUSEPORT)
-				      == 0) && (so->so_cred->cr_uid !=
-				     t->inp_socket->so_cred->cr_uid))
+				      == 0) && (inp->inp_cred->cr_uid !=
+				     t->inp_cred->cr_uid))
 					return (EADDRINUSE);
 				if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
 				    IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
@@ -214,8 +214,8 @@ in6_pcbbind(register struct inpcb *inp, 
 					    (so->so_type != SOCK_STREAM ||
 					     ntohl(t->inp_faddr.s_addr) ==
 					      INADDR_ANY) &&
-					    (so->so_cred->cr_uid !=
-					     t->inp_socket->so_cred->cr_uid))
+					    (inp->inp_cred->cr_uid !=
+					     t->inp_cred->cr_uid))
 						return (EADDRINUSE);
 				}
 			}
@@ -317,7 +317,7 @@ in6_pcbladdr(register struct inpcb *inp,
 	 */
 	*plocal_addr6 = in6_selectsrc(sin6, inp->in6p_outputopts,
 				      inp, NULL,
-				      inp->inp_socket->so_cred,
+				      inp->inp_cred,
 				      &ifp, &error);
 	if (ifp && scope_ambiguous &&
 	    (error = in6_setscope(&sin6->sin6_addr, ifp, NULL)) != 0) {

Modified: stable/7/sys/netinet6/udp6_usrreq.c
==============================================================================
--- stable/7/sys/netinet6/udp6_usrreq.c	Thu Oct 30 16:22:04 2008	(r184480)
+++ stable/7/sys/netinet6/udp6_usrreq.c	Thu Oct 30 16:29:04 2008	(r184481)
@@ -458,7 +458,7 @@ udp6_getcred(SYSCTL_HANDLER_ARGS)
 			error = cr_canseesocket(req->td->td_ucred,
 			    inp->inp_socket);
 		if (error == 0)
-			cru2x(inp->inp_socket->so_cred, &xuc);
+			cru2x(inp->inp_cred, &xuc);
 		INP_RUNLOCK(inp);
 	} else {
 		INP_INFO_RUNLOCK(&udbinfo);


More information about the svn-src-stable-7 mailing list