From 538996dc06eb821c841b6c90813605770644f7f9 Mon Sep 17 00:00:00 2001 From: smh Date: Fri, 14 Apr 2017 22:02:08 +0000 Subject: MFC r316313, r316328: Allow explicitly assigned IPv4 & IPv6 loopback addresses to be used in jails. Relnotes: Yes Sponsored by: Multiplay --- UPDATING | 5 +++++ sys/netinet/in_jail.c | 18 +++++++++--------- sys/netinet6/in6_jail.c | 19 +++++++++---------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/UPDATING b/UPDATING index c6ccf44..1fbfde7 100644 --- a/UPDATING +++ b/UPDATING @@ -16,6 +16,11 @@ from older versions of FreeBSD, try WITHOUT_CLANG and WITH_GCC to bootstrap to the tip of head, and then rebuild without this option. The bootstrap process from older version of current across the gcc/clang cutover is a bit fragile. +20170414: + Binds and sends to the loopback addresses, IPv6 and IPv4, will now + use any explicitly assigned loopback address available in the jail + instead of using the first assigned address of the jail. + 20170402: Clang, llvm, lldb, compiler-rt and libc++ have been upgraded to 4.0.0. Please see the 20141231 entry below for information about prerequisites diff --git a/sys/netinet/in_jail.c b/sys/netinet/in_jail.c index 07b47e3..998c2d9 100644 --- a/sys/netinet/in_jail.c +++ b/sys/netinet/in_jail.c @@ -306,11 +306,6 @@ prison_local_ip4(struct ucred *cred, struct in_addr *ia) } ia0.s_addr = ntohl(ia->s_addr); - if (ia0.s_addr == INADDR_LOOPBACK) { - ia->s_addr = pr->pr_ip4[0].s_addr; - mtx_unlock(&pr->pr_mtx); - return (0); - } if (ia0.s_addr == INADDR_ANY) { /* @@ -323,6 +318,11 @@ prison_local_ip4(struct ucred *cred, struct in_addr *ia) } error = prison_check_ip4_locked(pr, ia); + if (error == EADDRNOTAVAIL && ia0.s_addr == INADDR_LOOPBACK) { + ia->s_addr = pr->pr_ip4[0].s_addr; + error = 0; + } + mtx_unlock(&pr->pr_mtx); return (error); } @@ -354,7 +354,8 @@ prison_remote_ip4(struct ucred *cred, struct in_addr *ia) return (EAFNOSUPPORT); } - if (ntohl(ia->s_addr) == INADDR_LOOPBACK) { + if (ntohl(ia->s_addr) == INADDR_LOOPBACK && + prison_check_ip4_locked(pr, ia) == EADDRNOTAVAIL) { ia->s_addr = pr->pr_ip4[0].s_addr; mtx_unlock(&pr->pr_mtx); return (0); @@ -370,9 +371,8 @@ prison_remote_ip4(struct ucred *cred, struct in_addr *ia) /* * Check if given address belongs to the jail referenced by cred/prison. * - * Returns 0 if jail doesn't restrict IPv4 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. + * Returns 0 if address belongs to jail, + * EADDRNOTAVAIL if the address doesn't belong to the jail. */ int prison_check_ip4_locked(const struct prison *pr, const struct in_addr *ia) diff --git a/sys/netinet6/in6_jail.c b/sys/netinet6/in6_jail.c index f774805..8e0de66 100644 --- a/sys/netinet6/in6_jail.c +++ b/sys/netinet6/in6_jail.c @@ -293,12 +293,6 @@ prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only) return (EAFNOSUPPORT); } - if (IN6_IS_ADDR_LOOPBACK(ia6)) { - bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr)); - mtx_unlock(&pr->pr_mtx); - return (0); - } - if (IN6_IS_ADDR_UNSPECIFIED(ia6)) { /* * In case there is only 1 IPv6 address, and v6only is true, @@ -311,6 +305,11 @@ prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only) } error = prison_check_ip6_locked(pr, ia6); + if (error == EADDRNOTAVAIL && IN6_IS_ADDR_LOOPBACK(ia6)) { + bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr)); + error = 0; + } + mtx_unlock(&pr->pr_mtx); return (error); } @@ -341,7 +340,8 @@ prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6) return (EAFNOSUPPORT); } - if (IN6_IS_ADDR_LOOPBACK(ia6)) { + if (IN6_IS_ADDR_LOOPBACK(ia6) && + prison_check_ip6_locked(pr, ia6) == EADDRNOTAVAIL) { bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr)); mtx_unlock(&pr->pr_mtx); return (0); @@ -357,9 +357,8 @@ prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6) /* * Check if given address belongs to the jail referenced by cred/prison. * - * Returns 0 if jail doesn't restrict IPv6 or if address belongs to jail, - * EADDRNOTAVAIL if the address doesn't belong, or EAFNOSUPPORT if the jail - * doesn't allow IPv6. + * Returns 0 if address belongs to jail, + * EADDRNOTAVAIL if the address doesn't belong to the jail. */ int prison_check_ip6_locked(const struct prison *pr, const struct in6_addr *ia6) -- cgit v1.1