svn commit: r196176 - in head/sys: kern net sys

Bjoern A. Zeeb bz at FreeBSD.org
Thu Aug 13 10:26:35 UTC 2009


Author: bz
Date: Thu Aug 13 10:26:34 2009
New Revision: 196176
URL: http://svn.freebsd.org/changeset/base/196176

Log:
  Make it possible to change the vnet sysctl variables on jails
  with their own virtual network stack. Jails only inheriting a
  network stack cannot change anything that cannot be changed from
  within a prison.
  
  Reviewed by:	rwatson, zec
  Approved by:	re (kib)

Modified:
  head/sys/kern/kern_jail.c
  head/sys/kern/kern_sysctl.c
  head/sys/net/vnet.h
  head/sys/sys/jail.h
  head/sys/sys/sysctl.h

Modified: head/sys/kern/kern_jail.c
==============================================================================
--- head/sys/kern/kern_jail.c	Thu Aug 13 09:32:15 2009	(r196175)
+++ head/sys/kern/kern_jail.c	Thu Aug 13 10:26:34 2009	(r196176)
@@ -88,7 +88,11 @@ struct prison prison0 = {
 	.pr_childmax	= JAIL_MAX,
 	.pr_hostuuid	= DEFAULT_HOSTUUID,
 	.pr_children	= LIST_HEAD_INITIALIZER(&prison0.pr_children),
+#ifdef VIMAGE
+	.pr_flags	= PR_HOST|PR_VNET,
+#else
 	.pr_flags	= PR_HOST,
+#endif
 	.pr_allow	= PR_ALLOW_ALL,
 };
 MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF);
@@ -3308,6 +3312,25 @@ getcredhostid(struct ucred *cred, unsign
 	mtx_unlock(&cred->cr_prison->pr_mtx);
 }
 
+#ifdef VIMAGE
+/*
+ * Determine whether the prison represented by cred owns
+ * its vnet rather than having it inherited.
+ *
+ * Returns 1 in case the prison owns the vnet, 0 otherwise.
+ */
+int
+prison_owns_vnet(struct ucred *cred)
+{
+
+	/*
+	 * vnets cannot be added/removed after jail creation,
+	 * so no need to lock here.
+	 */
+	return (cred->cr_prison->pr_flags & PR_VNET ? 1 : 0);
+}
+#endif
+
 /*
  * Determine whether the subject represented by cred can "see"
  * status of a mount point.

Modified: head/sys/kern/kern_sysctl.c
==============================================================================
--- head/sys/kern/kern_sysctl.c	Thu Aug 13 09:32:15 2009	(r196175)
+++ head/sys/kern/kern_sysctl.c	Thu Aug 13 10:26:34 2009	(r196176)
@@ -1381,10 +1381,18 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
 
 	/* Is this sysctl writable by only privileged users? */
 	if (req->newptr && !(oid->oid_kind & CTLFLAG_ANYBODY)) {
+		int priv;
+
 		if (oid->oid_kind & CTLFLAG_PRISON)
-			error = priv_check(req->td, PRIV_SYSCTL_WRITEJAIL);
+			priv = PRIV_SYSCTL_WRITEJAIL;
+#ifdef VIMAGE
+		else if ((oid->oid_kind & CTLFLAG_VNET) &&
+		     prison_owns_vnet(req->td->td_ucred))
+			priv = PRIV_SYSCTL_WRITEJAIL;
+#endif
 		else
-			error = priv_check(req->td, PRIV_SYSCTL_WRITE);
+			priv = PRIV_SYSCTL_WRITE;
+		error = priv_check(req->td, priv);
 		if (error)
 			return (error);
 	}

