Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Sep 2006 10:26:17 +0100 (BST)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Max Laier <max@love2party.net>
Cc:        trustedbsd-discuss@trustedbsd.org, freebsd-arch@freebsd.org
Subject:   Re: New in-kernel privilege API: priv(9)
Message-ID:  <20060923102438.N6562@fledge.watson.org>
In-Reply-To: <200609140253.06818.max@love2party.net>
References:  <20060913150912.J1823@fledge.watson.org> <200609140253.06818.max@love2party.net>

next in thread | previous in thread | raw e-mail | index | archive | help

On Thu, 14 Sep 2006, Max Laier wrote:

> Right now, prison_priv_check() is looking rather scary to me.  If something 
> else wants to decide on finer granularity, alright, but in my opinion it's 
> easier (more obvious) to keep the "normal" information in the .h file where 
> the privileges are defined and described - as we are aiming for 
> centralization of the decision and information.  On top of that the caller 
> could mask off ALLOW_IN_JAIL if they think it's not appropriate in a special 
> use case of the privilege.

The attached version of the kern_jail.c diff removes all the extra commented 
out privileges that aren't granted, and were largely there as development 
scaffolding to make sure I considered all privileges.  Does this seem a bit 
less scary?

Robert N M Watson
Computer Laboratory
University of Cambridge

--- //depot/projects/trustedbsd/base/sys/kern/kern_jail.c	2006/09/18 08:37:28
+++ //depot/projects/trustedbsd/priv/sys/kern/kern_jail.c	2006/09/19 08:03:32
@@ -8,7 +8,7 @@
   */

  #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_jail.c,v 1.52 2006/09/17 20:00:35 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_jail.c,v 1.51 2005/09/28 00:30:56 csjp Exp $");

  #include "opt_mac.h"

@@ -20,6 +20,7 @@
  #include <sys/sysproto.h>
  #include <sys/mac.h>
  #include <sys/malloc.h>
+#include <sys/priv.h>
  #include <sys/proc.h>
  #include <sys/taskqueue.h>
  #include <sys/jail.h>
@@ -204,7 +205,7 @@
  	 * a process root from one prison, but attached to the jail
  	 * of another.
  	 */
-	error = suser(td);
+	error = priv_check(td, PRIV_JAIL_ATTACH);
  	if (error)
  		return (error);

@@ -522,6 +523,172 @@
  	}
  }

