svn commit: r202924 - in stable/7: sys/kern sys/netinet sys/netinet6 sys/sys usr.sbin/jail

Bjoern A. Zeeb bz at FreeBSD.org
Sun Jan 24 14:05:56 UTC 2010


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.


More information about the svn-src-stable-7 mailing list