Modified: head/sys/net/vnet.h
==============================================================================
--- head/sys/net/vnet.h	Thu Aug 13 09:32:15 2009	(r196175)
+++ head/sys/net/vnet.h	Thu Aug 13 10:26:34 2009	(r196176)
@@ -232,21 +232,25 @@ int	vnet_sysctl_handle_string(SYSCTL_HAN
 int	vnet_sysctl_handle_uint(SYSCTL_HANDLER_ARGS);
 
 #define	SYSCTL_VNET_INT(parent, nbr, name, access, ptr, val, descr)	\
-	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|CTLFLAG_MPSAFE|(access), \
+	SYSCTL_OID(parent, nbr, name,					\
+	    CTLTYPE_INT|CTLFLAG_MPSAFE|CTLFLAG_VNET|(access),		\
 	    ptr, val, vnet_sysctl_handle_int, "I", descr)
 #define	SYSCTL_VNET_PROC(parent, nbr, name, access, ptr, arg, handler,	\
 	    fmt, descr)							\
-	SYSCTL_OID(parent, nbr, name, access, ptr, arg, handler, fmt,	\
-	    descr)
+	SYSCTL_OID(parent, nbr, name, CTLFLAG_VNET|(access), ptr, arg, 	\
+	    handler, fmt, descr)
 #define	SYSCTL_VNET_STRING(parent, nbr, name, access, arg, len, descr)	\
-	SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|(access), arg,	\
-	    len, vnet_sysctl_handle_string, "A", descr)
+	SYSCTL_OID(parent, nbr, name,					\
+	    CTLTYPE_STRING|CTLFLAG_VNET|(access),			\
+	    arg, len, vnet_sysctl_handle_string, "A", descr)
 #define	SYSCTL_VNET_STRUCT(parent, nbr, name, access, ptr, type, descr)	\
-	SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), ptr,	\
+	SYSCTL_OID(parent, nbr, name,					\
+	    CTLTYPE_OPAQUE|CTLFLAG_VNET|(access), ptr,			\
 	    sizeof(struct type), vnet_sysctl_handle_opaque, "S," #type,	\
 	    descr)
 #define	SYSCTL_VNET_UINT(parent, nbr, name, access, ptr, val, descr)	\
-	SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \
+	SYSCTL_OID(parent, nbr, name,					\
+	    CTLTYPE_UINT|CTLFLAG_MPSAFE|CTLFLAG_VNET|(access),		\
 	    ptr, val, vnet_sysctl_handle_uint, "IU", descr)
 #define	VNET_SYSCTL_ARG(req, arg1) do {					\
 	if (arg1 != NULL)						\

Modified: head/sys/sys/jail.h
==============================================================================
--- head/sys/sys/jail.h	Thu Aug 13 09:32:15 2009	(r196175)
+++ head/sys/sys/jail.h	Thu Aug 13 10:26:34 2009	(r196176)
@@ -341,6 +341,7 @@ void getcredhostuuid(struct ucred *, cha
 void getcredhostid(struct ucred *, unsigned long *);
 int prison_allow(struct ucred *, unsigned);
 int prison_check(struct ucred *cred1, struct ucred *cred2);
+int prison_owns_vnet(struct ucred *);
 int prison_canseemount(struct ucred *cred, struct mount *mp);
 void prison_enforce_statfs(struct ucred *cred, struct mount *mp,
     struct statfs *sp);

Modified: head/sys/sys/sysctl.h
==============================================================================
--- head/sys/sys/sysctl.h	Thu Aug 13 09:32:15 2009	(r196175)
+++ head/sys/sys/sysctl.h	Thu Aug 13 10:26:34 2009	(r196176)
@@ -85,6 +85,7 @@ struct ctlname {
 #define CTLMASK_SECURE	0x00F00000	/* Secure level */
 #define CTLFLAG_TUN	0x00080000	/* Tunable variable */
 #define CTLFLAG_MPSAFE	0x00040000	/* Handler is MP safe */
+#define CTLFLAG_VNET	0x00020000	/* Prisons with vnet can fiddle */
 #define CTLFLAG_RDTUN	(CTLFLAG_RD|CTLFLAG_TUN)
 
 /*


More information about the svn-src-all mailing list