svn commit: r207276 - head/sys/netinet6

Bjoern A. Zeeb bz at FreeBSD.org
Tue Apr 27 15:05:03 UTC 2010


Author: bz
Date: Tue Apr 27 15:05:03 2010
New Revision: 207276
URL: http://svn.freebsd.org/changeset/base/207276

Log:
  Make sure IPv6 source address selection does not change interface
  addresses while walking the IPv6 address list if in the jail case
  something is connecting to ::1.
  
  Reported by:	Pieter de Boer (pieter thedarkside.nl)
  Tested by:	Pieter de Boer (pieter thedarkside.nl)
  MFC after:	4 days

Modified:
  head/sys/netinet6/in6_src.c

Modified: head/sys/netinet6/in6_src.c
==============================================================================
--- head/sys/netinet6/in6_src.c	Tue Apr 27 14:14:21 2010	(r207275)
+++ head/sys/netinet6/in6_src.c	Tue Apr 27 15:05:03 2010	(r207276)
@@ -182,7 +182,7 @@ in6_selectsrc(struct sockaddr_in6 *dstso
     struct inpcb *inp, struct route_in6 *ro, struct ucred *cred,
     struct ifnet **ifpp, struct in6_addr *srcp)
 {
-	struct in6_addr dst;
+	struct in6_addr dst, tmp;
 	struct ifnet *ifp = NULL;
 	struct in6_ifaddr *ia = NULL, *ia_best = NULL;
 	struct in6_pktinfo *pi = NULL;
@@ -326,10 +326,9 @@ in6_selectsrc(struct sockaddr_in6 *dstso
 		if (!V_ip6_use_deprecated && IFA6_IS_DEPRECATED(ia))
 			continue;
 
+		/* If jailed only take addresses of the jail into account. */
 		if (cred != NULL &&
-		    prison_local_ip6(cred, &ia->ia_addr.sin6_addr,
-			(inp != NULL &&
-			(inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
+		    prison_check_ip6(cred, &ia->ia_addr.sin6_addr) != 0)
 			continue;
 
 		/* Rule 1: Prefer same address */
@@ -476,10 +475,26 @@ in6_selectsrc(struct sockaddr_in6 *dstso
 		return (EADDRNOTAVAIL);
 	}
 
+	/*
+	 * At this point at least one of the addresses belonged to the jail
+	 * but it could still be, that we want to further restrict it, e.g.
+	 * theoratically IN6_IS_ADDR_LOOPBACK.
+	 * It must not be IN6_IS_ADDR_UNSPECIFIED anymore.
+	 * prison_local_ip6() will fix an IN6_IS_ADDR_LOOPBACK but should
+	 * let all others previously selected pass.
+	 * Use tmp to not change ::1 on lo0 to the primary jail address.
+	 */
+	tmp = ia->ia_addr.sin6_addr;
+	if (cred != NULL && prison_local_ip6(cred, &tmp, (inp != NULL &&
+	    (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) {
+		IN6_IFADDR_RUNLOCK();
+		return (EADDRNOTAVAIL);
+	}
+
 	if (ifpp)
 		*ifpp = ifp;
 
-	bcopy(&ia->ia_addr.sin6_addr, srcp, sizeof(*srcp));
+	bcopy(&tmp, srcp, sizeof(*srcp));
 	IN6_IFADDR_RUNLOCK();
 	return (0);
 }


More information about the svn-src-head mailing list