summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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