svn commit: r201128 - in stable/8/sys: kern net netinet netinet6 sys

Bjoern A. Zeeb bz at FreeBSD.org
Mon Dec 28 14:40:59 UTC 2009


Author: bz
Date: Mon Dec 28 14:40:58 2009
New Revision: 201128
URL: http://svn.freebsd.org/changeset/base/201128

Log:
  MFC r200473:
  
    Throughout the network stack we have a few places of
          if (jailed(cred))
    left.  If you are running with a vnet (virtual network stack) those will
    return true and defer you to classic IP-jails handling and thus things
    will be "denied" or returned with an error.
  
    Work around this problem by introducing another "jailed()" function,
    jailed_without_vnet(), that also takes vnets into account, and permits
    the calls, should the jail from the given cred have its own virtual
    network stack.
  
    We cannot change the classic jailed() call to do that,  as it is used
    outside the network stack as well.
  
    Discussed with:       julian, zec, jamie, rwatson (back in Sept)

Modified:
  stable/8/sys/kern/kern_jail.c
  stable/8/sys/net/rtsock.c
  stable/8/sys/netinet/raw_ip.c
  stable/8/sys/netinet6/raw_ip6.c
  stable/8/sys/sys/jail.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/kern/kern_jail.c
==============================================================================
--- stable/8/sys/kern/kern_jail.c	Mon Dec 28 14:39:21 2009	(r201127)
+++ stable/8/sys/kern/kern_jail.c	Mon Dec 28 14:40:58 2009	(r201128)
@@ -3161,7 +3161,7 @@ prison_check_af(struct ucred *cred, int 
 	pr = cred->cr_prison;
 #ifdef VIMAGE
 	/* Prisons with their own network stack are not limited. */
-	if (pr->pr_flags & PR_VNET)
+	if (prison_owns_vnet(cred))
 		return (0);
 #endif
 
@@ -3222,6 +3222,11 @@ prison_if(struct ucred *cred, struct soc
 	KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
 	KASSERT(sa != NULL, ("%s: sa is NULL", __func__));
 
+#ifdef VIMAGE
+	if (prison_owns_vnet(cred))
+		return (0);
+#endif
+
 	error = 0;
 	switch (sa->sa_family)
 	{
@@ -3279,6 +3284,24 @@ jailed(struct ucred *cred)
 }
 
 /*
+ * Return 1 if the passed credential is in a jail and that jail does not
+ * have its own virtual network stack, otherwise 0.
+ */
+int
+jailed_without_vnet(struct ucred *cred)
+{
+
+	if (!jailed(cred))
+		return (0);
+#ifdef VIMAGE
+	if (prison_owns_vnet(cred))
+		return (0);
+#endif
+
+	return (1);
+}
+
+/*
  * Return the correct hostname (domainname, et al) for the passed credential.
  */
 void

Modified: stable/8/sys/net/rtsock.c
==============================================================================
--- stable/8/sys/net/rtsock.c	Mon Dec 28 14:39:21 2009	(r201127)
+++ stable/8/sys/net/rtsock.c	Mon Dec 28 14:40:58 2009	(r201128)
@@ -651,7 +651,7 @@ route_output(struct mbuf *m, struct sock
 		report:
 			RT_LOCK_ASSERT(rt);
 			if ((rt->rt_flags & RTF_HOST) == 0
-			    ? jailed(curthread->td_ucred)
+			    ? jailed_without_vnet(curthread->td_ucred)
 			    : prison_if(curthread->td_ucred,
 			    rt_key(rt)) != 0) {
 				RT_UNLOCK(rt);
@@ -1312,7 +1312,7 @@ sysctl_dumpentry(struct radix_node *rn, 
 	if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
 		return 0;
 	if ((rt->rt_flags & RTF_HOST) == 0
-	    ? jailed(w->w_req->td->td_ucred)
+	    ? jailed_without_vnet(w->w_req->td->td_ucred)
 	    : prison_if(w->w_req->td->td_ucred, rt_key(rt)) != 0)
 		return (0);
 	bzero((caddr_t)&info, sizeof(info));

Modified: stable/8/sys/netinet/raw_ip.c
==============================================================================
--- stable/8/sys/netinet/raw_ip.c	Mon Dec 28 14:39:21 2009	(r201127)
+++ stable/8/sys/netinet/raw_ip.c	Mon Dec 28 14:40:58 2009	(r201128)
@@ -291,7 +291,7 @@ rip_input(struct mbuf *m, int off)
 			continue;
 		if (inp->inp_faddr.s_addr != ip->ip_src.s_addr)
 			continue;
-		if (jailed(inp->inp_cred)) {
+		if (jailed_without_vnet(inp->inp_cred)) {
 			/*
 			 * XXX: If faddr was bound to multicast group,
 			 * jailed raw socket will drop datagram.
@@ -325,7 +325,7 @@ rip_input(struct mbuf *m, int off)
 		if (!in_nullhost(inp->inp_faddr) &&
 		    !in_hosteq(inp->inp_faddr, ip->ip_src))
 			continue;
-		if (jailed(inp->inp_cred)) {
+		if (jailed_without_vnet(inp->inp_cred)) {
 			/*
 			 * Allow raw socket in jail to receive multicast;
 			 * assume process had PRIV_NETINET_RAW at attach,

Modified: stable/8/sys/netinet6/raw_ip6.c
==============================================================================
--- stable/8/sys/netinet6/raw_ip6.c	Mon Dec 28 14:39:21 2009	(r201127)
+++ stable/8/sys/netinet6/raw_ip6.c	Mon Dec 28 14:40:58 2009	(r201128)
@@ -184,7 +184,7 @@ rip6_input(struct mbuf **mp, int *offp, 
 		if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
 		    !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))
 			continue;
-		if (jailed(in6p->inp_cred)) {
+		if (jailed_without_vnet(in6p->inp_cred)) {
 			/*
 			 * Allow raw socket in jail to receive multicast;
 			 * assume process had PRIV_NETINET_RAW at attach,

Modified: stable/8/sys/sys/jail.h
==============================================================================
--- stable/8/sys/sys/jail.h	Mon Dec 28 14:39:21 2009	(r201127)
+++ stable/8/sys/sys/jail.h	Mon Dec 28 14:40:58 2009	(r201128)
@@ -335,6 +335,7 @@ struct mount;
 struct sockaddr;
 struct statfs;
 int jailed(struct ucred *cred);
+int jailed_without_vnet(struct ucred *);
 void getcredhostname(struct ucred *, char *, size_t);
 void getcreddomainname(struct ucred *, char *, size_t);
 void getcredhostuuid(struct ucred *, char *, size_t);


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