From owner-svn-src-stable@FreeBSD.ORG Sun Jan 24 14:05:56 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7B6AF106568B; Sun, 24 Jan 2010 14:05:56 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 67ED98FC08; Sun, 24 Jan 2010 14:05:56 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o0OE5uAj049487; Sun, 24 Jan 2010 14:05:56 GMT (envelope-from bz@svn.freebsd.org) Received: (from bz@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0OE5u9m049481; Sun, 24 Jan 2010 14:05:56 GMT (envelope-from bz@svn.freebsd.org) Message-Id: <201001241405.o0OE5u9m049481@svn.freebsd.org> From: "Bjoern A. Zeeb" Date: Sun, 24 Jan 2010 14:05:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202924 - in stable/7: sys/kern sys/netinet sys/netinet6 sys/sys usr.sbin/jail X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 Jan 2010 14:05:56 -0000 Author: bz Date: Sun Jan 24 14:05:56 2010 New Revision: 202924 URL: http://svn.freebsd.org/changeset/base/202924 Log: MFC r202468: Add security.jail.ip4_saddrsel/ip6_nosaddrsel sysctls to control whether to use source address selection (default) or the primary jail address for unbound outgoing connections. This is intended to be used by people upgrading from single-IP jails to multi-IP jails but not having to change firewall rules, application ACLs, ... but to force their connections (unless otherwise changed) to the primry jail IP they had been used for years, as well as for people prefering to implement similar policies. Note that for IPv6, if configured incorrectly, this might lead to scope violations, which single-IPv6 jails could as well, as by the design of jails. [1] Note that in contrast to FreeBSD 8.x and newer, where we have per-jail options, the sysctls are global for all jails. Reviewed by: jamie, hrs (ipv6 part) [for HEAD] Pointed out by: hrs [1] Tested by: Jase Thew (bazerka beardz.net) (IPv4) Approved by: re (kib) Modified: stable/7/sys/kern/kern_jail.c stable/7/sys/netinet/in_pcb.c stable/7/sys/netinet6/in6_src.c stable/7/sys/sys/jail.h stable/7/usr.sbin/jail/jail.8 Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/usr.sbin/jail/ (props changed) Modified: stable/7/sys/kern/kern_jail.c ============================================================================== --- stable/7/sys/kern/kern_jail.c Sun Jan 24 14:04:38 2010 (r202923) +++ stable/7/sys/kern/kern_jail.c Sun Jan 24 14:05:56 2010 (r202924) @@ -95,6 +95,22 @@ SYSCTL_INT(_security_jail, OID_AUTO, all &jail_allow_raw_sockets, 0, "Prison root can create raw sockets"); +#ifdef INET +static int jail_ip4_saddrsel = 1; +SYSCTL_INT(_security_jail, OID_AUTO, ip4_saddrsel, CTLFLAG_RW, + &jail_ip4_saddrsel, 0, + "Do (not) use IPv4 source address selection rather than the " + "primary jail IPv4 address."); +#endif + +#ifdef INET6 +static int jail_ip6_saddrsel = 1; +SYSCTL_INT(_security_jail, OID_AUTO, ip6_saddrsel, CTLFLAG_RW, + &jail_ip6_saddrsel, 0, + "Do (not) use IPv6 source address selection rather than the " + "primary jail IPv6 address."); +#endif + int jail_chflags_allowed = 0; SYSCTL_INT(_security_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW, &jail_chflags_allowed, 0, @@ -867,6 +883,39 @@ prison_get_ip4(struct ucred *cred, struc } /* + * Return 1 if we should do proper source address selection or are not jailed. + * We will return 0 if we should bypass source address selection in favour + * of the primary jail IPv4 address. Only in this case *ia will be updated and + * returned in NBO. + * Return EAFNOSUPPORT, in case this jail does not allow IPv4. + */ +int +prison_saddrsel_ip4(struct ucred *cred, struct in_addr *ia) +{ + struct in_addr lia; + int error; + + KASSERT(cred != NULL, ("%s: cred is NULL", __func__)); + KASSERT(ia != NULL, ("%s: ia is NULL", __func__)); + + if (!jailed(cred)) + return (1); + + if (jail_ip4_saddrsel != 0) + return (1); + + lia.s_addr = INADDR_ANY; + error = prison_get_ip4(cred, &lia); + if (error) + return (error); + if (lia.s_addr == INADDR_ANY) + return (1); + + ia->s_addr = lia.s_addr; + return (0); +} + +/* * Make sure our (source) address is set to something meaningful to this * jail. * @@ -1013,6 +1062,39 @@ prison_get_ip6(struct ucred *cred, struc } /* + * Return 1 if we should do proper source address selection or are not jailed. + * We will return 0 if we should bypass source address selection in favour + * of the primary jail IPv6 address. Only in this case *ia will be updated and + * returned in NBO. + * Return EAFNOSUPPORT, in case this jail does not allow IPv6. + */ +int +prison_saddrsel_ip6(struct ucred *cred, struct in6_addr *ia6) +{ + struct in6_addr lia6; + int error; + + KASSERT(cred != NULL, ("%s: cred is NULL", __func__)); + KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__)); + + if (!jailed(cred)) + return (1); + + if (jail_ip6_saddrsel != 0) + return (1); + + lia6 = in6addr_any; + error = prison_get_ip6(cred, &lia6); + if (error) + return (error); + if (IN6_IS_ADDR_UNSPECIFIED(&lia6)) + return (1); + + bcopy(&lia6, ia6, sizeof(struct in6_addr)); + return (0); +} + +/* * Make sure our (source) address is set to something meaningful to this jail. * * v6only should be set based on (inp->inp_flags & IN6P_IPV6_V6ONLY != 0) Modified: stable/7/sys/netinet/in_pcb.c ============================================================================== --- stable/7/sys/netinet/in_pcb.c Sun Jan 24 14:04:38 2010 (r202923) +++ stable/7/sys/netinet/in_pcb.c Sun Jan 24 14:05:56 2010 (r202924) @@ -552,6 +552,13 @@ in_pcbladdr(struct inpcb *inp, struct in KASSERT(laddr != NULL, ("%s: laddr NULL", __func__)); + /* + * Bypass source address selection and use the primary jail IP + * if requested. + */ + if (cred != NULL && !prison_saddrsel_ip4(cred, laddr)) + return (0); + error = 0; ia = NULL; bzero(&sro, sizeof(sro)); Modified: stable/7/sys/netinet6/in6_src.c ============================================================================== --- stable/7/sys/netinet6/in6_src.c Sun Jan 24 14:04:38 2010 (r202923) +++ stable/7/sys/netinet6/in6_src.c Sun Jan 24 14:05:56 2010 (r202924) @@ -258,6 +258,13 @@ in6_selectsrc(struct sockaddr_in6 *dstso } /* + * Bypass source address selection and use the primary jail IP + * if requested. + */ + if (cred != NULL && !prison_saddrsel_ip6(cred, srcp)) + return (0); + + /* * If the address is not specified, choose the best one based on * the outgoing interface and the destination address. */ Modified: stable/7/sys/sys/jail.h ============================================================================== --- stable/7/sys/sys/jail.h Sun Jan 24 14:04:38 2010 (r202923) +++ stable/7/sys/sys/jail.h Sun Jan 24 14:05:56 2010 (r202924) @@ -201,11 +201,13 @@ int prison_get_ip4(struct ucred *cred, s int prison_local_ip4(struct ucred *cred, struct in_addr *ia); int prison_remote_ip4(struct ucred *cred, struct in_addr *ia); int prison_check_ip4(struct ucred *cred, struct in_addr *ia); +int prison_saddrsel_ip4(struct ucred *, struct in_addr *); #ifdef INET6 int prison_get_ip6(struct ucred *, struct in6_addr *); int prison_local_ip6(struct ucred *, struct in6_addr *, int); int prison_remote_ip6(struct ucred *, struct in6_addr *); int prison_check_ip6(struct ucred *, struct in6_addr *); +int prison_saddrsel_ip6(struct ucred *, struct in6_addr *); #endif int prison_check_af(struct ucred *cred, int af); int prison_if(struct ucred *cred, struct sockaddr *sa); Modified: stable/7/usr.sbin/jail/jail.8 ============================================================================== --- stable/7/usr.sbin/jail/jail.8 Sun Jan 24 14:04:38 2010 (r202923) +++ stable/7/usr.sbin/jail/jail.8 Sun Jan 24 14:05:56 2010 (r202924) @@ -33,7 +33,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 24, 2009 +.Dd January 17, 2010 .Dt JAIL 8 .Os .Sh NAME @@ -532,6 +532,15 @@ and interact with various network subsys where privileged access to jails is given out to untrusted parties. As such, by default this option is disabled. +.It Va security.jail.ip4_saddrsel +This flag changes how IPv4 source address selection works and can disable +it for all prisons in favour of forcing the primary IPv4 address of each +jail to be used for unbound outgoing connections. +Source address selection is enabled by default for all jails. +.It Va security.jail.ip6_saddrsel +IPv6 equivalent to the +.Va security.jail.ip4_saddrsel +option. .It Va security.jail.enforce_statfs This MIB entry determines which information processes in a jail are able to get about mount-points.