Author: bz
Date: Sun May  2 16:32:41 2010
New Revision: 207514
URL: http://svn.freebsd.org/changeset/base/207514

Log:
  MFC r207276:
    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)

Modified:
  stable/8/sys/netinet6/in6_src.c
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)
  stable/8/sys/geom/sched/   (props changed)

Modified: stable/8/sys/netinet6/in6_src.c
==============================================================================
--- stable/8/sys/netinet6/in6_src.c     Sun May  2 15:58:25 2010        
(r207513)
+++ stable/8/sys/netinet6/in6_src.c     Sun May  2 16:32:41 2010        
(r207514)
@@ -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);
 }
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to