summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-11-06 13:37:19 +0000
committerrwatson <rwatson@FreeBSD.org>2006-11-06 13:37:19 +0000
commit7288104e2094825a9c98b9923f039817a76e2983 (patch)
tree49b2f12eb24e45ea767f3ad4ca390f0f9a7f08ef
parent0d72a08039b293b383899a1388733feffbb2bc25 (diff)
downloadFreeBSD-src-7288104e2094825a9c98b9923f039817a76e2983.zip
FreeBSD-src-7288104e2094825a9c98b9923f039817a76e2983.tar.gz
Add a new priv(9) kernel interface for checking the availability of
privilege for threads and credentials. Unlike the existing suser(9) interface, priv(9) exposes a named privilege identifier to the privilege checking code, allowing more complex policies regarding the granting of privilege to be expressed. Two interfaces are provided, replacing the existing suser(9) interface: suser(td) -> priv_check(td, priv) suser_cred(cred, flags) -> priv_check_cred(cred, priv, flags) A comprehensive list of currently available kernel privileges may be found in priv.h. New privileges are easily added as required, but the comments on adding privileges found in priv.h and priv(9) should be read before doing so. The new privilege interface exposed sufficient information to the privilege checking routine that it will now be possible for jail to determine whether a particular privilege is granted in the check routine, rather than relying on hints from the calling context via the SUSER_ALLOWJAIL flag. For now, the flag is maintained, but a new jail check function, prison_priv_check(), is exposed from kern_jail.c and used by the privilege check routine to determine if the privilege is permitted in jail. As a result, a centralized list of privileges permitted in jail is now present in kern_jail.c. The MAC Framework is now also able to instrument privilege checks, both to deny privileges otherwise granted (mac_priv_check()), and to grant privileges otherwise denied (mac_priv_grant()), permitting MAC Policy modules to implement privilege models, as well as control a much broader range of system behavior in order to constrain processes running with root privilege. The suser() and suser_cred() functions remain implemented, now in terms of priv_check() and the PRIV_ROOT privilege, for use during the transition and possibly continuing use by third party kernel modules that have not been updated. The PRIV_DRIVER privilege exists to allow device drivers to check privilege without adopting a more specific privilege identifier. This change does not modify the actual security policy, rather, it modifies the interface for privilege checks so changes to the security policy become more feasible. Sponsored by: nCircle Network Security, Inc. Obtained from: TrustedBSD Project Discussed on: arch@ Reviewed (at least in part) by: mlaier, jmg, pjd, bde, ceri, Alex Lyashkov <umka at sevcity dot net>, Skip Ford <skip dot ford at verizon dot net>, Antoine Brodin <antoine dot brodin at laposte dot net>
-rw-r--r--share/man/man9/Makefile1
-rw-r--r--share/man/man9/priv.9115
-rw-r--r--share/man/man9/suser.99
-rw-r--r--sys/conf/files2
-rw-r--r--sys/kern/kern_jail.c169
-rw-r--r--sys/kern/kern_priv.c154
-rw-r--r--sys/kern/kern_prot.c147
-rw-r--r--sys/security/mac/mac_framework.h2
-rw-r--r--sys/security/mac/mac_internal.h34
-rw-r--r--sys/security/mac/mac_priv.c64
-rw-r--r--sys/sys/jail.h1
-rw-r--r--sys/sys/priv.h457
-rw-r--r--sys/sys/systm.h2
13 files changed, 1065 insertions, 92 deletions
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 7c56c97..2b8b5bb 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -188,6 +188,7 @@ MAN= accept_filter.9 \
pmap_zero_page.9 \
printf.9 \
prison_check.9 \
+ priv.9 \
pseudofs.9 \
psignal.9 \
random.9 \
diff --git a/share/man/man9/priv.9 b/share/man/man9/priv.9
new file mode 100644
index 0000000..4693769
--- /dev/null
+++ b/share/man/man9/priv.9
@@ -0,0 +1,115 @@
+.\"-
+.\" Copyright (c) 2006 nCircle Network Security, Inc.
+.\" All rights reserved.
+.\"
+.\" This software was developed by Robert N. M. Watson for the TrustedBSD
+.\" Project under contract to nCircle Network Security, Inc.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
+.\" INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+.\" TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+.\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 30, 2006
+.Dt priv 9
+.Os
+.Sh NAME
+.Nm priv
+.Nd kernel privilege checking API
+.Sh SYNOPSIS
+.In sys/priv.h
+.Ft int
+.Fn priv_check "struct thread *td" "int priv"
+.Ft int
+.Fn priv_check_cred "struct ucred *cred" "int priv" "int flags"
+.Sh DESCRIPTION
+The
+.Xr priv 9
+interfaces check to see if specific system privileges are granted to the
+passed thread,
+.Va td ,
+or credential,
+.Va cred.
+This interface replaces the
+.Xr suser 9
+privilege checking interface.
+Privileges typically represent rights in one of two categories: the right to
+manage a particular component of the system, or an exemption to a specific
+policy or access control list.
+The caller identifies the desired privilege via the
+.Fa priv
+argument.
+Additional access control context may also be passed using the
+.Va flags .
+.Ss Privilege Policies
+Privileges are typically granted based on one of two base system policies:
+the superuser policy, which grants privilege based on the effective (or
+sometimes real) uid having a value of 0, and the
+.Xr jail 2
+policy, which permits only certain privileges to be granted to processes in a
+jail.
+The set of available privileges may also be influenced by the TrustedBSD MAC
+Framework, described in
+.Xr mac 9 .
+.Sh IMPLEMENTATION NOTES
+When adding a new privilege check to a code path, first check the complete
+list of current privileges in
+.Pa sys/priv.h
+to see if one already exists for the class of privilege required.
+Only if there is not an exact match should a new privilege be added to the
+privilege list.
+As the privilege number becomes encoded in the kernel module ABI, privileges
+should only be appended to the list, not inserted in the list, and the list
+sort order should not be changed.
+.Pp
+Certain catch-all privileges exist, such as
+.Dv PRIV_DRIVER ,
+intended to be used by device drivers, rather than adding a new
+driver-specific privilege.
+.Sh RETURN VALUES
+Typically, 0 will be returned for success, and
+.Dv EPERM
+will be returned on failure.
+Most consumers of
+.Xr priv 9
+will wish to directly return the error code from a failed privilege check to
+user space; a small number will wish to translate it to another error code
+appropriate to a specific context.
+.Pp
+When designing new APIs, it is preferable to return explicit errors from a
+call if privilege is not granted rather than changing the semantics of the
+call but returning success.
+For example, the behavior exhibited by
+.Xr stat 2 ,
+in which the generation field is optionally zero'd out when insufficient
+privilege is not present is highly undesirable, as it results in frequent
+privilege checks, and the caller is unable to tell if an access control
+failure occured.
+.Sh SEE ALSO
+.Xr jail 2 ,
+.Xr mac 9 ,
+.Xr suser 9 ,
+.Xr ucred 9
+.Sh AUTHORS
+The
+.Xr priv 9
+API and implementation were created by Robert Watson under contract to
+nCircle Network Security, Inc.
diff --git a/share/man/man9/suser.9 b/share/man/man9/suser.9
index fc1d89f..eb05454 100644
--- a/share/man/man9/suser.9
+++ b/share/man/man9/suser.9
@@ -54,6 +54,12 @@ and
.Fn suser_cred
functions check if the credentials given include superuser powers.
.Pp
+These interfaces have now been obsoleted by
+.Xr priv 9 ,
+and are provided only for compatibility with third party kernel modules that
+have not yet been updated to the new interface.
+They should not be used in any new kernel code.
+.Pp
The
.Fn suser
function is the most common, and should be used unless special
@@ -123,7 +129,8 @@ of some other implementations of
in which a TRUE response indicates superuser powers.
.Sh SEE ALSO
.Xr chroot 2 ,
-.Xr jail 2
+.Xr jail 2 ,
+.Xr priv 9
.Sh BUGS
The
.Fn suser
diff --git a/sys/conf/files b/sys/conf/files
index d5d7242..c4fb1c0 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1350,6 +1350,7 @@ kern/kern_ntptime.c standard
kern/kern_physio.c standard
kern/kern_pmc.c standard
kern/kern_poll.c optional device_polling
+kern/kern_priv.c standard
kern/kern_proc.c standard
kern/kern_prot.c standard
kern/kern_resource.c standard
@@ -1936,6 +1937,7 @@ security/mac/mac_label.c optional mac
security/mac/mac_net.c optional mac
security/mac/mac_pipe.c optional mac
security/mac/mac_posix_sem.c optional mac
+security/mac/mac_priv.c optional mac
security/mac/mac_process.c optional mac
security/mac/mac_socket.c optional mac
security/mac/mac_system.c optional mac
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 3924388..c676ddc 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -19,6 +19,7 @@ __FBSDID("$FreeBSD$");
#include <sys/errno.h>
#include <sys/sysproto.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/taskqueue.h>
#include <sys/jail.h>
@@ -205,7 +206,7 @@ jail_attach(struct thread *td, struct jail_attach_args *uap)
* 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);
@@ -523,6 +524,172 @@ prison_enforce_statfs(struct ucred *cred, struct mount *mp, struct statfs *sp)
}
}
+/*
+ * 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, int 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:
+
+ /*
+ * System V and POSIX IPC privileges are granted in jail.
+ */
+ 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)
{
diff --git a/sys/kern/kern_priv.c b/sys/kern/kern_priv.c
new file mode 100644
index 0000000..6d2d692
--- /dev/null
+++ b/sys/kern/kern_priv.c
@@ -0,0 +1,154 @@
+/*-
+ * Copyright (c) 2006 nCircle Network Security, Inc.
+ * All rights reserved.
+ *
+ * This software was developed by Robert N. M. Watson for the TrustedBSD
+ * Project under contract to nCircle Network Security, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
+ * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "opt_mac.h"
+
+#include <sys/param.h>
+#include <sys/jail.h>
+#include <sys/kernel.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+
+#include <security/mac/mac_framework.h>
+
+/*
+ * `suser_enabled' (which can be set by the security.bsd.suser_enabled
+ * sysctl) determines whether the system 'super-user' policy is in effect. If
+ * it is nonzero, an effective uid of 0 connotes special privilege,
+ * overriding many mandatory and discretionary protections. If it is zero,
+ * uid 0 is offered no special privilege in the kernel security policy.
+ * Setting it to zero may seriously impact the functionality of many existing
+ * userland programs, and should not be done without careful consideration of
+ * the consequences.
+ */
+int suser_enabled = 1;
+SYSCTL_INT(_security_bsd, OID_AUTO, suser_enabled, CTLFLAG_RW,
+ &suser_enabled, 0, "processes with uid 0 have privilege");
+TUNABLE_INT("security.bsd.suser_enabled", &suser_enabled);
+
+/*
+ * Check a credential for privilege. Lots of good reasons to deny privilege;
+ * only a few to grant it.
+ */
+int
+priv_check_cred(struct ucred *cred, int priv, int flags)
+{
+ int error;
+
+ KASSERT(PRIV_VALID(priv), ("priv_check_cred: invalid privilege %d",
+ priv));
+
+#ifdef MAC
+ error = mac_priv_check(cred, priv);
+ if (error)
+ return (error);
+#endif
+
+ /*
+ * Jail policy will restrict certain privileges that may otherwise be
+ * be granted.
+ *
+ * While debugging the transition from SUSER_ALLOWJAIL to Jail being
+ * aware of specific privileges, perform run-time checking that the
+ * two versions of the policy align. This assertion will go away
+ * once the SUSER_ALLOWJAIL flag has gone away.
+ */
+ error = prison_priv_check(cred, priv);
+#ifdef NOTYET
+ KASSERT(!jailed(cred) || error == ((flags & SUSER_ALLOWJAIL) ? 0 :
+ EPERM), ("priv_check_cred: prison_priv_check %d but flags %s",
+ error, flags & SUSER_ALLOWJAIL ? "allowjail" : "!allowjail"));
+#endif
+ if (error)
+ return (error);
+
+ /*
+ * Having determined if privilege is restricted by various policies,
+ * now determine if privilege is granted. For now, we allow
+ * short-circuit boolean evaluation, so may not call all policies.
+ * Perhaps we should.
+ *
+ * Superuser policy grants privilege based on the effective (or in
+ * certain edge cases, real) uid being 0. We allow the policy to be
+ * globally disabled, although this is currently of limited utility.
+ */
+ if (suser_enabled) {
+ if (flags & SUSER_RUID) {
+ if (cred->cr_ruid == 0)
+ return (0);
+ } else {
+ if (cred->cr_uid == 0)
+ return (0);
+ }
+ }
+
+ /*
+ * Now check with MAC, if enabled, to see if a policy module grants
+ * privilege.
+ */
+#ifdef MAC
+ if (mac_priv_grant(cred, priv) == 0)
+ return (0);
+#endif
+ return (EPERM);
+}
+
+int
+priv_check(struct thread *td, int priv)
+{
+
+ KASSERT(td == curthread, ("priv_check: td != curthread"));
+
+ return (priv_check_cred(td->td_ucred, priv, 0));
+}
+
+/*
+ * Historical suser() wrapper functions, which now simply request PRIV_ROOT.
+ * These will be removed in the near future, and exist solely because
+ * the kernel and modules are not yet fully adapted to the new model.
+ */
+int
+suser_cred(struct ucred *cred, int flags)
+{
+
+ return (priv_check_cred(cred, PRIV_ROOT, flags));
+}
+
+int
+suser(struct thread *td)
+{
+
+ KASSERT(td == curthread, ("suser: td != curthread"));
+
+ return (suser_cred(td->td_ucred, 0));
+}
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index daa8966..cb86a9c 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/refcount.h>
#include <sys/sx.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/sysproto.h>
#include <sys/jail.h>
@@ -547,7 +548,8 @@ setuid(struct thread *td, struct setuid_args *uap)
#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
uid != oldcred->cr_uid && /* allow setuid(geteuid()) */
#endif
- (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0)
+ (error = priv_check_cred(oldcred, PRIV_CRED_SETUID,
+ SUSER_ALLOWJAIL)) != 0)
goto fail;
/*
@@ -563,7 +565,8 @@ setuid(struct thread *td, struct setuid_args *uap)
#ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */
uid == oldcred->cr_uid ||
#endif
- suser_cred(oldcred, SUSER_ALLOWJAIL) == 0) /* we are using privs */
+ /* We are using privs. */
+ priv_check_cred(oldcred, PRIV_CRED_SETUID, SUSER_ALLOWJAIL) == 0)
#endif
{
/*
@@ -639,7 +642,8 @@ seteuid(struct thread *td, struct seteuid_args *uap)
if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */
euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */
- (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0)
+ (error = priv_check_cred(oldcred, PRIV_CRED_SETEUID,
+ SUSER_ALLOWJAIL)) != 0)
goto fail;
/*
@@ -711,7 +715,8 @@ setgid(struct thread *td, struct setgid_args *uap)
#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */
#endif
- (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0)
+ (error = priv_check_cred(oldcred, PRIV_CRED_SETGID,
+ SUSER_ALLOWJAIL)) != 0)
goto fail;
crcopy(newcred, oldcred);
@@ -724,7 +729,8 @@ setgid(struct thread *td, struct setgid_args *uap)
#ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */
gid == oldcred->cr_groups[0] ||
#endif
- suser_cred(oldcred, SUSER_ALLOWJAIL) == 0) /* we are using privs */
+ /* We are using privs. */
+ priv_check_cred(oldcred, PRIV_CRED_SETGID, SUSER_ALLOWJAIL) == 0)
#endif
{
/*
@@ -796,7 +802,8 @@ setegid(struct thread *td, struct setegid_args *uap)
if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */
egid != oldcred->cr_svgid && /* allow setegid(saved gid) */
- (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0)
+ (error = priv_check_cred(oldcred, PRIV_CRED_SETEGID,
+ SUSER_ALLOWJAIL)) != 0)
goto fail;
crcopy(newcred, oldcred);
@@ -859,7 +866,8 @@ kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
goto fail;
#endif
- error = suser_cred(oldcred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS,
+ SUSER_ALLOWJAIL);
if (error)
goto fail;
@@ -931,7 +939,8 @@ setreuid(register struct thread *td, struct setreuid_args *uap)
ruid != oldcred->cr_svuid) ||
(euid != (uid_t)-1 && euid != oldcred->cr_uid &&
euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) &&
- (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0)
+ (error = priv_check_cred(oldcred, PRIV_CRED_SETREUID,
+ SUSER_ALLOWJAIL)) != 0)
goto fail;
crcopy(newcred, oldcred);
@@ -999,7 +1008,8 @@ setregid(register struct thread *td, struct setregid_args *uap)
rgid != oldcred->cr_svgid) ||
(egid != (gid_t)-1 && egid != oldcred->cr_groups[0] &&
egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) &&
- (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0)
+ (error = priv_check_cred(oldcred, PRIV_CRED_SETREGID,
+ SUSER_ALLOWJAIL)) != 0)
goto fail;
crcopy(newcred, oldcred);
@@ -1079,7 +1089,8 @@ setresuid(register struct thread *td, struct setresuid_args *uap)
(suid != (uid_t)-1 && suid != oldcred->cr_ruid &&
suid != oldcred->cr_svuid &&
suid != oldcred->cr_uid)) &&
- (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0)
+ (error = priv_check_cred(oldcred, PRIV_CRED_SETRESUID,
+ SUSER_ALLOWJAIL)) != 0)
goto fail;
crcopy(newcred, oldcred);
@@ -1160,7 +1171,8 @@ setresgid(register struct thread *td, struct setresgid_args *uap)
(sgid != (gid_t)-1 && sgid != oldcred->cr_rgid &&
sgid != oldcred->cr_svgid &&
sgid != oldcred->cr_groups[0])) &&
- (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0)
+ (error = priv_check_cred(oldcred, PRIV_CRED_SETRESGID,
+ SUSER_ALLOWJAIL)) != 0)
goto fail;
crcopy(newcred, oldcred);
@@ -1324,65 +1336,14 @@ groupmember(gid_t gid, struct ucred *cred)
}
/*
- * `suser_enabled' (which can be set by the security.suser_enabled
- * sysctl) determines whether the system 'super-user' policy is in effect.
- * If it is nonzero, an effective uid of 0 connotes special privilege,
- * overriding many mandatory and discretionary protections. If it is zero,
- * uid 0 is offered no special privilege in the kernel security policy.
- * Setting it to zero may seriously impact the functionality of many
- * existing userland programs, and should not be done without careful
- * consideration of the consequences.
- */
-int suser_enabled = 1;
-SYSCTL_INT(_security_bsd, OID_AUTO, suser_enabled, CTLFLAG_RW,
- &suser_enabled, 0, "processes with uid 0 have privilege");
-TUNABLE_INT("security.bsd.suser_enabled", &suser_enabled);
-
-/*
- * Test whether the specified credentials imply "super-user" privilege.
- * Return 0 or EPERM.
- */
-int
-suser_cred(struct ucred *cred, int flag)
-{
-
- if (!suser_enabled)
- return (EPERM);
- if (((flag & SUSER_RUID) ? cred->cr_ruid : cred->cr_uid) != 0)
- return (EPERM);
- if (jailed(cred) && !(flag & SUSER_ALLOWJAIL))
- return (EPERM);
- return (0);
-}
-
-/*
- * Shortcut to hide contents of struct td and struct proc from the
- * caller, promoting binary compatibility.
- */
-int
-suser(struct thread *td)
-{
-
-#ifdef INVARIANTS
- if (td != curthread) {
- printf("suser: thread %p (%d %s) != curthread %p (%d %s)\n",
- td, td->td_proc->p_pid, td->td_proc->p_comm,
- curthread, curthread->td_proc->p_pid,
- curthread->td_proc->p_comm);
-#ifdef KDB
- kdb_backtrace();
-#endif
- }
-#endif
- return (suser_cred(td->td_ucred, 0));
-}
-
-/*
* Test the active securelevel against a given level. securelevel_gt()
* implements (securelevel > level). securelevel_ge() implements
* (securelevel >= level). Note that the logic is inverted -- these
* functions return EPERM on "success" and 0 on "failure".
*
+ * XXXRW: Possibly since this has to do with privilege, it should move to
+ * kern_priv.c.
+ *
* MPSAFE
*/
int
@@ -1435,7 +1396,8 @@ cr_seeotheruids(struct ucred *u1, struct ucred *u2)
{
if (!see_other_uids && u1->cr_ruid != u2->cr_ruid) {
- if (suser_cred(u1, SUSER_ALLOWJAIL) != 0)
+ if (priv_check_cred(u1, PRIV_SEEOTHERUIDS, SUSER_ALLOWJAIL)
+ != 0)
return (ESRCH);
}
return (0);
@@ -1474,7 +1436,8 @@ cr_seeothergids(struct ucred *u1, struct ucred *u2)
break;
}
if (!match) {
- if (suser_cred(u1, SUSER_ALLOWJAIL) != 0)
+ if (priv_check_cred(u1, PRIV_SEEOTHERGIDS,
+ SUSER_ALLOWJAIL) != 0)
return (ESRCH);
}
}
@@ -1591,7 +1554,8 @@ cr_cansignal(struct ucred *cred, struct proc *proc, int signum)
break;
default:
/* Not permitted without privilege. */
- error = suser_cred(cred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(cred, PRIV_SIGNAL_SUGID,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
}
@@ -1606,7 +1570,8 @@ cr_cansignal(struct ucred *cred, struct proc *proc, int signum)
cred->cr_uid != proc->p_ucred->cr_ruid &&
cred->cr_uid != proc->p_ucred->cr_svuid) {
/* Not permitted without privilege. */
- error = suser_cred(cred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(cred, PRIV_SIGNAL_DIFFCRED,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
}
@@ -1614,7 +1579,6 @@ cr_cansignal(struct ucred *cred, struct proc *proc, int signum)
return (0);
}
-
/*-
* Determine whether td may deliver the specified signal to p.
* Returns: 0 for permitted, an errno value otherwise
@@ -1683,19 +1647,14 @@ p_cansched(struct thread *td, struct proc *p)
return (error);
if ((error = cr_seeothergids(td->td_ucred, p->p_ucred)))
return (error);
- if (td->td_ucred->cr_ruid == p->p_ucred->cr_ruid)
- return (0);
- if (td->td_ucred->cr_uid == p->p_ucred->cr_ruid)
- return (0);
- if (suser_cred(td->td_ucred, SUSER_ALLOWJAIL) == 0)
- return (0);
-
-#ifdef CAPABILITIES
- if (!cap_check(NULL, td, CAP_SYS_NICE, SUSER_ALLOWJAIL))
- return (0);
-#endif
-
- return (EPERM);
+ if (td->td_ucred->cr_ruid != p->p_ucred->cr_ruid &&
+ td->td_ucred->cr_uid != p->p_ucred->cr_ruid) {
+ error = priv_check_cred(td->td_ucred, PRIV_SCHED_DIFFCRED,
+ SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
+ }
+ return (0);
}
/*
@@ -1730,7 +1689,8 @@ p_candebug(struct thread *td, struct proc *p)
KASSERT(td == curthread, ("%s: td not curthread", __func__));
PROC_LOCK_ASSERT(p, MA_OWNED);
if (!unprivileged_proc_debug) {
- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(td->td_ucred, PRIV_DEBUG_UNPRIV,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
}
@@ -1778,11 +1738,18 @@ p_candebug(struct thread *td, struct proc *p)
/*
* If p's gids aren't a subset, or the uids aren't a subset,
* or the credential has changed, require appropriate privilege
- * for td to debug p. For POSIX.1e capabilities, this will
- * require CAP_SYS_PTRACE.
+ * for td to debug p.
*/
- if (!grpsubset || !uidsubset || credentialchanged) {
- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ if (!grpsubset || !uidsubset) {
+ error = priv_check_cred(td->td_ucred, PRIV_DEBUG_DIFFCRED,
+ SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
+ }
+
+ if (credentialchanged) {
+ error = priv_check_cred(td->td_ucred, PRIV_DEBUG_SUGID,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
}
@@ -1796,6 +1763,7 @@ p_candebug(struct thread *td, struct proc *p)
/*
* Can't trace a process that's currently exec'ing.
+ *
* XXX: Note, this is not a security policy decision, it's a
* basic correctness/functionality decision. Therefore, this check
* should be moved to the caller's of p_candebug().
@@ -2057,7 +2025,8 @@ setlogin(struct thread *td, struct setlogin_args *uap)
int error;
char logintmp[MAXLOGNAME];
- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(td->td_ucred, PRIV_PROC_SETLOGIN,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
error = copyinstr(uap->namebuf, logintmp, sizeof(logintmp), NULL);
diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h
index 78f69da..a895cfe 100644
--- a/sys/security/mac/mac_framework.h
+++ b/sys/security/mac/mac_framework.h
@@ -407,6 +407,8 @@ int mac_pipe_label_set(struct ucred *cred, struct pipepair *pp,
struct label *label);
void mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred);
void mac_associate_nfsd_label(struct ucred *cred);
+int mac_priv_check(struct ucred *cred, int priv);
+int mac_priv_grant(struct ucred *cred, int priv);
/*
* Calls to help various file systems implement labeling functionality
diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h
index 5db5f7d..b2289ee 100644
--- a/sys/security/mac/mac_internal.h
+++ b/sys/security/mac/mac_internal.h
@@ -2,6 +2,7 @@
* Copyright (c) 1999-2002 Robert N. M. Watson
* Copyright (c) 2001 Ilmar S. Habibulin
* Copyright (c) 2001-2004 Networks Associates Technology, Inc.
+ * Copyright (c) 2006 nCircle Network Security, Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@@ -12,6 +13,9 @@
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
* as part of the DARPA CHATS research program.
*
+ * This software was developed by Robert N. M. Watson for the TrustedBSD
+ * Project under contract to nCircle Network Security, Inc.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -152,6 +156,36 @@ int vn_setlabel(struct vnode *vp, struct label *intlabel,
} while (0)
/*
+ * MAC_GRANT performs the designated check by walking the policy module
+ * list and checking with each as to how it feels about the request. Unlike
+ * MAC_CHECK, it grants if any policies return '0', and otherwise returns
+ * EPERM. Note that it returns its value via 'error' in the scope of the
+ * caller.
+ */
+#define MAC_GRANT(check, args...) do { \
+ struct mac_policy_conf *mpc; \
+ int entrycount; \
+ \
+ error = EPERM; \
+ LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \
+ if (mpc->mpc_ops->mpo_ ## check != NULL) { \
+ if (mpc->mpc_ops->mpo_ ## check(args) == 0) \
+ error = 0; \
+ } \
+ } \
+ if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \
+ LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \
+ if (mpc->mpc_ops->mpo_ ## check != NULL) { \
+ if (mpc->mpc_ops->mpo_ ## check (args) \
+ == 0) \
+ error = 0; \
+ } \
+ } \
+ mac_policy_list_unbusy(); \
+ } \
+} while (0)
+
+/*
* MAC_BOOLEAN performs the designated boolean composition by walking
* the module list, invoking each instance of the operation, and
* combining the results using the passed C operator. Note that it
diff --git a/sys/security/mac/mac_priv.c b/sys/security/mac/mac_priv.c
new file mode 100644
index 0000000..76ce71e
--- /dev/null
+++ b/sys/security/mac/mac_priv.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 2006 nCircle Network Security, Inc.
+ * All rights reserved.
+ *
+ * This software was developed by Robert N. M. Watson for the TrustedBSD
+ * Project under contract to nCircle Network Security, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
+ * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * MAC checks for system privileges.
+ */
+
+#include "opt_mac.h"
+
+#include <sys/param.h>
+#include <sys/priv.h>
+#include <sys/module.h>
+#include <sys/mac_policy.h>
+
+#include <security/mac/mac_framework.h>
+#include <security/mac/mac_internal.h>
+
+int
+mac_priv_check(struct ucred *cred, int priv)
+{
+ int error;
+
+ MAC_CHECK(priv_check, cred, priv);
+
+ return (error);
+}
+
+int
+mac_priv_grant(struct ucred *cred, int priv)
+{
+ int error;
+
+ MAC_GRANT(priv_grant, cred, priv);
+
+ return (error);
+}
diff --git a/sys/sys/jail.h b/sys/sys/jail.h
index 0be8fac..b9a5858 100644
--- a/sys/sys/jail.h
+++ b/sys/sys/jail.h
@@ -110,6 +110,7 @@ u_int32_t prison_getip(struct ucred *cred);
void prison_hold(struct prison *pr);
int prison_if(struct ucred *cred, struct sockaddr *sa);
int prison_ip(struct ucred *cred, int flag, u_int32_t *ip);
+int prison_priv_check(struct ucred *cred, int priv);
void prison_remote_ip(struct ucred *cred, int flags, u_int32_t *ip);
#endif /* _KERNEL */
diff --git a/sys/sys/priv.h b/sys/sys/priv.h
new file mode 100644
index 0000000..d77622b
--- /dev/null
+++ b/sys/sys/priv.h
@@ -0,0 +1,457 @@
+/*-
+ * Copyright (c) 2006 nCircle Network Security, Inc.
+ * All rights reserved.
+ *
+ * This software was developed by Robert N. M. Watson for the TrustedBSD
+ * Project under contract to nCircle Network Security, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
+ * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Privilege checking interface for BSD kernel.
+ */
+#ifndef _SYS_PRIV_H_
+#define _SYS_PRIV_H_
+
+/*
+ * Privilege list. In no particular order.
+ *
+ * Think carefully before adding or reusing one of these privileges -- are
+ * there existing instances referring to the same privilege? Third party
+ * vendors may request the assignment of privileges to be used in loadable
+ * modules. Particular numeric privilege assignments are part of the
+ * loadable kernel module ABI, and should not be changed across minor
+ * releases.
+ *
+ * When adding a new privilege, remember to determine if it's appropriate for
+ * use in jail, and update the privilege switch in kern_jail.c as necessary.
+ */
+
+/*
+ * Track beginning of privilege list.
+ */
+#define _PRIV_LOWEST 0
+
+/*
+ * PRIV_ROOT is a catch-all for as yet unnamed privileges. No new
+ * references to this privilege should be added.
+ */
+#define PRIV_ROOT 1 /* Catch-all during development. */
+
+/*
+ * The remaining privileges typically correspond to one or a small
+ * number of specific privilege checks, and have (relatively) precise
+ * meanings. They are loosely sorted into a set of base system
+ * privileges, such as the ability to reboot, and then loosely by
+ * subsystem, indicated by a subsystem name.
+ */
+#define PRIV_ACCT 2 /* Manage process accounting. */
+#define PRIV_MAXFILES 3 /* Exceed system open files limit. */
+#define PRIV_MAXPROC 4 /* Exceed system processes limit. */
+#define PRIV_KTRACE 5 /* Set/clear KTRFAC_ROOT on ktrace. */
+#define PRIV_SETDUMPER 6 /* Configure dump device. */
+#define PRIV_NFSD 7 /* Can become NFS daemon. */
+#define PRIV_REBOOT 8 /* Can reboot system. */
+#define PRIV_SWAPON 9 /* Can swapon(). */
+#define PRIV_SWAPOFF 10 /* Can swapoff(). */
+#define PRIV_MSGBUF 11 /* Can read kernel message buffer. */
+#define PRIV_WITNESS 12 /* Can configure WITNESS. */
+#define PRIV_IO 13 /* Can perform low-level I/O. */
+#define PRIV_KEYBOARD 14 /* Reprogram keyboard. */
+#define PRIV_DRIVER 15 /* Low-level driver privilege. */
+#define PRIV_ADJTIME 16 /* Set time adjustment. */
+#define PRIV_NTP_ADJTIME 17 /* Set NTP time adjustment. */
+#define PRIV_CLOCK_SETTIME 18 /* Can call clock_settime. */
+#define PRIV_SETTIMEOFDAY 19 /* Can call settimeofday. */
+#define PRIV_SETHOSTID 20 /* Can call sethostid. */
+#define PRIV_SETDOMAINNAME 21 /* Can call setdomainname. */
+
+/*
+ * Audit subsystem privileges.
+ */
+#define PRIV_AUDIT_CONTROL 40 /* Can configure audit. */
+#define PRIV_AUDIT_FAILSTOP 41 /* Can run during audit fail stop. */
+#define PRIV_AUDIT_GETAUDIT 42 /* Can get proc audit properties. */
+#define PRIV_AUDIT_SETAUDIT 43 /* Can set proc audit properties. */
+#define PRIV_AUDIT_SUBMIT 44 /* Can submit an audit record. */
+
+/*
+ * Credential management privileges.
+ */
+#define PRIV_CRED_SETUID 50 /* setuid. */
+#define PRIV_CRED_SETEUID 51 /* seteuid to !ruid and !svuid. */
+#define PRIV_CRED_SETGID 52 /* setgid. */
+#define PRIV_CRED_SETEGID 53 /* setgid to !rgid and !svgid. */
+#define PRIV_CRED_SETGROUPS 54 /* Set process additional groups. */
+#define PRIV_CRED_SETREUID 55 /* setreuid. */
+#define PRIV_CRED_SETREGID 56 /* setregid. */
+#define PRIV_CRED_SETRESUID 57 /* setresuid. */
+#define PRIV_CRED_SETRESGID 58 /* setresgid. */
+#define PRIV_SEEOTHERGIDS 59 /* Exempt bsd.seeothergids. */
+#define PRIV_SEEOTHERUIDS 60 /* Exempt bsd.seeotheruids. */
+
+/*
+ * Debugging privileges.
+ */
+#define PRIV_DEBUG_DIFFCRED 80 /* Exempt debugging other users. */
+#define PRIV_DEBUG_SUGID 81 /* Exempt debugging setuid proc. */
+#define PRIV_DEBUG_UNPRIV 82 /* Exempt unprivileged debug limit. */
+
+/*
+ * Dtrace privileges.
+ */
+#define PRIV_DTRACE_KERNEL 90 /* Allow use of DTrace on the kernel. */
+#define PRIV_DTRACE_PROC 91 /* Allow attaching DTrace to process. */
+#define PRIV_DTRACE_USER 92 /* Process may submit DTrace events. */
+
+/*
+ * Firmware privilegs.
+ */
+#define PRIV_FIRMWARE_LOAD 100 /* Can load firmware. */
+
+/*
+ * Jail privileges.
+ */
+#define PRIV_JAIL_ATTACH 110 /* Attach to a jail. */
+
+/*
+ * Kernel environment priveleges.
+ */
+#define PRIV_KENV_SET 120 /* Set kernel env. variables. */
+#define PRIV_KENV_UNSET 121 /* Unset kernel env. variables. */
+
+/*
+ * Loadable kernel module privileges.
+ */
+#define PRIV_KLD_LOAD 130 /* Load a kernel module. */
+#define PRIV_KLD_UNLOAD 131 /* Unload a kernel module. */
+
+/*
+ * Privileges associated with the MAC Framework and specific MAC policy
+ * modules.
+ */
+#define PRIV_MAC_PARTITION 140 /* Privilege in mac_partition policy. */
+#define PRIV_MAC_PRIVS 141 /* Privilege in the mac_privs policy. */
+
+/*
+ * Process-related privileges.
+ */
+#define PRIV_PROC_LIMIT 160 /* Exceed user process limit. */
+#define PRIV_PROC_SETLOGIN 161 /* Can call setlogin. */
+#define PRIV_PROC_SETRLIMIT 162 /* Can raise resources limits. */
+
+/* System V IPC privileges.
+ */
+#define PRIV_IPC_READ 170 /* Can override IPC read perm. */
+#define PRIV_IPC_WRITE 171 /* Can override IPC write perm. */
+#define PRIV_IPC_EXEC 172 /* Can override IPC exec perm. */
+#define PRIV_IPC_ADMIN 173 /* Can override IPC owner-only perm. */
+#define PRIV_IPC_MSGSIZE 174 /* Exempt IPC message queue limit. */
+
+/*
+ * POSIX message queue privileges.
+ */
+#define PRIV_MQ_ADMIN 180 /* Can override msgq owner-only perm. */
+
+/*
+ * Performance monitoring counter privileges.
+ */
+#define PRIV_PMC_MANAGE 190 /* Can administer PMC. */
+#define PRIV_PMC_SYSTEM 191 /* Can allocate a system-wide PMC. */
+
+/*
+ * Scheduling privileges.
+ */
+#define PRIV_SCHED_DIFFCRED 200 /* Exempt scheduling other users. */
+#define PRIV_SCHED_SETPRIORITY 201 /* Can set lower nice value for proc. */
+#define PRIV_SCHED_RTPRIO 202 /* Can set real time scheduling. */
+#define PRIV_SCHED_SETPOLICY 203 /* Can set scheduler policy. */
+#define PRIV_SCHED_SET 204 /* Can set thread scheduler. */
+#define PRIV_SCHED_SETPARAM 205 /* Can set thread scheduler params. */
+
+/*
+ * POSIX semaphore privileges.
+ */
+#define PRIV_SEM_WRITE 220 /* Can override sem write perm. */
+
+/*
+ * Signal privileges.
+ */
+#define PRIV_SIGNAL_DIFFCRED 230 /* Exempt signalling other users. */
+#define PRIV_SIGNAL_SUGID 231 /* Non-conserv signal setuid proc. */
+
+/*
+ * Sysctl privileges.
+ */
+#define PRIV_SYSCTL_DEBUG 240 /* Can invoke sysctl.debug. */
+#define PRIV_SYSCTL_WRITE 241 /* Can write sysctls. */
+#define PRIV_SYSCTL_WRITEJAIL 242 /* Can write sysctls, jail permitted. */
+
+/*
+ * TTY privileges.
+ */
+#define PRIV_TTY_CONSOLE 250 /* Set console to tty. */
+#define PRIV_TTY_DRAINWAIT 251 /* Set tty drain wait time. */
+#define PRIV_TTY_DTRWAIT 252 /* Set DTR wait on tty. */
+#define PRIV_TTY_EXCLUSIVE 253 /* Override tty exclusive flag. */
+#define PRIV_TTY_PRISON 254 /* Can open pts across jails. */
+#define PRIV_TTY_STI 255 /* Simulate input on another tty. */
+#define PRIV_TTY_SETA 256 /* Set tty termios structure. */
+
+/*
+ * UFS-specific privileges.
+ */
+#define PRIV_UFS_EXTATTRCTL 270 /* Can configure EAs on UFS1. */
+#define PRIV_UFS_GETQUOTA 271 /* getquota(). */
+#define PRIV_UFS_QUOTAOFF 272 /* quotaoff(). */
+#define PRIV_UFS_QUOTAON 273 /* quotaon(). */
+#define PRIV_UFS_SETQUOTA 274 /* setquota(). */
+#define PRIV_UFS_SETUSE 275 /* setuse(). */
+#define PRIV_UFS_EXCEEDQUOTA 276 /* Exempt from quota restrictions. */
+
+/*
+ * VFS privileges.
+ */
+#define PRIV_VFS_READ 310 /* Override vnode DAC read perm. */
+#define PRIV_VFS_WRITE 311 /* Override vnode DAC write perm. */
+#define PRIV_VFS_ADMIN 312 /* Override vnode DAC admin perm. */
+#define PRIV_VFS_EXEC 313 /* Override vnode DAC exec perm. */
+#define PRIV_VFS_LOOKUP 314 /* Override vnode DAC lookup perm. */
+#define PRIV_VFS_BLOCKRESERVE 315 /* Can use free block reserve. */
+#define PRIV_VFS_CHFLAGS_DEV 316 /* Can chflags() a device node. */
+#define PRIV_VFS_CHOWN 317 /* Can set user; group to non-member. */
+#define PRIV_VFS_CHROOT 318 /* chroot(). */
+#define PRIV_VFS_CLEARSUGID 319 /* Don't clear sugid on change. */
+#define PRIV_VFS_EXTATTR_SYSTEM 320 /* Operate on system EA namespace. */
+#define PRIV_VFS_FCHROOT 321 /* fchroot(). */
+#define PRIV_VFS_FHOPEN 322 /* Can fhopen(). */
+#define PRIV_VFS_FHSTAT 323 /* Can fhstat(). */
+#define PRIV_VFS_FHSTATFS 324 /* Can fhstatfs(). */
+#define PRIV_VFS_GENERATION 325 /* stat() returns generation number. */
+#define PRIV_VFS_GETFH 326 /* Can retrieve file handles. */
+#define PRIV_VFS_LINK 327 /* bsd.hardlink_check_uid */
+#define PRIV_VFS_MKNOD_BAD 328 /* Can mknod() to mark bad inodes. */
+#define PRIV_VFS_MKNOD_DEV 329 /* Can mknod() to create dev nodes. */
+#define PRIV_VFS_MKNOD_WHT 330 /* Can mknod() to create whiteout. */
+#define PRIV_VFS_MOUNT 331 /* Can mount(). */
+#define PRIV_VFS_MOUNT_OWNER 332 /* Override owner on user mounts. */
+#define PRIV_VFS_MOUNT_EXPORTED 333 /* Can set MNT_EXPORTED on mount. */
+#define PRIV_VFS_MOUNT_PERM 334 /* Override dev node perms at mount. */
+#define PRIV_VFS_MOUNT_SUIDDIR 335 /* Can set MNT_SUIDDIR on mount. */
+#define PRIV_VFS_MOUNT_NONUSER 336 /* Can perform a non-user mount. */
+#define PRIV_VFS_SETGID 337 /* Can setgid if not in group. */
+#define PRIV_VFS_STICKYFILE 338 /* Can set sticky bit on file. */
+#define PRIV_VFS_SYSFLAGS 339 /* Can modify system flags. */
+#define PRIV_VFS_UNMOUNT 340 /* Can unmount(). */
+
+/*
+ * Virtual memory privileges.
+ */
+#define PRIV_VM_MADV_PROTECT 360 /* Can set MADV_PROTECT. */
+#define PRIV_VM_MLOCK 361 /* Can mlock(), mlockall(). */
+#define PRIV_VM_MUNLOCK 362 /* Can munlock(), munlockall(). */
+
+/*
+ * Device file system privileges.
+ */
+#define PRIV_DEVFS_RULE 370 /* Can manage devfs rules. */
+#define PRIV_DEVFS_SYMLINK 371 /* Can create symlinks in devfs. */
+
+/*
+ * Random number generator privileges.
+ */
+#define PRIV_RANDOM_RESEED 380 /* Closing /dev/random reseeds. */
+
+/*
+ * Network stack privileges.
+ */
+#define PRIV_NET_BRIDGE 390 /* Administer bridge. */
+#define PRIV_NET_GRE 391 /* Administer GRE. */
+#define PRIV_NET_PPP 392 /* Administer PPP. */
+#define PRIV_NET_SLIP 393 /* Administer SLIP. */
+#define PRIV_NET_BPF 394 /* Monitor BPF. */
+#define PRIV_NET_RAW 395 /* Open raw socket. */
+#define PRIV_NET_ROUTE 396 /* Administer routing. */
+#define PRIV_NET_TAP 397 /* Can open tap device. */
+#define PRIV_NET_SETIFMTU 398 /* Set interface MTU. */
+#define PRIV_NET_SETIFFLAGS 399 /* Set interface flags. */
+#define PRIV_NET_SETIFCAP 400 /* Set interface capabilities. */
+#define PRIV_NET_SETIFNAME 401 /* Set interface name. */
+#define PRIV_NET_SETIFMETRIC 402 /* Set interface metrics. */
+#define PRIV_NET_SETIFPHYS 403 /* Set interface physical layer prop. */
+#define PRIV_NET_SETIFMAC 404 /* Set interface MAC label. */
+#define PRIV_NET_ADDMULTI 405 /* Add multicast addr. to ifnet. */
+#define PRIV_NET_DELMULTI 406 /* Delete multicast addr. from ifnet. */
+#define PRIV_NET_HWIOCTL 507 /* Issue hardware ioctl on ifnet. */
+#define PRIV_NET_SETLLADDR 508
+#define PRIV_NET_ADDIFGROUP 509 /* Add new interface group. */
+#define PRIV_NET_DELIFGROUP 510 /* Delete interface group. */
+#define PRIV_NET_IFCREATE 511 /* Create cloned interface. */
+#define PRIV_NET_IFDESTROY 512 /* Destroy cloned interface. */
+#define PRIV_NET_ADDIFADDR 513 /* Add protocol addr to interface. */
+#define PRIV_NET_DELIFADDR 514 /* Delete protocol addr on interface. */
+
+/*
+ * 802.11-related privileges.
+ */
+#define PRIV_NET80211_GETKEY 540 /* Query 802.11 keys. */
+#define PRIV_NET80211_MANAGE 541 /* Administer 802.11. */
+
+/*
+ * AppleTalk privileges.
+ */
+#define PRIV_NETATALK_RESERVEDPORT 550 /* Bind low port number. */
+
+/*
+ * ATM privileges.
+ */
+#define PRIV_NETATM_CFG 560
+#define PRIV_NETATM_ADD 561
+#define PRIV_NETATM_DEL 562
+#define PRIV_NETATM_SET 563
+
+/*
+ * Bluetooth privileges.
+ */
+#define PRIV_NETBLUETOOTH_RAW 570 /* Open raw bluetooth socket. */
+
+/*
+ * Netgraph and netgraph module privileges.
+ */
+#define PRIV_NETGRAPH_CONTROL 580 /* Open netgraph control socket. */
+#define PRIV_NETGRAPH_TTY 581 /* Configure tty for netgraph. */
+
+/*
+ * IPv4 and IPv6 privileges.
+ */
+#define PRIV_NETINET_RESERVEDPORT 590 /* Bind low port number. */
+#define PRIV_NETINET_IPFW 591 /* Administer IPFW firewall. */
+#define PRIV_NETINET_DIVERT 592 /* Open IP divert socket. */
+#define PRIV_NETINET_PF 593 /* Administer pf firewall. */
+#define PRIV_NETINET_DUMMYNET 594 /* Administer DUMMYNET. */
+#define PRIV_NETINET_CARP 595 /* Administer CARP. */
+#define PRIV_NETINET_MROUTE 596 /* Administer multicast routing. */
+#define PRIV_NETINET_RAW 597 /* Open netinet raw socket. */
+#define PRIV_NETINET_GETCRED 598 /* Query netinet pcb credentials. */
+#define PRIV_NETINET_ADDRCTRL6 599 /* Administer IPv6 address scopes. */
+#define PRIV_NETINET_ND6 600 /* Administer IPv6 neighbor disc. */
+#define PRIV_NETINET_SCOPE6 601 /* Administer IPv6 address scopes. */
+#define PRIV_NETINET_ALIFETIME6 602 /* Administer IPv6 address lifetimes. */
+#define PRIV_NETINET_IPSEC 603 /* Administer IPSEC. */
+
+/*
+ * IPX/SPX privileges.
+ */
+#define PRIV_NETIPX_RESERVEDPORT 620 /* Bind low port number. */
+#define PRIV_NETIPX_RAW 621 /* Open netipx raw socket. */
+
+/*
+ * NCP privileges.
+ */
+#define PRIV_NETNCP 630 /* Use another user's connection. */
+
+/*
+ * SMB privileges.
+ */
+#define PRIV_NETSMB 640 /* Use another user's connection. */
+
+/*
+ * VM86 privileges.
+ */
+#define PRIV_VM86_INTCALL 650/* Allow invoking vm86 int handlers. */
+
+/*
+ * Set of reserved privilege values, which will be allocated to code as
+ * needed, in order to avoid renumbering later privileges due to insertion.
+ */
+#define _PRIV_RESERVED0 660
+#define _PRIV_RESERVED1 661
+#define _PRIV_RESERVED2 662
+#define _PRIV_RESERVED3 663
+#define _PRIV_RESERVED4 664
+#define _PRIV_RESERVED5 665
+#define _PRIV_RESERVED6 666
+#define _PRIV_RESERVED7 667
+#define _PRIV_RESERVED8 668
+#define _PRIV_RESERVED9 669
+#define _PRIV_RESERVED10 670
+#define _PRIV_RESERVED11 671
+#define _PRIV_RESERVED12 672
+#define _PRIV_RESERVED13 673
+#define _PRIV_RESERVED14 674
+#define _PRIV_RESERVED15 675
+
+/*
+ * Define a set of valid privilege numbers that can be used by loadable
+ * modules that don't yet have privilege reservations. Ideally, these should
+ * not be used, since their meaning is opaque to any policies that are aware
+ * of specific privileges, such as jail, and as such may be arbitrarily
+ * denied.
+ */
+#define PRIV_MODULE0 700
+#define PRIV_MODULE1 701
+#define PRIV_MODULE2 702
+#define PRIV_MODULE3 703
+#define PRIV_MODULE4 704
+#define PRIV_MODULE5 705
+#define PRIV_MODULE6 706
+#define PRIV_MODULE7 707
+#define PRIV_MODULE8 708
+#define PRIV_MODULE9 709
+#define PRIV_MODULE10 710
+#define PRIV_MODULE11 711
+#define PRIV_MODULE12 712
+#define PRIV_MODULE13 713
+#define PRIV_MODULE14 714
+#define PRIV_MODULE15 715
+
+/*
+ * Track end of privilege list.
+ */
+#define _PRIV_HIGHEST 716
+
+/*
+ * Validate that a named privilege is known by the privilege system. Invalid
+ * privileges presented to the privilege system by a priv_check interface
+ * will result in a panic. This is only approximate due to sparse allocation
+ * of the privilege space.
+ */
+#define PRIV_VALID(x) ((x) > _PRIV_LOWEST && (x) < _PRIV_HIGHEST)
+
+#ifdef _KERNEL
+/*
+ * Privilege check interfaces, modeled after historic suser() interfacs, but
+ * with the addition of a specific privilege name. The existing SUSER_* flag
+ * name space is used here. The jail flag will likely be something that can
+ * be removed at some point as jail itself will be able to decide if the priv
+ * is appropriate, rather than the caller.
+ */
+struct thread;
+struct ucred;
+int priv_check(struct thread *td, int priv);
+int priv_check_cred(struct ucred *cred, int priv, int flags);
+#endif
+
+#endif /* !_SYS_PRIV_H_ */
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 2ad8858..f276a6c 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -230,7 +230,7 @@ void cpu_stopprofclock(void);
#define SUSER_RUID 2
int suser(struct thread *td);
-int suser_cred(struct ucred *cred, int flag);
+int suser_cred(struct ucred *cred, int flags);
int cr_cansee(struct ucred *u1, struct ucred *u2);
int cr_canseesocket(struct ucred *cred, struct socket *so);
OpenPOWER on IntegriCloud