svn commit: r188144 - in head: lib/libc/sys sys/kern sys/net sys/netinet sys/netinet6

Jamie Gritton jamie at FreeBSD.org
Thu Feb 5 06:06:11 PST 2009


Author: jamie
Date: Thu Feb  5 14:06:09 2009
New Revision: 188144
URL: http://svn.freebsd.org/changeset/base/188144

Log:
  Standardize the various prison_foo_ip[46] functions and prison_if to
  return zero on success and an error code otherwise.  The possible errors
  are EADDRNOTAVAIL if an address being checked for doesn't match the
  prison, and EAFNOSUPPORT if the prison doesn't have any addresses in
  that address family.  For most callers of these functions, use the
  returned error code instead of e.g. a hard-coded EADDRNOTAVAIL or
  EINVAL.
  
  Always include a jailed() check in these functions, where a non-jailed
  cred always returns success (and makes no changes).  Remove the explicit
  jailed() checks that preceded many of the function calls.
  
  Approved by:	bz (mentor)

Modified:
  head/lib/libc/sys/send.2
  head/sys/kern/kern_jail.c
  head/sys/net/if.c
  head/sys/net/rtsock.c
  head/sys/netinet/in.c
  head/sys/netinet/in_pcb.c
  head/sys/netinet/raw_ip.c
  head/sys/netinet/tcp_usrreq.c
  head/sys/netinet/udp_usrreq.c
  head/sys/netinet6/in6.c
  head/sys/netinet6/in6_pcb.c
  head/sys/netinet6/in6_src.c
  head/sys/netinet6/raw_ip6.c
  head/sys/netinet6/udp6_usrreq.c

Modified: head/lib/libc/sys/send.2
==============================================================================
--- head/lib/libc/sys/send.2	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/lib/libc/sys/send.2	Thu Feb  5 14:06:09 2009	(r188144)
@@ -28,7 +28,7 @@
 .\"     From: @(#)send.2	8.2 (Berkeley) 2/21/94
 .\" $FreeBSD$
 .\"
-.Dd September 13, 2006
+.Dd February 5, 2009
 .Dt SEND 2
 .Os
 .Sh NAME
@@ -190,7 +190,7 @@ receiver is not listening on the remote 
 The remote host was down.
 .It Bq Er ENETDOWN
 The remote network was down.
-.It Bq Er EPERM
+.It Bq Er EADDRNOTAVAIL
 The process using a
 .Dv SOCK_RAW
 socket was jailed and the source