+/*
+ * Check with permission for a specific privilege is granted within jail.  We
+ * have a specific list of accepted privileges; the rest are denied.
+ */
+int
+prison_priv_check(struct ucred *cred, enum priv priv)
+{
+
+	if (!(jailed(cred)))
+		return (0);
+
+	switch (priv) {
+
+		/*
+		 * Allow ktrace privileges for root in jail.
+		 */
+	case PRIV_KTRACE:
+
+		/*
+		 * Allow jailed processes to configure audit identity and
+		 * submit audit records (login, etc).  In the future we may
+		 * want to further refine the relationship between audit and
+		 * jail.
+		 */
+	case PRIV_AUDIT_GETAUDIT:
+	case PRIV_AUDIT_SETAUDIT:
+	case PRIV_AUDIT_SUBMIT:
+
+		/*
+		 * Allow jailed processes to manipulate process UNIX
+		 * credentials in any way they see fit.
+		 */
+	case PRIV_CRED_SETUID:
+	case PRIV_CRED_SETEUID:
+	case PRIV_CRED_SETGID:
+	case PRIV_CRED_SETEGID:
+	case PRIV_CRED_SETGROUPS:
+	case PRIV_CRED_SETREUID:
+	case PRIV_CRED_SETREGID:
+	case PRIV_CRED_SETRESUID:
+	case PRIV_CRED_SETRESGID:
+
+		/*
+		 * Jail implements visibility constraints already, so allow
+		 * jailed root to override uid/gid-based constraints.
+		 */
+	case PRIV_SEEOTHERGIDS:
+	case PRIV_SEEOTHERUIDS:
+
+		/*
+		 * Jail implements inter-process debugging limits already, so
+		 * allow jailed root various debugging privileges.
+		 */
+	case PRIV_DEBUG_DIFFCRED:
+	case PRIV_DEBUG_SUGID:
+	case PRIV_DEBUG_UNPRIV:
+
+		/*
+		 * Allow jail to set various resource limits and login
+		 * properties, and for now, exceed process resource limits.
+		 */
+	case PRIV_PROC_LIMIT:
+	case PRIV_PROC_SETLOGIN:
+	case PRIV_PROC_SETRLIMIT:
+
+		/*
+		 * The following privileges should be granted to jail once
+		 * implemented.
+	 */
+	/* case PRIV_IPC_READ: */
+	/* case PRIV_IPC_WRITE: */
+	/* case PRIV_IPC_EXEC: */
+	/* case PRIV_IPC_ADMIN: */
+	/* case PRIV_IPC_MSGSIZE: */
+	/* case PRIV_MQ_ADMIN: */
+
+		/*
+		 * Jail implements its own inter-process limits, so allow
+		 * root processes in jail to change scheduling on other
+		 * processes in the same jail.  Likewise for signalling.
+		 */
+	case PRIV_SCHED_DIFFCRED:
+	case PRIV_SIGNAL_DIFFCRED:
+	case PRIV_SIGNAL_SUGID:
+
+		/*
+		 * Allow jailed processes to write to sysctls marked as jail
+		 * writable.
+		 */
+	case PRIV_SYSCTL_WRITEJAIL:
+
+		/*
+		 * Allow root in jail to manage a variety of quota
+		 * properties.  Some are a bit surprising and should be
+		 * reconsidered.
+		 */
+	case PRIV_UFS_GETQUOTA:
+	case PRIV_UFS_QUOTAOFF:		/* XXXRW: Slightly surprising. */
+	case PRIV_UFS_QUOTAON:		/* XXXRW: Slightly surprising. */
+	case PRIV_UFS_SETQUOTA:
+	case PRIV_UFS_SETUSE:		/* XXXRW: Slightly surprising. */
+
+		/*
+		 * Since Jail relies on chroot() to implement file system
+		 * protections, grant many VFS privileges to root in jail.
+		 * Be careful to exclude mount-related and NFS-related
+		 * privileges.
+		 */
+	case PRIV_VFS_READ:
+	case PRIV_VFS_WRITE:
+	case PRIV_VFS_ADMIN:
+	case PRIV_VFS_EXEC:
+	case PRIV_VFS_LOOKUP:
+	case PRIV_VFS_BLOCKRESERVE:	/* XXXRW: Slightly surprising. */
+	case PRIV_VFS_CHFLAGS_DEV:
+	case PRIV_VFS_CHOWN:
+	case PRIV_VFS_CHROOT:
+	case PRIV_VFS_CLEARSUGID:
+	case PRIV_VFS_FCHROOT:
+	case PRIV_VFS_LINK:
+	case PRIV_VFS_SETGID:
+	case PRIV_VFS_STICKYFILE:
+		return (0);
+
+		/*
+		 * Depending on the global setting, allow privilege of
+		 * setting system flags.
+		 */
+	case PRIV_VFS_SYSFLAGS:
+		if (jail_chflags_allowed)
+			return (0);
+		else
+			return (EPERM);
+
+		/*
+		 * Allow jailed root to bind reserved ports.
+		 */
+	case PRIV_NETINET_RESERVEDPORT:
+		return (0);
+
+		/*
+		 * Conditionally allow creating raw sockets in jail.
+		 */
+	case PRIV_NETINET_RAW:
+		if (jail_allow_raw_sockets)
+			return (0);
+		else
+			return (EPERM);
+
+		/*
+		 * Since jail implements its own visibility limits on netstat
+		 * sysctls, allow getcred.  This allows identd to work in
+		 * jail.
+		 */
+	case PRIV_NETINET_GETCRED:
+               return (0);
+
+	default:
+		/*
+		 * In all remaining cases, deny the privilege request.  This
+		 * includes almost all network privileges, many system
+		 * configuration privileges.
+		 */
+		return (EPERM);
+	}
+}
+
  static int
  sysctl_jail_list(SYSCTL_HANDLER_ARGS)
  {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060923102438.N6562>