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