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
This commit is contained in:
Bjoern A. Zeeb 2010-04-27 15:05:03 +00:00
parent fd963b9929
commit 877fc3b64b

View File

@ -182,7 +182,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
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 *dstsock, struct ip6_pktopts *opts,
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 *dstsock, struct ip6_pktopts *opts,
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);
}