Modified: head/sys/kern/kern_jail.c
==============================================================================
--- head/sys/kern/kern_jail.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/kern/kern_jail.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -217,7 +217,7 @@ prison_check_conflicting_ips(struct pris
 		if ((p->pr_ip4s >= 1 && pr->pr_ip4s > 1) ||
 		    (p->pr_ip4s > 1 && pr->pr_ip4s >= 1)) {
 			for (i = 0; i < p->pr_ip4s; i++) {
-				if (_prison_check_ip4(pr, &p->pr_ip4[i]))
+				if (_prison_check_ip4(pr, &p->pr_ip4[i]) == 0)
 					return (EINVAL);
 			}
 		}
@@ -226,7 +226,7 @@ prison_check_conflicting_ips(struct pris
 		if ((p->pr_ip6s >= 1 && pr->pr_ip6s > 1) ||
 		    (p->pr_ip6s > 1 && pr->pr_ip6s >= 1)) {
 			for (i = 0; i < p->pr_ip6s; i++) {
-				if (_prison_check_ip6(pr, &p->pr_ip6[i]))
+				if (_prison_check_ip6(pr, &p->pr_ip6[i]) == 0)
 					return (EINVAL);
 			}
 		}
@@ -807,9 +807,10 @@ prison_proc_free(struct prison *pr)
  * Pass back primary IPv4 address of this jail.
  *
  * If not jailed return success but do not alter the address.  Caller has to
- * make sure to intialize it correctly (INADDR_ANY).
+ * make sure to intialize it correctly (e.g. INADDR_ANY).
  *
- * Returns 0 on success, 1 on error.  Address returned in NBO.
+ * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv4.
+ * Address returned in NBO.
  */
 int
 prison_get_ip4(struct ucred *cred, struct in_addr *ia)
@@ -823,7 +824,7 @@ prison_get_ip4(struct ucred *cred, struc
 		return (0);
 
 	if (cred->cr_prison->pr_ip4 == NULL)
-		return (1);
+		return (EAFNOSUPPORT);
 
 	ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
 	return (0);
@@ -833,8 +834,9 @@ prison_get_ip4(struct ucred *cred, struc
  * Make sure our (source) address is set to something meaningful to this
  * jail.
  *
- * Returns 0 on success, 1 on error.  Address passed in in NBO and returned
- * in NBO.
+ * Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
+ * the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv4.
+ * Address passed in in NBO and returned in NBO.
  */
 int
 prison_local_ip4(struct ucred *cred, struct in_addr *ia)
@@ -847,7 +849,7 @@ prison_local_ip4(struct ucred *cred, str
 	if (!jailed(cred))
 		return (0);
 	if (cred->cr_prison->pr_ip4 == NULL)
-		return (1);
+		return (EAFNOSUPPORT);
 
 	ia0.s_addr = ntohl(ia->s_addr);
 	if (ia0.s_addr == INADDR_LOOPBACK) {
@@ -855,25 +857,23 @@ prison_local_ip4(struct ucred *cred, str
 		return (0);
 	}
 
-	/*
-	 * In case there is only 1 IPv4 address, bind directly.
-	 */
-	if (ia0.s_addr == INADDR_ANY && cred->cr_prison->pr_ip4s == 1) {
-		ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
+	if (ia0.s_addr == INADDR_ANY) {
+		/*
+		 * In case there is only 1 IPv4 address, bind directly.
+		 */
+		if (cred->cr_prison->pr_ip4s == 1)
+			ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
 		return (0);
 	}
 
-	if (ia0.s_addr == INADDR_ANY || prison_check_ip4(cred, ia))
-		return (0);
-
-	return (1);
+	return (_prison_check_ip4(cred->cr_prison, ia));
 }
 
 /*
  * Rewrite destination address in case we will connect to loopback address.
  *
- * Returns 0 on success, 1 on error.  Address passed in in NBO and returned
- * in NBO.
+ * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv4.
+ * Address passed in in NBO and returned in NBO.
  */
 int
 prison_remote_ip4(struct ucred *cred, struct in_addr *ia)
@@ -885,7 +885,8 @@ prison_remote_ip4(struct ucred *cred, st
 	if (!jailed(cred))
 		return (0);
 	if (cred->cr_prison->pr_ip4 == NULL)
-		return (1);
+		return (EAFNOSUPPORT);
+
 	if (ntohl(ia->s_addr) == INADDR_LOOPBACK) {
 		ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
 		return (0);
@@ -898,23 +899,22 @@ prison_remote_ip4(struct ucred *cred, st
 }
 
 /*
- * Check if given address belongs to the jail referenced by cred.
+ * Check if given address belongs to the jail referenced by cred/prison.
  *
- * Returns 1 if address belongs to jail, 0 if not.  Address passed in in NBO.
+ * Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
+ * the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv4.
+ * Address passed in in NBO.
  */
 static int
 _prison_check_ip4(struct prison *pr, struct in_addr *ia)
 {
 	int i, a, z, d;
 
-	if (pr->pr_ip4 == NULL)
-		return (0);
-
 	/*
 	 * Check the primary IP.
 	 */
 	if (pr->pr_ip4[0].s_addr == ia->s_addr)
-		return (1);
+		return (0);
 
 	/*
 	 * All the other IPs are sorted so we can do a binary search.
@@ -929,9 +929,10 @@ _prison_check_ip4(struct prison *pr, str
 		else if (d < 0)
 			a = i + 1;
 		else
-			return (1);
+			return (0);
 	}
-	return (0);
+
+	return (EADDRNOTAVAIL);
 }
 
 int
@@ -942,7 +943,9 @@ prison_check_ip4(struct ucred *cred, str
 	KASSERT(ia != NULL, ("%s: ia is NULL", __func__));
 
 	if (!jailed(cred))
-		return (1);
+		return (0);
+	if (cred->cr_prison->pr_ip4 == NULL)
+		return (EAFNOSUPPORT);
 
 	return (_prison_check_ip4(cred->cr_prison, ia));
 }
@@ -953,9 +956,9 @@ prison_check_ip4(struct ucred *cred, str
  * Pass back primary IPv6 address for this jail.
  *
  * If not jailed return success but do not alter the address.  Caller has to
- * make sure to intialize it correctly (IN6ADDR_ANY_INIT).
+ * make sure to intialize it correctly (e.g. IN6ADDR_ANY_INIT).
  *
- * Returns 0 on success, 1 on error.
+ * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6.
  */
 int
 prison_get_ip6(struct ucred *cred, struct in6_addr *ia6)
@@ -967,7 +970,8 @@ prison_get_ip6(struct ucred *cred, struc
 	if (!jailed(cred))
 		return (0);
 	if (cred->cr_prison->pr_ip6 == NULL)
-		return (1);
+		return (EAFNOSUPPORT);
+
 	bcopy(&cred->cr_prison->pr_ip6[0], ia6, sizeof(struct in6_addr));
 	return (0);
 }
@@ -978,7 +982,8 @@ prison_get_ip6(struct ucred *cred, struc
  * v6only should be set based on (inp->inp_flags & IN6P_IPV6_V6ONLY != 0)
  * when needed while binding.
  *
- * Returns 0 on success, 1 on error.
+ * Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
+ * the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv6.
  */
 int
 prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only)
@@ -990,32 +995,32 @@ prison_local_ip6(struct ucred *cred, str
 	if (!jailed(cred))
 		return (0);
 	if (cred->cr_prison->pr_ip6 == NULL)
-		return (1);
+		return (EAFNOSUPPORT);
+
 	if (IN6_IS_ADDR_LOOPBACK(ia6)) {
 		bcopy(&cred->cr_prison->pr_ip6[0], ia6,
 		    sizeof(struct in6_addr));
 		return (0);
 	}
 
-	/*
-	 * In case there is only 1 IPv6 address, and v6only is true, then
-	 * bind directly.
-	 */
-	if (v6only != 0 && IN6_IS_ADDR_UNSPECIFIED(ia6) &&
-	    cred->cr_prison->pr_ip6s == 1) {
-		bcopy(&cred->cr_prison->pr_ip6[0], ia6,
-		    sizeof(struct in6_addr));
+	if (IN6_IS_ADDR_UNSPECIFIED(ia6)) {
+		/*
+		 * In case there is only 1 IPv6 address, and v6only is true,
+		 * then bind directly.
+		 */
+		if (v6only != 0 && cred->cr_prison->pr_ip6s == 1)
+			bcopy(&cred->cr_prison->pr_ip6[0], ia6,
+			    sizeof(struct in6_addr));
 		return (0);
 	}
-	if (IN6_IS_ADDR_UNSPECIFIED(ia6) || prison_check_ip6(cred, ia6))
-		return (0);
-	return (1);
+
+	return (_prison_check_ip6(cred->cr_prison, ia6));
 }
 
 /*
  * Rewrite destination address in case we will connect to loopback address.
  *
- * Returns 0 on success, 1 on error.
+ * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6.
  */
 int
 prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
@@ -1027,7 +1032,8 @@ prison_remote_ip6(struct ucred *cred, st
 	if (!jailed(cred))
 		return (0);
 	if (cred->cr_prison->pr_ip6 == NULL)
-		return (1);
+		return (EAFNOSUPPORT);
+
 	if (IN6_IS_ADDR_LOOPBACK(ia6)) {
 		bcopy(&cred->cr_prison->pr_ip6[0], ia6,
 		    sizeof(struct in6_addr));
@@ -1041,23 +1047,21 @@ prison_remote_ip6(struct ucred *cred, st
 }
 
 /*
- * Check if given address belongs to the jail referenced by cred.
+ * Check if given address belongs to the jail referenced by cred/prison.
  *
- * Returns 1 if address belongs to jail, 0 if not.
+ * Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
+ * the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv6.
  */
 static int
 _prison_check_ip6(struct prison *pr, struct in6_addr *ia6)
 {
 	int i, a, z, d;
 
-	if (pr->pr_ip6 == NULL)
-		return (0);
-
 	/*
 	 * Check the primary IP.
 	 */
 	if (IN6_ARE_ADDR_EQUAL(&pr->pr_ip6[0], ia6))
-		return (1);
+		return (0);
 
 	/*
 	 * All the other IPs are sorted so we can do a binary search.
@@ -1072,9 +1076,10 @@ _prison_check_ip6(struct prison *pr, str
 		else if (d < 0)
 			a = i + 1;
 		else
-			return (1);
+			return (0);
 	}
-	return (0);
+
+	return (EADDRNOTAVAIL);
 }
 
 int
@@ -1085,7 +1090,9 @@ prison_check_ip6(struct ucred *cred, str
 	KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__));
 
 	if (!jailed(cred))
-		return (1);
+		return (0);
+	if (cred->cr_prison->pr_ip6 == NULL)
+		return (EAFNOSUPPORT);
 
 	return (_prison_check_ip6(cred->cr_prison, ia6));
 }
@@ -1095,8 +1102,9 @@ prison_check_ip6(struct ucred *cred, str
  * Check if given address belongs to the jail referenced by cred (wrapper to
  * prison_check_ip[46]).
  *
- * Returns 1 if address belongs to jail, 0 if not.  IPv4 Address passed in in
- * NBO.
+ * Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
+ * the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow
+ * the address family.  IPv4 Address passed in in NBO.
  */
 int
 prison_if(struct ucred *cred, struct sockaddr *sa)
@@ -1107,35 +1115,31 @@ prison_if(struct ucred *cred, struct soc
 #ifdef INET6
 	struct sockaddr_in6 *sai6;
 #endif
-	int ok;
+	int error;
 
 	KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
 	KASSERT(sa != NULL, ("%s: sa is NULL", __func__));
 
-	ok = 0;
-	switch(sa->sa_family)
+	error = 0;
+	switch (sa->sa_family)
 	{
 #ifdef INET
 	case AF_INET:
 		sai = (struct sockaddr_in *)sa;
-		if (prison_check_ip4(cred, &sai->sin_addr))
-			ok = 1;
+		error = prison_check_ip4(cred, &sai->sin_addr);
 		break;
-
 #endif
 #ifdef INET6
 	case AF_INET6:
 		sai6 = (struct sockaddr_in6 *)sa;
-		if (prison_check_ip6(cred, (struct in6_addr *)&sai6->sin6_addr))
-			ok = 1;
+		error = prison_check_ip6(cred, &sai6->sin6_addr);
 		break;
-
 #endif
 	default:
-		if (!jail_socket_unixiproute_only)
-			ok = 1;
+		if (jailed(cred) && jail_socket_unixiproute_only)
+			error = EAFNOSUPPORT;
 	}
-	return (ok);
+	return (error);
 }
 
 /*

Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/net/if.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -2271,8 +2271,7 @@ again:
 		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
 			struct sockaddr *sa = ifa->ifa_addr;
 
-			if (jailed(curthread->td_ucred) &&
-			    !prison_if(curthread->td_ucred, sa))
+			if (prison_if(curthread->td_ucred, sa) != 0)
 				continue;
 			addrs++;
 #ifdef COMPAT_43

Modified: head/sys/net/rtsock.c
==============================================================================
--- head/sys/net/rtsock.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/net/rtsock.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -347,7 +347,7 @@ rtm_get_jailed(struct rt_addrinfo *info,
 		 * 1. Check if the returned address is part of the jail.
 		 */
 		ia = ((struct sockaddr_in *)rt->rt_ifa->ifa_addr)->sin_addr;
-		if (prison_check_ip4(cred, &ia) != 0) {
+		if (prison_check_ip4(cred, &ia) == 0) {
 			info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
 
 		} else {
@@ -366,7 +366,7 @@ rtm_get_jailed(struct rt_addrinfo *info,
 				if (sa->sa_family != AF_INET)
 					continue;
 				ia = ((struct sockaddr_in *)sa)->sin_addr;
-				if (prison_check_ip4(cred, &ia) != 0) {
+				if (prison_check_ip4(cred, &ia) == 0) {
 					found = 1;
 					break;
 				}
@@ -399,7 +399,7 @@ rtm_get_jailed(struct rt_addrinfo *info,
 		 */
 		bcopy(&((struct sockaddr_in6 *)rt->rt_ifa->ifa_addr)->sin6_addr,
 		    &ia6, sizeof(struct in6_addr));
-		if (prison_check_ip6(cred, &ia6) != 0) {
+		if (prison_check_ip6(cred, &ia6) == 0) {
 			info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
 		} else {
 			struct ifaddr *ifa;
@@ -418,7 +418,7 @@ rtm_get_jailed(struct rt_addrinfo *info,
 					continue;
 				bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
 				    &ia6, sizeof(struct in6_addr));
-				if (prison_check_ip6(cred, &ia6) != 0) {
+				if (prison_check_ip6(cred, &ia6) == 0) {
 					found = 1;
 					break;
 				}
@@ -612,9 +612,10 @@ route_output(struct mbuf *m, struct sock
 		case RTM_GET:
 		report:
 			RT_LOCK_ASSERT(rt);
-			if (jailed(curthread->td_ucred) &&
-			    ((rt->rt_flags & RTF_HOST) == 0 ||
-			    !prison_if(curthread->td_ucred, rt_key(rt)))) {
+			if ((rt->rt_flags & RTF_HOST) == 0
+			    ? jailed(curthread->td_ucred)
+			    : prison_if(curthread->td_ucred,
+			    rt_key(rt)) != 0) {
 				RT_UNLOCK(rt);
 				senderr(ESRCH);
 			}
@@ -1263,9 +1264,9 @@ sysctl_dumpentry(struct radix_node *rn, 
 
 	if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
 		return 0;
-	if (jailed(w->w_req->td->td_ucred) &&
-	    ((rt->rt_flags & RTF_HOST) == 0 ||
-	    !prison_if(w->w_req->td->td_ucred, rt_key(rt))))
+	if ((rt->rt_flags & RTF_HOST) == 0
+	    ? jailed(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));
 	info.rti_info[RTAX_DST] = rt_key(rt);
@@ -1327,8 +1328,8 @@ sysctl_iflist(int af, struct walkarg *w)
 		while ((ifa = TAILQ_NEXT(ifa, ifa_link)) != NULL) {
 			if (af && af != ifa->ifa_addr->sa_family)
 				continue;
-			if (jailed(w->w_req->td->td_ucred) &&
-			    !prison_if(w->w_req->td->td_ucred, ifa->ifa_addr))
+			if (prison_if(w->w_req->td->td_ucred,
+			    ifa->ifa_addr) != 0)
 				continue;
 			info.rti_info[RTAX_IFA] = ifa->ifa_addr;
 			info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
@@ -1376,8 +1377,8 @@ sysctl_ifmalist(int af, struct walkarg *
 		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
 			if (af && af != ifma->ifma_addr->sa_family)
 				continue;
-			if (jailed(w->w_req->td->td_ucred) &&
-			    !prison_if(w->w_req->td->td_ucred, ifma->ifma_addr))
+			if (prison_if(w->w_req->td->td_ucred,
+			    ifma->ifma_addr) != 0)
 				continue;
 			info.rti_info[RTAX_IFA] = ifma->ifma_addr;
 			info.rti_info[RTAX_GATEWAY] =

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/netinet/in.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -264,7 +264,7 @@ in_control(struct socket *so, u_long cmd
 			if (iap->ia_ifp == ifp &&
 			    iap->ia_addr.sin_addr.s_addr == dst.s_addr) {
 				if (td == NULL || prison_check_ip4(
-				    td->td_ucred, &dst))
+				    td->td_ucred, &dst) == 0)
 					ia = iap;
 				break;
 			}
@@ -273,8 +273,8 @@ in_control(struct socket *so, u_long cmd
 				iap = ifatoia(ifa);
 				if (iap->ia_addr.sin_family == AF_INET) {
 					if (td != NULL &&
-					    !prison_check_ip4(td->td_ucred,
-					    &iap->ia_addr.sin_addr))
+					    prison_check_ip4(td->td_ucred,
+					    &iap->ia_addr.sin_addr) != 0)
 						continue;
 					ia = iap;
 					break;
@@ -1199,8 +1199,7 @@ in_lltable_dump(struct lltable *llt, str
 			if ((lle->la_flags & (LLE_DELETED|LLE_VALID)) != LLE_VALID)
 				continue;
 			/* Skip if jailed and not a valid IP of the prison. */
-			if (jailed(wr->td->td_ucred) &&
-			    !prison_if(wr->td->td_ucred, L3_ADDR(lle)))
+			if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
 				continue;
 			/*
 			 * produce a msg made of:

Modified: head/sys/netinet/in_pcb.c
==============================================================================
--- head/sys/netinet/in_pcb.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/netinet/in_pcb.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -325,8 +325,9 @@ in_pcbbind_setup(struct inpcb *inp, stru
 		if (sin->sin_family != AF_INET)
 			return (EAFNOSUPPORT);
 #endif
-		if (prison_local_ip4(cred, &sin->sin_addr))
-			return (EINVAL);
+		error = prison_local_ip4(cred, &sin->sin_addr);
+		if (error)
+			return (error);
 		if (sin->sin_port != *lportp) {
 			/* Don't allow the port to change. */
 			if (*lportp != 0)
@@ -391,8 +392,9 @@ in_pcbbind_setup(struct inpcb *inp, stru
 				     t->inp_cred->cr_uid))
 					return (EADDRINUSE);
 			}
-			if (prison_local_ip4(cred, &sin->sin_addr))
-				return (EADDRNOTAVAIL);
+			error = prison_local_ip4(cred, &sin->sin_addr);
+			if (error)
+				return (error);
 			t = in_pcblookup_local(pcbinfo, sin->sin_addr,
 			    lport, wild, cred);
 			if (t && (t->inp_vflag & INP_TIMEWAIT)) {
@@ -426,8 +428,9 @@ in_pcbbind_setup(struct inpcb *inp, stru
 		u_short first, last, aux;
 		int count;
 
-		if (prison_local_ip4(cred, &laddr))
-			return (EINVAL);
+		error = prison_local_ip4(cred, &laddr);
+		if (error)
+			return (error);
 
 		if (inp->inp_flags & INP_HIGHPORT) {
 			first = V_ipport_hifirstauto;	/* sysctl */
@@ -493,8 +496,9 @@ in_pcbbind_setup(struct inpcb *inp, stru
 		} while (in_pcblookup_local(pcbinfo, laddr,
 		    lport, wild, cred));
 	}
-	if (prison_local_ip4(cred, &laddr))
-		return (EINVAL);
+	error = prison_local_ip4(cred, &laddr);
+	if (error)
+		return (error);
 	*laddrp = laddr.s_addr;
 	*lportp = lport;
 	return (0);
@@ -614,7 +618,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 			if (sa->sa_family != AF_INET)
 				continue;
 			sin = (struct sockaddr_in *)sa;
-			if (prison_check_ip4(cred, &sin->sin_addr)) {
+			if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
 				ia = (struct in_ifaddr *)ifa;
 				break;
 			}
@@ -625,8 +629,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 		}
 
 		/* 3. As a last resort return the 'default' jail address. */
-		if (prison_get_ip4(cred, laddr) != 0)
-			error = EADDRNOTAVAIL;
+		error = prison_get_ip4(cred, laddr);
 		goto done;
 	}
 
@@ -651,7 +654,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 		/* Jailed. */
 		/* 1. Check if the iface address belongs to the jail. */
 		sin = (struct sockaddr_in *)sro.ro_rt->rt_ifa->ifa_addr;
-		if (prison_check_ip4(cred, &sin->sin_addr)) {
+		if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
 			ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa;
 			laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
 			goto done;
@@ -667,7 +670,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 			if (sa->sa_family != AF_INET)
 				continue;
 			sin = (struct sockaddr_in *)sa;
-			if (prison_check_ip4(cred, &sin->sin_addr)) {
+			if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
 				ia = (struct in_ifaddr *)ifa;
 				break;
 			}
@@ -678,8 +681,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 		}
 
 		/* 3. As a last resort return the 'default' jail address. */
-		if (prison_get_ip4(cred, laddr) != 0)
-			error = EADDRNOTAVAIL;
+		error = prison_get_ip4(cred, laddr);
 		goto done;
 	}
 
@@ -729,7 +731,8 @@ in_pcbladdr(struct inpcb *inp, struct in
 				if (sa->sa_family != AF_INET)
 					continue;
 				sin = (struct sockaddr_in *)sa;
-				if (prison_check_ip4(cred, &sin->sin_addr)) {
+				if (prison_check_ip4(cred,
+				    &sin->sin_addr) == 0) {
 					ia = (struct in_ifaddr *)ifa;
 					break;
 				}
@@ -741,8 +744,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 		}
 
 		/* 3. As a last resort return the 'default' jail address. */
-		if (prison_get_ip4(cred, laddr) != 0)
-			error = EADDRNOTAVAIL;
+		error = prison_get_ip4(cred, laddr);
 		goto done;
 	}
 
@@ -776,7 +778,7 @@ in_pcbconnect_setup(struct inpcb *inp, s
 	struct sockaddr_in *sin = (struct sockaddr_in *)nam;
 	struct in_ifaddr *ia;
 	struct inpcb *oinp;
-	struct in_addr laddr, faddr, jailia;
+	struct in_addr laddr, faddr;
 	u_short lport, fport;
 	int error;
 
@@ -809,15 +811,11 @@ in_pcbconnect_setup(struct inpcb *inp, s
 		 * choose the broadcast address for that interface.
 		 */
 		if (faddr.s_addr == INADDR_ANY) {
-			if (cred != NULL && jailed(cred)) {
-				if (prison_get_ip4(cred, &jailia) != 0)
-					return (EADDRNOTAVAIL);
-				faddr.s_addr = jailia.s_addr;
-			} else {
-				faddr =
-				    IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->
-				    sin_addr;
-			}
+			faddr =
+			    IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr;
+			if (cred != NULL &&
+			    (error = prison_get_ip4(cred, &faddr)) != 0)
+				return (error);
 		} else if (faddr.s_addr == (u_long)INADDR_BROADCAST &&
 		    (TAILQ_FIRST(&V_in_ifaddrhead)->ia_ifp->if_flags &
 		    IFF_BROADCAST))
@@ -1375,7 +1373,8 @@ in_pcblookup_hash(struct inpcbinfo *pcbi
 
 			injail = jailed(inp->inp_cred);
 			if (injail) {
-				if (!prison_check_ip4(inp->inp_cred, &laddr))
+				if (prison_check_ip4(inp->inp_cred,
+				    &laddr) != 0)
 					continue;
 			} else {
 				if (local_exact != NULL)

Modified: head/sys/netinet/raw_ip.c
==============================================================================
--- head/sys/netinet/raw_ip.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/netinet/raw_ip.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -276,10 +276,8 @@ 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 (!prison_check_ip4(inp->inp_cred, &ip->ip_dst))
-				continue;
-		}
+		if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
+			continue;
 		if (last != NULL) {
 			struct mbuf *n;
 
@@ -306,10 +304,8 @@ rip_input(struct mbuf *m, int off)
 		if (inp->inp_faddr.s_addr &&
 		    inp->inp_faddr.s_addr != ip->ip_src.s_addr)
 			continue;
-		if (jailed(inp->inp_cred)) {
-			if (!prison_check_ip4(inp->inp_cred, &ip->ip_dst))
-				continue;
-		}
+		if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
+			continue;
 		if (last != NULL) {
 			struct mbuf *n;
 
@@ -370,14 +366,12 @@ 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_cred)) {
-			if (prison_get_ip4(inp->inp_cred, &ip->ip_src) != 0) {
-				INP_RUNLOCK(inp);
-				m_freem(m);
-				return (EPERM);
-			}
-		} else {
-			ip->ip_src = inp->inp_laddr;
+		ip->ip_src = inp->inp_laddr;
+		error = prison_get_ip4(inp->inp_cred, &ip->ip_src);
+		if (error != 0) {
+			INP_RUNLOCK(inp);
+			m_freem(m);
+			return (error);
 		}
 		ip->ip_dst.s_addr = dst;
 		ip->ip_ttl = inp->inp_ip_ttl;
@@ -388,10 +382,11 @@ rip_output(struct mbuf *m, struct socket
 		}
 		INP_RLOCK(inp);
 		ip = mtod(m, struct ip *);
-		if (!prison_check_ip4(inp->inp_cred, &ip->ip_src)) {
+		error = prison_check_ip4(inp->inp_cred, &ip->ip_src);
+		if (error != 0) {
 			INP_RUNLOCK(inp);
 			m_freem(m);
-			return (EPERM);
+			return (error);
 		}
 
 		/*
@@ -803,12 +798,14 @@ rip_bind(struct socket *so, struct socka
 	INIT_VNET_INET(so->so_vnet);
 	struct sockaddr_in *addr = (struct sockaddr_in *)nam;
 	struct inpcb *inp;
+	int error;
 
 	if (nam->sa_len != sizeof(*addr))
 		return (EINVAL);
 
-	if (!prison_check_ip4(td->td_ucred, &addr->sin_addr))
-		return (EADDRNOTAVAIL);
+	error = prison_check_ip4(td->td_ucred, &addr->sin_addr);
+	if (error != 0)
+		return (error);
 
 	if (TAILQ_EMPTY(&V_ifnet) ||
 	    (addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK) ||

Modified: head/sys/netinet/tcp_usrreq.c
==============================================================================
--- head/sys/netinet/tcp_usrreq.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/netinet/tcp_usrreq.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -441,8 +441,8 @@ tcp_usr_connect(struct socket *so, struc
 	if (sinp->sin_family == AF_INET
 	    && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
 		return (EAFNOSUPPORT);
-	if (prison_remote_ip4(td->td_ucred, &sinp->sin_addr) != 0)
-		return (EINVAL);
+	if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr)) != 0)
+		return (error);
 
 	TCPDEBUG0;
 	INP_INFO_WLOCK(&V_tcbinfo);
@@ -508,10 +508,9 @@ tcp6_usr_connect(struct socket *so, stru
 		in6_sin6_2_sin(&sin, sin6p);
 		inp->inp_vflag |= INP_IPV4;
 		inp->inp_vflag &= ~INP_IPV6;
-		if (prison_remote_ip4(td->td_ucred, &sin.sin_addr) != 0) {
-			error = EINVAL;
+		if ((error = prison_remote_ip4(td->td_ucred,
+		    &sin.sin_addr)) != 0)
 			goto out;
-		}
 		if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0)
 			goto out;
 		error = tcp_output_connect(so, nam);
@@ -520,10 +519,8 @@ tcp6_usr_connect(struct socket *so, stru
 	inp->inp_vflag &= ~INP_IPV4;
 	inp->inp_vflag |= INP_IPV6;
 	inp->inp_inc.inc_flags |= INC_ISIPV6;
-	if (prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr) != 0) {
-		error = EINVAL;
+	if ((error = prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr)) != 0)
 		goto out;
-	}
 	if ((error = tcp6_connect(tp, nam, td)) != 0)
 		goto out;
 	error = tcp_output_connect(so, nam);

Modified: head/sys/netinet/udp_usrreq.c
==============================================================================
--- head/sys/netinet/udp_usrreq.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/netinet/udp_usrreq.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -982,10 +982,9 @@ udp_output(struct inpcb *inp, struct mbu
 		 * Jail may rewrite the destination address, so let it do
 		 * that before we use it.
 		 */
-		if (prison_remote_ip4(td->td_ucred, &sin->sin_addr) != 0) {
-			error = EINVAL;
+		error = prison_remote_ip4(td->td_ucred, &sin->sin_addr);
+		if (error)
 			goto release;
-		}
 
 		/*
 		 * If a local address or port hasn't yet been selected, or if
@@ -1271,10 +1270,11 @@ udp_connect(struct socket *so, struct so
 		return (EISCONN);
 	}
 	sin = (struct sockaddr_in *)nam;
-	if (prison_remote_ip4(td->td_ucred, &sin->sin_addr) != 0) {
+	error = prison_remote_ip4(td->td_ucred, &sin->sin_addr);
+	if (error != 0) {
 		INP_WUNLOCK(inp);
 		INP_INFO_WUNLOCK(&V_udbinfo);
-		return (EAFNOSUPPORT);
+		return (error);
 	}
 	error = in_pcbconnect(inp, nam, td->td_ucred);
 	if (error == 0)

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/netinet6/in6.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -330,9 +330,9 @@ in6_control(struct socket *so, u_long cm
 			error = in6_setscope(&sa6->sin6_addr, ifp, NULL);
 		if (error != 0)
 			return (error);
-		if (td != NULL && !prison_check_ip6(td->td_ucred,
-		    &sa6->sin6_addr))
-			return (EADDRNOTAVAIL);
+		if (td != NULL && (error = prison_check_ip6(td->td_ucred,
+		    &sa6->sin6_addr)) != 0)
+			return (error);
 		ia = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
 	} else
 		ia = NULL;
@@ -2241,8 +2241,7 @@ in6_lltable_dump(struct lltable *llt, st
 			if ((lle->la_flags & (LLE_DELETED|LLE_VALID)) != LLE_VALID)
 				continue;
 			/* Skip if jailed and not a valid IP of the prison. */
-			if (jailed(wr->td->td_ucred) &&
-			    !prison_if(wr->td->td_ucred, L3_ADDR(lle)))
+			if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
 				continue;
 			/*
 			 * produce a msg made of:

Modified: head/sys/netinet6/in6_pcb.c
==============================================================================
--- head/sys/netinet6/in6_pcb.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/netinet6/in6_pcb.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -119,7 +119,7 @@ in6_pcbbind(register struct inpcb *inp, 
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL;
 	struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
 	u_short	lport = 0;
-	int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
+	int error, wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
 
 	INP_INFO_WLOCK_ASSERT(pcbinfo);
 	INP_WLOCK_ASSERT(inp);
@@ -131,8 +131,6 @@ in6_pcbbind(register struct inpcb *inp, 
 	if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
 		wild = INPLOOKUP_WILDCARD;
 	if (nam) {
-		int error;
-
 		sin6 = (struct sockaddr_in6 *)nam;
 		if (nam->sa_len != sizeof(*sin6))
 			return (EINVAL);
@@ -145,9 +143,9 @@ in6_pcbbind(register struct inpcb *inp, 
 		if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0)
 			return(error);
 
-		if (prison_local_ip6(cred, &sin6->sin6_addr,
-		    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
-			return (EINVAL);
+		if ((error = prison_local_ip6(cred, &sin6->sin6_addr,
+		    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
+			return (error);
 
 		lport = sin6->sin6_port;
 		if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
@@ -223,9 +221,9 @@ in6_pcbbind(register struct inpcb *inp, 
 						return (EADDRINUSE);
 				}
 			}
-			if (prison_local_ip6(cred, &sin6->sin6_addr,
-			    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
-				return (EADDRNOTAVAIL);
+			if ((error = prison_local_ip6(cred, &sin6->sin6_addr,
+			    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
+				return (error);
 			t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
 			    lport, wild, cred);
 			if (t && (reuseport & ((t->inp_vflag & INP_TIMEWAIT) ?
@@ -258,13 +256,12 @@ in6_pcbbind(register struct inpcb *inp, 
 		}
 		inp->in6p_laddr = sin6->sin6_addr;
 	}
-	if (prison_local_ip6(cred, &inp->in6p_laddr,
-	    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
-		return (EINVAL);
+	if ((error = prison_local_ip6(cred, &inp->in6p_laddr,
+	    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
+		return (error);
 	if (lport == 0) {
-		int e;
-		if ((e = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0)
-			return (e);
+		if ((error = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0)
+			return (error);
 	} else {
 		inp->inp_lport = lport;
 		if (in_pcbinshash(inp) != 0) {
@@ -320,8 +317,8 @@ in6_pcbladdr(register struct inpcb *inp,
 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
 			sin6->sin6_addr = in6addr_loopback;
 	}
-	if (prison_remote_ip6(inp->inp_cred, &sin6->sin6_addr) != 0)
-		return (EADDRNOTAVAIL);
+	if ((error = prison_remote_ip6(inp->inp_cred, &sin6->sin6_addr)) != 0)
+		return (error);
 
 	/*
 	 * XXX: in6_selectsrc might replace the bound local address
@@ -885,7 +882,8 @@ in6_pcblookup_hash(struct inpcbinfo *pcb
 
 			injail = jailed(inp->inp_cred);
 			if (injail) {
-				if (!prison_check_ip6(inp->inp_cred, laddr))
+				if (prison_check_ip6(inp->inp_cred,
+				    laddr) != 0)
 					continue;
 			} else {
 				if (local_exact != NULL)

Modified: head/sys/netinet6/in6_src.c
==============================================================================
--- head/sys/netinet6/in6_src.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/netinet6/in6_src.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -240,11 +240,10 @@ in6_selectsrc(struct sockaddr_in6 *dstso
 			if (*errorp != 0)
 				return (NULL);
 		}
-		if (cred != NULL && prison_local_ip6(cred, &srcsock.sin6_addr,
-		    (inp != NULL && (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) {
-			*errorp = EADDRNOTAVAIL;
+		if (cred != NULL && (*errorp = prison_local_ip6(cred,
+		    &srcsock.sin6_addr, (inp != NULL &&
+		    (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
 			return (NULL);
-		}
 
 		ia6 = (struct in6_ifaddr *)ifa_ifwithaddr((struct sockaddr *)(&srcsock));
 		if (ia6 == NULL ||
@@ -262,11 +261,10 @@ in6_selectsrc(struct sockaddr_in6 *dstso
 	 * Otherwise, if the socket has already bound the source, just use it.
 	 */
 	if (inp != NULL && !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
-		if (cred != NULL && prison_local_ip6(cred, &inp->in6p_laddr,
-		    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) {
-			*errorp = EADDRNOTAVAIL;
+		if (cred != NULL &&
+		    (*errorp = prison_local_ip6(cred, &inp->in6p_laddr,
+		    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
 			return (NULL);
-		}
 		return (&inp->in6p_laddr);
 	}
 
@@ -823,15 +821,16 @@ in6_pcbsetport(struct in6_addr *laddr, s
 	INIT_VNET_INET(curvnet);
 	struct socket *so = inp->inp_socket;
 	u_int16_t lport = 0, first, last, *lastport;
-	int count, error = 0, wild = 0, dorandom;
+	int count, error, wild = 0, dorandom;
 	struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
 
 	INP_INFO_WLOCK_ASSERT(pcbinfo);
 	INP_WLOCK_ASSERT(inp);
 
-	if (prison_local_ip6(cred, laddr,
-	    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
-		return(EINVAL);
+	error = prison_local_ip6(cred, laddr,
+	    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0));
+	if (error)
+		return(error);
 
 	/* XXX: this is redundant when called from in6_pcbbind */
 	if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)

Modified: head/sys/netinet6/raw_ip6.c
==============================================================================
--- head/sys/netinet6/raw_ip6.c	Thu Feb  5 14:02:04 2009	(r188143)
+++ head/sys/netinet6/raw_ip6.c	Thu Feb  5 14:06:09 2009	(r188144)
@@ -179,10 +179,8 @@ 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 (!prison_check_ip6(in6p->inp_cred, &ip6->ip6_dst))
-				continue;
-		}
+		if (prison_check_ip6(in6p->inp_cred, &ip6->ip6_dst) != 0)
+			continue;
 		INP_RLOCK(in6p);
 		if (in6p->in6p_cksum != -1) {
 			V_rip6stat.rip6s_isum++;
@@ -411,11 +409,9 @@ rip6_output(m, va_alist)
 			error = EADDRNOTAVAIL;
 		goto bad;
 	}
-	if (jailed(in6p->inp_cred))
-		if (prison_get_ip6(in6p->inp_cred, in6a) != 0) {
-			error = EPERM;
-			goto bad;
-		}

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list