Dear all,

A month and a half ago, I posted a patch implementing a priv(9) API. I've now
updated this patch to reflect a more thorough review of kernel privilege,
corrected some of the nits, etc. I would like to move ahead with committing
priv(9), so this is a final request for review (or serious objections) before
I do so in a few days. The commit will occur in two phases:

(1) Commit of the base portions of the patch:

Modified Files:
sys/kern/kern_jail.c sys/kern/kern_prot.c
sys/security/mac/mac_framework.h
sys/security/mac/mac_internal.h sys/sys/jail.h sys/sys/systm.h
sys/conf/files share/man/man9/Makefile share/man/man9/suser.9
Added Files:
sys/kern/kern_priv.c sys/security/mac/mac_priv.c
sys/sys/priv.h share/man/man9/priv.9

Commit message for this attached below.

(2) Sweep of the remaining kernel files, cleaning up privilege checks,
replacing suser()/suser_cred() calls, etc, across the kernel.

Among other things, I'd like to be able to add some additional names to the
"Reviewed by:" list. :-) This is, of course, a set of highly sensitive
security-related changes, and having detailed reviews is very important.

The primary changes from the previous patch to this one are:

- Significant cleanup of the kern_jail.c code. It's now simply a list of
privileges granted in jail, with justifications.

- A number of tweaks and fixes to privilege use across the kernel. A moderate
number of the XXX's added in the previous patch are now fixed. Not all
though.

- The privilege list has changed from an enum to an int with #define's. This
has several benefits -- one is that there's no longer a concern about the C
limit of not being able to forward declare enumerated types. Also, since
the numeric assignment of privilege identifiers is part of the kernel ABI
for modules, I've moved to explicitly assigning privilege numbers, and have
left gaps for subsystem growth, etc.

A few XXX's still exist that will require some further attention, likely after
merging the patch. Pawel and I are also discussing whether there are some UFS
privileges that should become general VFS privileges such as quota bypass
privileges). Another concern is that there are one or two places where
privileges are inconsistently granted inside and outside of jail, and we will
want to either subdivide the privilege or move to a more consistent approach.
For this reason, the KASSERT() after prison_priv_check() in priv_check()
concerning the consistency of SUSER_ALLOWJAIL and the internal logic is
temporarily disabled. Once we've decided that all looks good with regard to
jail, I can sweep the kernel removing the SUSER_ALLOWJAIL arguments, and
complete the migration of jail configuration frobs to kern_jail.c from their
current scattered locations across the kernel.

Thanks,

Robert N M Watson
Computer Laboratory
University of Cambridge

> 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.
> Discussed on: arch@
> Reviewed (at least in part) by: mlaier, jmg



Index: share/man/man9/Makefile
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/share/man/man9/Makefile,v
retrieving revision 1.282
diff -u -r1.282 Makefile
--- share/man/man9/Makefile 5 Oct 2006 12:40:44 -0000 1.282
+++ share/man/man9/Makefile 31 Oct 2006 09:06:00 -0000
@@ -188,6 +188,7 @@
pmap_zero_page.9 \
printf.9 \
prison_check.9 \
+ priv.9 \
pseudofs.9 \
psignal.9 \
random.9 \
Index: share/man/man9/priv.9
================================================== =================
RCS file: share/man/man9/priv.9
diff -N share/man/man9/priv.9
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ share/man/man9/priv.9 31 Oct 2006 09:03:48 -0000
@@ -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, 2007
+.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.
Index: share/man/man9/suser.9
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/share/man/man9/suser.9,v
retrieving revision 1.29
diff -u -r1.29 suser.9
--- share/man/man9/suser.9 16 May 2006 22:58:43 -0000 1.29
+++ share/man/man9/suser.9 31 Oct 2006 09:05:47 -0000
@@ -54,6 +54,12 @@
.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 @@
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
Index: sys/amd64/amd64/io.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/amd64/amd64/io.c,v
retrieving revision 1.1
diff -u -r1.1 io.c
--- sys/amd64/amd64/io.c 1 Aug 2004 11:40:50 -0000 1.1
+++ sys/amd64/amd64/io.c 30 Oct 2006 17:07:54 -0000
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -54,7 +55,7 @@
{
int error;

- error = suser(td);
+ error = priv_check(td, PRIV_IO);
if (error != 0)
return (error);
error = securelevel_gt(td->td_ucred, 0);
Index: sys/compat/linux/linux_misc.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/compat/linux/linux_misc.c,v
retrieving revision 1.191
diff -u -r1.191 linux_misc.c
--- sys/compat/linux/linux_misc.c 28 Oct 2006 16:47:38 -0000 1.191
+++ sys/compat/linux/linux_misc.c 30 Oct 2006 17:07:54 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1020,7 +1021,8 @@
* Keep cr_groups[0] unchanged to prevent that.
*/

- if ((error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) {
+ if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS,
+ SUSER_ALLOWJAIL)) != 0) {
PROC_UNLOCK(p);
crfree(newcred);
return (error);
@@ -1341,7 +1343,7 @@
switch (args->cmd) {
case REBOOT_CAD_ON:
case REBOOT_CAD_OFF:
- return suser(td);
+ return (priv_check(td, PRIV_REBOOT));
case REBOOT_HALT:
bsd_args.opt = RB_HALT;
break;
Index: sys/compat/linux/linux_uid16.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/compat/linux/linux_uid16.c,v
retrieving revision 1.19
diff -u -r1.19 linux_uid16.c
--- sys/compat/linux/linux_uid16.c 19 Mar 2006 11:10:33 -0000 1.19
+++ sys/compat/linux/linux_uid16.c 30 Oct 2006 17:07:54 -0000
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -123,7 +124,8 @@
* Keep cr_groups[0] unchanged to prevent that.
*/

- if ((error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) {
+ if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS,
+ SUSER_ALLOWJAIL)) != 0) {
PROC_UNLOCK(p);
crfree(newcred);
return (error);
Index: sys/compat/svr4/svr4_fcntl.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/compat/svr4/svr4_fcntl.c,v
retrieving revision 1.38
diff -u -r1.38 svr4_fcntl.c
--- sys/compat/svr4/svr4_fcntl.c 22 Oct 2006 11:52:11 -0000 1.38
+++ sys/compat/svr4/svr4_fcntl.c 30 Oct 2006 17:07:54 -0000
@@ -44,6 +44,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -280,7 +281,8 @@
goto out;

if (td->td_ucred->cr_uid != vattr.va_uid &&
- (error = suser(td)) != 0)
+ (error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN,
+ SUSER_ALLOWJAIL)) != 0)
goto out;

if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
Index: sys/compat/svr4/svr4_misc.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/compat/svr4/svr4_misc.c,v
retrieving revision 1.90
diff -u -r1.90 svr4_misc.c
--- sys/compat/svr4/svr4_misc.c 22 Oct 2006 11:52:11 -0000 1.90
+++ sys/compat/svr4/svr4_misc.c 30 Oct 2006 17:07:54 -0000
@@ -52,6 +52,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -611,7 +612,8 @@
struct file *fp;
int error, vfslocked;

- if ((error = suser(td)) != 0)
+ if ((error = priv_check_cred(td->td_ucred, PRIV_VFS_FCHROOT,
+ SUSER_ALLOWJAIL)) != 0)
return error;
if ((error = getvnode(fdp, uap->fd, &fp)) != 0)
return error;
Index: sys/conf/files
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/conf/files,v
retrieving revision 1.1156
diff -u -r1.1156 files
--- sys/conf/files 30 Oct 2006 05:51:53 -0000 1.1156
+++ sys/conf/files 30 Oct 2006 21:24:56 -0000
@@ -1347,6 +1347,7 @@
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
@@ -1920,6 +1921,7 @@
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
Index: sys/contrib/altq/altq/altq_cbq.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_cbq.c,v
retrieving revision 1.3
diff -u -r1.3 altq_cbq.c
--- sys/contrib/altq/altq/altq_cbq.c 9 Aug 2005 10:19:41 -0000 1.3
+++ sys/contrib/altq/altq/altq_cbq.c 30 Oct 2006 17:07:54 -0000
@@ -1062,7 +1062,9 @@
/* currently only command that an ordinary user can call */
break;
default:
-#if (__FreeBSD_version > 400000)
+#if (__FreeBSD_version > 700000)
+ error = priv_check(p, PRIV_ALTQ_MANAGE);
+#elsif (__FreeBSD_version > 400000)
error = suser(p);
#else
error = suser(p->p_ucred, &p->p_acflag);
Index: sys/contrib/altq/altq/altq_cdnr.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_cdnr.c,v
retrieving revision 1.2
diff -u -r1.2 altq_cdnr.c
--- sys/contrib/altq/altq/altq_cdnr.c 12 Jun 2004 00:57:20 -0000 1.2
+++ sys/contrib/altq/altq/altq_cdnr.c 30 Oct 2006 17:07:54 -0000
@@ -1262,7 +1262,9 @@
case CDNR_GETSTATS:
break;
default:
-#if (__FreeBSD_version > 400000)
+#if (__FreeBSD_versoin > 700000)
+ if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0)
+#elsif (__FreeBSD_version > 400000)
if ((error = suser(p)) != 0)
#else
if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
Index: sys/contrib/altq/altq/altq_hfsc.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_hfsc.c,v
retrieving revision 1.2
diff -u -r1.2 altq_hfsc.c
--- sys/contrib/altq/altq/altq_hfsc.c 12 Jun 2004 00:57:20 -0000 1.2
+++ sys/contrib/altq/altq/altq_hfsc.c 30 Oct 2006 17:07:54 -0000
@@ -1975,7 +1975,10 @@
case HFSC_GETSTATS:
break;
default:
-#if (__FreeBSD_version > 400000)
+#if (__FreeBSD_version > 700000)
+ if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0)
+ return (error);
+#elsif (__FreeBSD_version > 400000)
if ((error = suser(p)) != 0)
return (error);
#else
Index: sys/contrib/altq/altq/altq_priq.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_priq.c,v
retrieving revision 1.2
diff -u -r1.2 altq_priq.c
--- sys/contrib/altq/altq/altq_priq.c 12 Jun 2004 00:57:20 -0000 1.2
+++ sys/contrib/altq/altq/altq_priq.c 30 Oct 2006 17:07:54 -0000
@@ -772,7 +772,10 @@
case PRIQ_GETSTATS:
break;
default:
-#if (__FreeBSD_version > 400000)
+#if (__FreeBSD_version > 700000)
+ if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0)
+ return (error);
+#elsif (__FreeBSD_version > 400000)
if ((error = suser(p)) != 0)
return (error);
#else
Index: sys/contrib/altq/altq/altq_red.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_red.c,v
retrieving revision 1.2
diff -u -r1.2 altq_red.c
--- sys/contrib/altq/altq/altq_red.c 12 Jun 2004 00:57:20 -0000 1.2
+++ sys/contrib/altq/altq/altq_red.c 30 Oct 2006 17:07:54 -0000
@@ -781,7 +781,9 @@
case RED_GETSTATS:
break;
default:
-#if (__FreeBSD_version > 400000)
+#if (__FreeBSD_version > 700000)
+ if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0)
+#elsif (__FreeBSD_version > 400000)
if ((error = suser(p)) != 0)
#else
if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
Index: sys/contrib/altq/altq/altq_rio.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_rio.c,v
retrieving revision 1.3
diff -u -r1.3 altq_rio.c
--- sys/contrib/altq/altq/altq_rio.c 10 Jun 2005 16:49:03 -0000 1.3
+++ sys/contrib/altq/altq/altq_rio.c 30 Oct 2006 17:07:54 -0000
@@ -531,7 +531,10 @@
case RIO_GETSTATS:
break;
default:
-#if (__FreeBSD_version > 400000)
+#if (__FreeBSD_versoin > 700000)
+ if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0)
+ return (error);
+#elsif (__FreeBSD_version > 400000)
if ((error = suser(p)) != 0)
return (error);
#else
Index: sys/contrib/pf/net/if_pfsync.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/pf/net/if_pfsync.c,v
retrieving revision 1.30
diff -u -r1.30 if_pfsync.c
--- sys/contrib/pf/net/if_pfsync.c 9 Jul 2006 06:04:01 -0000 1.30
+++ sys/contrib/pf/net/if_pfsync.c 30 Oct 2006 17:07:54 -0000
@@ -54,6 +54,9 @@
#endif

#include
+#ifdef __FreeBSD__
+#include
+#endif
#include
#include
#include
@@ -1057,7 +1060,7 @@
break;
case SIOCSETPFSYNC:
#ifdef __FreeBSD__
- if ((error = suser(curthread)) != 0)
+ if ((error = priv_check(curthread, PRIV_NETINET_PF)) != 0)
#else
if ((error = suser(p, p->p_acflag)) != 0)
#endif
Index: sys/dev/an/if_an.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/an/if_an.c,v
retrieving revision 1.79
diff -u -r1.79 if_an.c
--- sys/dev/an/if_an.c 16 May 2006 14:36:22 -0000 1.79
+++ sys/dev/an/if_an.c 30 Oct 2006 17:07:54 -0000
@@ -92,6 +92,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1920,7 +1921,7 @@
break;
#ifdef ANCACHE
if (sc->areq.an_type == AN_RID_ZERO_CACHE) {
- error = suser(td);
+ error = priv_check(td, PRIV_DRIVER);
if (error)
break;
sc->an_sigitems = sc->an_nextitem = 0;
@@ -1944,7 +1945,7 @@
error = copyout(&sc->areq, ifr->ifr_data, sizeof(sc->areq));
break;
case SIOCSAIRONET:
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_DRIVER)))
goto out;
error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq));
if (error != 0)
@@ -1952,7 +1953,7 @@
an_setdef(sc, &sc->areq);
break;
case SIOCGPRIVATE_0: /* used by Cisco client utility */
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_DRIVER)))
goto out;
error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl));
if (error)
@@ -1974,7 +1975,7 @@
}
break;
case SIOCGPRIVATE_1: /* used by Cisco client utility */
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_DRIVER)))
goto out;
error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl));
if (error)
@@ -2226,7 +2227,7 @@
}
break;
case SIOCS80211:
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_NET80211_MANAGE)))
goto out;
sc->areq.an_len = sizeof(sc->areq);
/*
Index: sys/dev/arl/if_arl.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/arl/if_arl.c,v
retrieving revision 1.13
diff -u -r1.13 if_arl.c
--- sys/dev/arl/if_arl.c 16 May 2006 14:36:23 -0000 1.13
+++ sys/dev/arl/if_arl.c 30 Oct 2006 17:07:54 -0000
@@ -43,6 +43,7 @@
#include
#include
#include
+#include
#include
#include

@@ -504,7 +505,7 @@
break;

case SIOCS80211:
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_NET80211_MANAGE)))
break;
switch (ireq->i_type) {
case IEEE80211_IOC_SSID:
@@ -577,7 +578,7 @@
}
case SIOCGARLALL:
bzero(&arlan_io, sizeof(arlan_io));
- if (!suser(td)) {
+ if (!priv_check(td, PRIV_DRIVER)) {
bcopy(ar->systemId, arlan_io.cfg.sid, 4);
}

@@ -616,7 +617,7 @@
} while (0)

case SIOCSARLALL:
- if (suser(td))
+ if (priv_check(td, PRIV_DRIVER))
break;

user = (void *)ifr->ifr_data;
Index: sys/dev/asr/asr.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/asr/asr.c,v
retrieving revision 1.79
diff -u -r1.79 asr.c
--- sys/dev/asr/asr.c 31 Oct 2006 05:53:26 -0000 1.79
+++ sys/dev/asr/asr.c 31 Oct 2006 08:40:40 -0000
@@ -117,6 +117,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -3145,7 +3146,7 @@
s = splcam ();
if (ASR_ctlr_held) {
error = EBUSY;
- } else if ((error = suser(td)) == 0) {
+ } else if ((error = priv_check(td, PRIV_DRIVER)) == 0) {
++ASR_ctlr_held;
}
splx(s);
Index: sys/dev/ata/atapi-cd.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/ata/atapi-cd.c,v
retrieving revision 1.189
diff -u -r1.189 atapi-cd.c
--- sys/dev/ata/atapi-cd.c 28 Jun 2006 15:04:10 -0000 1.189
+++ sys/dev/ata/atapi-cd.c 30 Oct 2006 17:07:54 -0000
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -257,8 +258,11 @@
cdp->flags |= F_LOCKED;
break;

+ /*
+ * XXXRW: Why does this require privilege?
+ */
case CDIOCRESET:
- error = suser(td);
+ error = priv_check(td, PRIV_DRIVER);
if (error)
break;
error = acd_test_ready(dev);
Index: sys/dev/ce/if_ce.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/ce/if_ce.c,v
retrieving revision 1.3
diff -u -r1.3 if_ce.c
--- sys/dev/ce/if_ce.c 3 Feb 2006 20:55:30 -0000 1.3
+++ sys/dev/ce/if_ce.c 30 Oct 2006 17:07:54 -0000
@@ -29,6 +29,7 @@
#if NPCI > 0

#include
+#include
#include
#include
#include
@@ -1341,9 +1342,11 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else /* __FreeBSD_version >= 500000 */
+#elsif __FreeBSD_version < 700000
error = suser (td);
-#endif /* __FreeBSD_version >= 500000 */
+#else
+ error = priv_check (td, PRIV_DRIVER);
+#endif
if (error)
return error;
#if __FreeBSD_version >= 600034
@@ -1380,8 +1383,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1408,8 +1413,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1426,8 +1433,10 @@
CE_DEBUG2 (d, ("ioctl: setcfg\n"));
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1526,8 +1535,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1560,8 +1571,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1586,8 +1599,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1608,8 +1623,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1634,8 +1651,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1658,8 +1677,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1686,8 +1707,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1708,8 +1731,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1734,8 +1759,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1758,8 +1785,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1784,8 +1813,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1810,8 +1841,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1836,8 +1869,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1867,8 +1902,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1892,8 +1929,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1909,8 +1948,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
@@ -1945,8 +1986,10 @@
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
-#else
+#elsif __FreeBSD_version < 700000
error = suser (td);
+#else
+ error = priv_check (td, PRIV_DRIVER);
#endif
if (error)
return error;
Index: sys/dev/cnw/if_cnw.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/cnw/if_cnw.c,v
retrieving revision 1.23
diff -u -r1.23 if_cnw.c
--- sys/dev/cnw/if_cnw.c 16 May 2006 14:36:23 -0000 1.23
+++ sys/dev/cnw/if_cnw.c 30 Oct 2006 17:07:54 -0000
@@ -236,6 +236,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1339,7 +1340,7 @@
#if !defined(__FreeBSD__)
error = suser(p->p_ucred, &p->p_acflag);
#else
- error = suser(td);
+ error = priv_check(td, PRIV_DRIVER);
#endif
if (error)
break;
@@ -1350,7 +1351,7 @@
#if !defined(__FreeBSD__)
error = suser(p->p_ucred, &p->p_acflag);
#else
- error = suser(td);
+ error = priv_check(td, PRIV_DRIVER);
#endif
if (error)
break;
@@ -1361,7 +1362,7 @@
#if !defined(__FreeBSD__)
error = suser(p->p_ucred, &p->p_acflag);
#else
- error = suser(td);
+ error = priv_check(td, PRIV_DRIVER);
#endif
if (error)
break;
Index: sys/dev/cp/if_cp.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/cp/if_cp.c,v
retrieving revision 1.29
diff -u -r1.29 if_cp.c
--- sys/dev/cp/if_cp.c 27 Sep 2005 16:57:44 -0000 1.29
+++ sys/dev/cp/if_cp.c 30 Oct 2006 17:07:54 -0000
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1071,7 +1072,7 @@
case SERIAL_SETPROTO:
CP_DEBUG2 (d, ("ioctl: setproto\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (d->ifp->if_drv_flags & IFF_DRV_RUNNING)
@@ -1102,7 +1103,7 @@
case SERIAL_SETKEEPALIVE:
CP_DEBUG2 (d, ("ioctl: setkeepalive\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if ((IFP2SP(d->ifp)->pp_flags & PP_FR) ||
@@ -1126,7 +1127,7 @@

case SERIAL_SETMODE:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (*(int*)data != SERIAL_HDLC)
@@ -1142,7 +1143,7 @@

case SERIAL_SETCFG:
CP_DEBUG2 (d, ("ioctl: setcfg\n"));
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_E1)
@@ -1239,7 +1240,7 @@
case SERIAL_CLRSTAT:
CP_DEBUG2 (d, ("ioctl: clrstat\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
c->rintr = 0;
@@ -1268,7 +1269,7 @@
case SERIAL_SETBAUD:
CP_DEBUG2 (d, ("ioctl: setbaud\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1286,7 +1287,7 @@
case SERIAL_SETLOOP:
CP_DEBUG2 (d, ("ioctl: setloop\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1306,7 +1307,7 @@
case SERIAL_SETDPLL:
CP_DEBUG2 (d, ("ioctl: setdpll\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_SERIAL)
@@ -1328,7 +1329,7 @@
case SERIAL_SETNRZI:
CP_DEBUG2 (d, ("ioctl: setnrzi\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_SERIAL)
@@ -1348,7 +1349,7 @@
case SERIAL_SETDEBUG:
CP_DEBUG2 (d, ("ioctl: setdebug\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
d->chan->debug = *(int*)data;
@@ -1370,7 +1371,7 @@
case SERIAL_SETHIGAIN:
CP_DEBUG2 (d, ("ioctl: sethigain\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_E1)
@@ -1392,7 +1393,7 @@
case SERIAL_SETPHONY:
CP_DEBUG2 (d, ("ioctl: setphony\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_E1)
@@ -1414,7 +1415,7 @@
case SERIAL_SETUNFRAM:
CP_DEBUG2 (d, ("ioctl: setunfram\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_E1)
@@ -1436,7 +1437,7 @@
case SERIAL_SETSCRAMBLER:
CP_DEBUG2 (d, ("ioctl: setscrambler\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_G703 && !c->unfram)
@@ -1461,7 +1462,7 @@
case SERIAL_SETMONITOR:
CP_DEBUG2 (d, ("ioctl: setmonitor\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_E1)
@@ -1483,7 +1484,7 @@
case SERIAL_SETUSE16:
CP_DEBUG2 (d, ("ioctl: setuse16\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_E1)
@@ -1505,7 +1506,7 @@
case SERIAL_SETCRC4:
CP_DEBUG2 (d, ("ioctl: setcrc4\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_E1)
@@ -1538,7 +1539,7 @@
case SERIAL_SETCLK:
CP_DEBUG2 (d, ("ioctl: setclk\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_E1 &&
@@ -1571,7 +1572,7 @@
case SERIAL_SETTIMESLOTS:
CP_DEBUG2 (d, ("ioctl: settimeslots\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if ((c->type != T_E1 || c->unfram) && c->type != T_DATA)
@@ -1597,7 +1598,7 @@
case SERIAL_SETINVCLK:
CP_DEBUG2 (d, ("ioctl: setinvclk\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_SERIAL)
@@ -1620,7 +1621,7 @@
case SERIAL_SETINVTCLK:
CP_DEBUG2 (d, ("ioctl: setinvtclk\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_SERIAL)
@@ -1642,7 +1643,7 @@
case SERIAL_SETINVRCLK:
CP_DEBUG2 (d, ("ioctl: setinvrclk\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->type != T_SERIAL)
@@ -1669,7 +1670,7 @@
case SERIAL_RESET:
CP_DEBUG2 (d, ("ioctl: reset\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1682,7 +1683,7 @@
case SERIAL_HARDRESET:
CP_DEBUG2 (d, ("ioctl: hardreset\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1714,7 +1715,7 @@
case SERIAL_SETDIR:
CP_DEBUG2 (d, ("ioctl: setdir\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1739,7 +1740,7 @@
if (c->type != T_E3 && c->type != T_T3 && c->type != T_STS1)
return EINVAL;
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1761,7 +1762,7 @@
if (c->type != T_T3 && c->type != T_STS1)
return EINVAL;
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
Index: sys/dev/ctau/if_ct.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/ctau/if_ct.c,v
retrieving revision 1.29
diff -u -r1.29 if_ct.c
--- sys/dev/ctau/if_ct.c 16 May 2006 14:36:24 -0000 1.29
+++ sys/dev/ctau/if_ct.c 30 Oct 2006 17:07:54 -0000
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1300,7 +1301,7 @@

case SERIAL_SETPROTO:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (d->ifp->if_drv_flags & IFF_DRV_RUNNING)
@@ -1328,7 +1329,7 @@

case SERIAL_SETKEEPALIVE:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if ((IFP2SP(d->ifp)->pp_flags & PP_FR) ||
@@ -1357,7 +1358,7 @@

case SERIAL_SETCFG:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->mode == M_HDLC)
@@ -1435,7 +1436,7 @@

case SERIAL_CLRSTAT:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
c->rintr = 0;
@@ -1458,7 +1459,7 @@

case SERIAL_SETBAUD:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1474,7 +1475,7 @@

case SERIAL_SETLOOP:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1492,7 +1493,7 @@

case SERIAL_SETDPLL:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->mode == M_E1 || c->mode == M_G703)
@@ -1512,7 +1513,7 @@

case SERIAL_SETNRZI:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->mode == M_E1 || c->mode == M_G703)
@@ -1530,7 +1531,7 @@

case SERIAL_SETDEBUG:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
c->debug = *(int*)data;
@@ -1550,7 +1551,7 @@

case SERIAL_SETHIGAIN:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1572,7 +1573,7 @@
if (c->mode != M_E1)
return EINVAL;
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1595,7 +1596,7 @@

case SERIAL_SETCLK:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1619,7 +1620,7 @@

case SERIAL_SETTIMESLOTS:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1637,7 +1638,7 @@

case SERIAL_SETSUBCHAN:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splimp ();
@@ -1663,7 +1664,7 @@
case SERIAL_SETINVCLK:
case SERIAL_SETINVTCLK:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->mode == M_E1 || c->mode == M_G703)
@@ -1677,7 +1678,7 @@

case SERIAL_SETINVRCLK:
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->mode == M_E1 || c->mode == M_G703)
Index: sys/dev/cx/if_cx.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/cx/if_cx.c,v
retrieving revision 1.52
diff -u -r1.52 if_cx.c
--- sys/dev/cx/if_cx.c 16 May 2006 14:36:24 -0000 1.52
+++ sys/dev/cx/if_cx.c 30 Oct 2006 17:07:54 -0000
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1632,7 +1633,7 @@
case SERIAL_SETPORT:
CX_DEBUG2 (d, ("ioctl: setproto\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;

@@ -1658,7 +1659,7 @@
case SERIAL_SETPROTO:
CX_DEBUG2 (d, ("ioctl: setproto\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->mode == M_ASYNC)
@@ -1695,7 +1696,7 @@
case SERIAL_SETKEEPALIVE:
CX_DEBUG2 (d, ("ioctl: setkeepalive\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if ((IFP2SP(d->ifp)->pp_flags & PP_FR) ||
@@ -1725,7 +1726,7 @@
case SERIAL_SETMODE:
CX_DEBUG2 (d, ("ioctl: setmode\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;

@@ -1778,7 +1779,7 @@
case SERIAL_CLRSTAT:
CX_DEBUG2 (d, ("ioctl: clrstat\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splhigh ();
@@ -1810,7 +1811,7 @@
case SERIAL_SETBAUD:
CX_DEBUG2 (d, ("ioctl: setbaud\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->mode == M_ASYNC)
@@ -1836,7 +1837,7 @@
case SERIAL_SETLOOP:
CX_DEBUG2 (d, ("ioctl: setloop\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->mode == M_ASYNC)
@@ -1862,7 +1863,7 @@
case SERIAL_SETDPLL:
CX_DEBUG2 (d, ("ioctl: setdpll\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->mode == M_ASYNC)
@@ -1888,7 +1889,7 @@
case SERIAL_SETNRZI:
CX_DEBUG2 (d, ("ioctl: setnrzi\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
if (c->mode == M_ASYNC)
@@ -1912,7 +1913,7 @@
case SERIAL_SETDEBUG:
CX_DEBUG2 (d, ("ioctl: setdebug\n"));
/* Only for superuser! */
- error = suser (td);
+ error = priv_check (td, PRIV_DRIVER);
if (error)
return error;
s = splhigh ();
Index: sys/dev/dcons/dcons_os.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/dcons/dcons_os.c,v
retrieving revision 1.11
diff -u -r1.11 dcons_os.c
--- sys/dev/dcons/dcons_os.c 26 May 2006 13:51:38 -0000 1.11
+++ sys/dev/dcons/dcons_os.c 30 Oct 2006 17:07:54 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include

@@ -293,7 +294,8 @@
if ((tp->t_state & TS_ISOPEN) == 0) {
tp->t_state |= TS_CARR_ON;
ttyconsolemode(tp, 0);
- } else if ((tp->t_state & TS_XCLUDE) && suser(td)) {
+ } else if ((tp->t_state & TS_XCLUDE) &&
+ priv_check(td, PRIV_TTY_EXCLUSIVE)) {
splx(s);
return (EBUSY);
}
Index: sys/dev/drm/drmP.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/drm/drmP.h,v
retrieving revision 1.17
diff -u -r1.17 drmP.h
--- sys/dev/drm/drmP.h 7 Sep 2006 23:04:47 -0000 1.17
+++ sys/dev/drm/drmP.h 30 Oct 2006 17:07:54 -0000
@@ -50,6 +50,9 @@
#include
#include
#include
+#if __FreeBSD_version >= 700000
+#include
+#endif
#include
#include
#include
@@ -233,7 +236,11 @@

#define PAGE_ALIGN(addr) round_page(addr)
/* DRM_SUSER returns true if the user is superuser */
+#if __FreeBSD_version >= 700000
+#define DRM_SUSER(p) (priv_check(p, PRIV_DRIVER) == 0)
+#else
#define DRM_SUSER(p) (suser(p) == 0)
+#endif
#define DRM_AGP_FIND_DEVICE() agp_find_device()
#define DRM_MTRR_WC MDF_WRITECOMBINE
#define jiffies ticks
Index: sys/dev/fdc/fdc.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/fdc/fdc.c,v
retrieving revision 1.313
diff -u -r1.313 fdc.c
--- sys/dev/fdc/fdc.c 8 Sep 2006 21:46:00 -0000 1.313
+++ sys/dev/fdc/fdc.c 30 Oct 2006 17:07:54 -0000
@@ -69,6 +69,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1489,8 +1490,9 @@
return (0);

case FD_CLRERR:
- if (suser(td) != 0)
- return (EPERM);
+ error = priv_check(td, PRIV_DRIVER);
+ if (error)
+ return (error);
fd->fdc->fdc_errs = 0;
return (0);

Index: sys/dev/hwpmc/hwpmc_mod.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/hwpmc/hwpmc_mod.c,v
retrieving revision 1.25
diff -u -r1.25 hwpmc_mod.c
--- sys/dev/hwpmc/hwpmc_mod.c 17 Sep 2006 20:00:35 -0000 1.25
+++ sys/dev/hwpmc/hwpmc_mod.c 30 Oct 2006 17:07:54 -0000
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -2782,10 +2783,9 @@
KASSERT(td == curthread,
("[pmc,%d] td != curthread", __LINE__));

- if (suser(td) || jailed(td->td_ucred)) {
- error = EPERM;
+ error = priv_check(td, PRIV_PMC_MANAGE);
+ if (error)
break;
- }

if ((error = copyin(arg, &pma, sizeof(pma))) != 0)
break;
@@ -2918,11 +2918,16 @@
*/

if (PMC_IS_SYSTEM_MODE(mode)) {
- if (jailed(curthread->td_ucred))
- error = EPERM;
- else if (suser(curthread) &&
- (pmc_unprivileged_syspmcs == 0))
+ if (jailed(curthread->td_ucred)) {
error = EPERM;
+ break;
+ }
+ if (!pmc_unprivileged_syspmcs) {
+ error = priv_check(curthread,
+ PRIV_PMC_SYSTEM);
+ if (error)
+ break;
+ }
}

if (error)
Index: sys/dev/if_ndis/if_ndis.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/if_ndis/if_ndis.c,v
retrieving revision 1.117
diff -u -r1.117 if_ndis.c
--- sys/dev/if_ndis/if_ndis.c 4 Feb 2006 19:42:49 -0000 1.117
+++ sys/dev/if_ndis/if_ndis.c 30 Oct 2006 17:07:54 -0000
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -2836,7 +2837,7 @@
error = ENOTTY;
break;
case SIOCGDRVSPEC:
- if ((error = suser(curthread)))
+ if ((error = priv_check(curthread, PRIV_DRIVER)))
break;
error = copyin(ifr->ifr_data, &oid, sizeof(oid));
if (error)
@@ -2865,7 +2866,7 @@
free(oidbuf, M_TEMP);
break;
case SIOCSDRVSPEC:
- if ((error = suser(curthread)))
+ if ((error = priv_check(curthread, PRIV_DRIVER)))
break;
error = copyin(ifr->ifr_data, &oid, sizeof(oid));
if (error)
@@ -2894,7 +2895,7 @@
free(oidbuf, M_TEMP);
break;
case SIOCGPRIVATE_0:
- if ((error = suser(curthread)))
+ if ((error = priv_check(curthread, PRIV_DRIVER)))
break;
NDIS_LOCK(sc);
if (sc->ndis_evt[sc->ndis_evtcidx].ne_sts == 0) {
@@ -3062,7 +3063,7 @@
uint32_t foo;
int error, len;

- error = suser(curthread);
+ error = priv_check(curthread, PRIV_DRIVER);
if (error)
return (error);

@@ -3370,7 +3371,7 @@
break;
#endif
case IEEE80211_IOC_STATIONNAME:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NET80211_MANAGE);
if (error)
break;
if (ireq->i_val != 0 ||
Index: sys/dev/kbd/kbd.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/kbd/kbd.c,v
retrieving revision 1.45
diff -u -r1.45 kbd.c
--- sys/dev/kbd/kbd.c 28 Feb 2006 23:46:23 -0000 1.45
+++ sys/dev/kbd/kbd.c 30 Oct 2006 17:07:54 -0000
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -972,11 +973,11 @@
if (keymap_restrict_change >= 2) {
for (i = 0; i < NUM_STATES; i++)
if (oldkey->map[i] != newkey->map[i])
- return suser(td);
+ return priv_check(td, PRIV_KEYBOARD);
if (oldkey->spcl != newkey->spcl)
- return suser(td);
+ return priv_check(td, PRIV_KEYBOARD);
if (oldkey->flgs != newkey->flgs)
- return suser(td);
+ return priv_check(td, PRIV_KEYBOARD);
return (0);
}

@@ -991,7 +992,7 @@
if ((oldkey->spcl & (0x80 >> i)) == (newkey->spcl & (0x80 >> i))
&& oldkey->map[i] == newkey->map[i])
continue;
- return suser(td);
+ return priv_check(td, PRIV_KEYBOARD);
}

return (0);
@@ -1020,20 +1021,20 @@
return (0);

if (oldmap->n_accs != newmap->n_accs)
- return suser(td);
+ return priv_check(td, PRIV_KEYBOARD);

for (accent = 0; accent < oldmap->n_accs; accent++) {
oldacc = &oldmap->acc[accent];
newacc = &newmap->acc[accent];
if (oldacc->accchar != newacc->accchar)
- return suser(td);
+ return priv_check(td, PRIV_KEYBOARD);
for (i = 0; i < NUM_ACCENTCHARS; ++i) {
if (oldacc->map[i][0] != newacc->map[i][0])
- return suser(td);
+ return priv_check(td, PRIV_KEYBOARD);
if (oldacc->map[i][0] == 0) /* end of table */
break;
if (oldacc->map[i][1] != newacc->map[i][1])
- return suser(td);
+ return priv_check(td, PRIV_KEYBOARD);
}
}

@@ -1048,7 +1049,7 @@

if (oldkey->len != newkey->flen ||
bcmp(oldkey->str, newkey->keydef, oldkey->len) != 0)
- return suser(td);
+ return priv_check(td, PRIV_KEYBOARD);

return (0);
}
Index: sys/dev/lmc/if_lmc.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/lmc/if_lmc.c,v
retrieving revision 1.29
diff -u -r1.29 if_lmc.c
--- sys/dev/lmc/if_lmc.c 15 Jul 2006 02:07:38 -0000 1.29
+++ sys/dev/lmc/if_lmc.c 30 Oct 2006 17:07:55 -0000
@@ -113,6 +113,9 @@
# include
# include
# include
+# if (__FreeBSD_version >= 700000)
+# include
+# endif
# if (__FreeBSD_version >= 500000)
# include
# include
Index: sys/dev/lmc/if_lmc.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/lmc/if_lmc.h,v
retrieving revision 1.4
diff -u -r1.4 if_lmc.h
--- sys/dev/lmc/if_lmc.h 21 Jul 2006 08:45:00 -0000 1.4
+++ sys/dev/lmc/if_lmc.h 30 Oct 2006 17:07:55 -0000
@@ -1223,7 +1223,11 @@
# define TOP_UNLOCK mtx_unlock (&sc->top_mtx)
# define BOTTOM_TRYLOCK mtx_trylock(&sc->bottom_mtx)
# define BOTTOM_UNLOCK mtx_unlock (&sc->bottom_mtx)
-# define CHECK_CAP suser(curthread)
+# if (__FreeBSD_version >= 700000)
+# define CHECK_CAP priv_check(curthread, PRIV_DRIVER)
+# else
+# define CHECK_CAP suser(curthread)
+# endif
# else /* FreeBSD-4 */
# define TOP_TRYLOCK (sc->top_spl = splimp())
# define TOP_UNLOCK splx(sc->top_spl)
Index: sys/dev/nmdm/nmdm.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/nmdm/nmdm.c,v
retrieving revision 1.37
diff -u -r1.37 nmdm.c
--- sys/dev/nmdm/nmdm.c 4 Jan 2006 08:34:23 -0000 1.37
+++ sys/dev/nmdm/nmdm.c 30 Oct 2006 17:07:55 -0000
@@ -41,6 +41,7 @@

#include
#include
+#include
#include
#include
#include
@@ -286,7 +287,8 @@
if ((tp->t_state & TS_ISOPEN) == 0) {
ttyinitmode(tp, 0, 0);
ttsetwater(tp); /* XXX ? */
- } else if (tp->t_state & TS_XCLUDE && suser(td)) {
+ } else if (tp->t_state & TS_XCLUDE &&
+ priv_check(td, PRIV_TTY_EXCLUSIVE)) {
return (EBUSY);
}

Index: sys/dev/null/null.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/null/null.c,v
retrieving revision 1.31
diff -u -r1.31 null.c
--- sys/dev/null/null.c 27 Feb 2005 22:00:45 -0000 1.31
+++ sys/dev/null/null.c 30 Oct 2006 17:07:55 -0000
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -87,7 +88,7 @@

if (cmd != DIOCSKERNELDUMP)
return (ENOIOCTL);
- error = suser(td);
+ error = priv_check(td, PRIV_SETDUMPER);
if (error)
return (error);
return (set_dumper(NULL));
Index: sys/dev/ofw/ofw_console.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/ofw/ofw_console.c,v
retrieving revision 1.34
diff -u -r1.34 ofw_console.c
--- sys/dev/ofw/ofw_console.c 30 May 2006 07:56:57 -0000 1.34
+++ sys/dev/ofw/ofw_console.c 30 Oct 2006 17:07:55 -0000
@@ -140,7 +140,8 @@
ttyconsolemode(tp, 0);

setuptimeout = 1;
- } else if ((tp->t_state & TS_XCLUDE) && suser(td)) {
+ } else if ((tp->t_state & TS_XCLUDE) &&
+ priv_check(td, PRIV_TTY_EXCLUSIVE)) {
return (EBUSY);
}

Index: sys/dev/random/randomdev.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/random/randomdev.c,v
retrieving revision 1.60
diff -u -r1.60 randomdev.c
--- sys/dev/random/randomdev.c 20 Dec 2005 21:41:52 -0000 1.60
+++ sys/dev/random/randomdev.c 30 Oct 2006 17:07:55 -0000
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -85,7 +86,7 @@
random_close(struct cdev *dev __unused, int flags, int fmt __unused,
struct thread *td)
{
- if ((flags & FWRITE) && (suser(td) == 0)
+ if ((flags & FWRITE) && (priv_check(td, PRIV_RANDOM_RESEED) == 0)
&& (securelevel_gt(td->td_ucred, 0) == 0)) {
(*random_systat.reseed)();
random_systat.seeded = 1;
Index: sys/dev/sbni/if_sbni.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/sbni/if_sbni.c,v
retrieving revision 1.22
diff -u -r1.22 if_sbni.c
--- sys/dev/sbni/if_sbni.c 11 Nov 2005 16:04:54 -0000 1.22
+++ sys/dev/sbni/if_sbni.c 30 Oct 2006 17:07:55 -0000
@@ -67,6 +67,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1110,7 +1111,7 @@

case SIOCSHWFLAGS: /* set flags */
/* root only */
- error = suser(td);
+ error = priv_check(td, PRIV_DRIVER);
if (error)
break;
flags = *(struct sbni_flags*)&ifr->ifr_data;
@@ -1132,7 +1133,7 @@
break;

case SIOCRINSTATS:
- if (!(error = suser(td))) /* root only */
+ if (!(error = priv_check(td, PRIV_DRIVER))) /* root only */
bzero(&sc->in_stats, sizeof(struct sbni_in_stats));
break;

Index: sys/dev/sbsh/if_sbsh.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/sbsh/if_sbsh.c,v
retrieving revision 1.16
diff -u -r1.16 if_sbsh.c
--- sys/dev/sbsh/if_sbsh.c 16 May 2006 14:36:31 -0000 1.16
+++ sys/dev/sbsh/if_sbsh.c 30 Oct 2006 17:07:55 -0000
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -424,7 +425,7 @@

switch(cmd) {
case SIOCLOADFIRMW:
- if ((error = suser(curthread)) != 0)
+ if ((error = priv_check(curthread, PRIV_DRIVER)) != 0)
break;
if (ifp->if_flags & IFF_UP)
error = EBUSY;
@@ -444,7 +445,7 @@
break;

case SIOCGETSTATS :
- if ((error = suser(curthread)) != 0)
+ if ((error = priv_check(curthread, PRIV_DRIVER)) != 0)
break;

t = 0;
@@ -478,7 +479,7 @@
break;

case SIOCCLRSTATS :
- if (!(error = suser(curthread))) {
+ if (!(error = priv_check(curthread, PRIV_DRIVER))) {
bzero(&sc->in_stats, sizeof(struct sbni16_stats));
t = 2;
if (issue_cx28975_cmd(sc, _DSL_CLEAR_ERROR_CTRS, &t, 1))
Index: sys/dev/si/si.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/si/si.c,v
retrieving revision 1.137
diff -u -r1.137 si.c
--- sys/dev/si/si.c 6 Jan 2006 19:56:12 -0000 1.137
+++ sys/dev/si/si.c 30 Oct 2006 17:07:55 -0000
@@ -53,6 +53,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -650,7 +651,7 @@

ip = (int *)data;

-#define SUCHECK if ((error = suser(td))) goto out
+#define SUCHECK if ((error = priv_check(td, PRIV_DRIVER))) goto out

switch (cmd) {
case TCSIPORTS:
Index: sys/dev/syscons/syscons.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/syscons/syscons.c,v
retrieving revision 1.447
diff -u -r1.447 syscons.c
--- sys/dev/syscons/syscons.c 27 Sep 2006 19:56:59 -0000 1.447
+++ sys/dev/syscons/syscons.c 30 Oct 2006 17:07:55 -0000
@@ -50,6 +50,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -517,7 +518,7 @@
ttyld_modem(tp, 1);
}
else
- if (tp->t_state & TS_XCLUDE && suser(td))
+ if (tp->t_state & TS_XCLUDE && priv_check(td, PRIV_TTY_EXCLUSIVE))
return(EBUSY);

error = ttyld_open(tp, dev);
@@ -1092,7 +1093,7 @@
return 0;

case KDENABIO: /* allow io operations */
- error = suser(td);
+ error = priv_check(td, PRIV_IO);
if (error != 0)
return error;
error = securelevel_gt(td->td_ucred, 0);
Index: sys/dev/syscons/sysmouse.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/syscons/sysmouse.c,v
retrieving revision 1.28
diff -u -r1.28 sysmouse.c
--- sys/dev/syscons/sysmouse.c 4 Dec 2005 02:12:42 -0000 1.28
+++ sys/dev/syscons/sysmouse.c 30 Oct 2006 17:07:55 -0000
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -83,7 +84,8 @@
ttyinitmode(tp, 0, 0);
smparam(tp, &tp->t_termios);
ttyld_modem(tp, 1);
- } else if (tp->t_state & TS_XCLUDE && suser(td)) {
+ } else if (tp->t_state & TS_XCLUDE &&
+ priv_check(td, PRIV_TTY_EXCLUSIVE)) {
return EBUSY;
}

Index: sys/dev/wi/if_wi.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/wi/if_wi.c,v
retrieving revision 1.199
diff -u -r1.199 if_wi.c
--- sys/dev/wi/if_wi.c 5 Aug 2006 04:58:25 -0000 1.199
+++ sys/dev/wi/if_wi.c 30 Oct 2006 17:07:55 -0000
@@ -76,6 +76,7 @@
#endif
#include
#include
+#include
#include
#include
#include
@@ -1273,7 +1274,7 @@
WI_UNLOCK(sc);
break;
case SIOCSIFGENERIC:
- error = suser(td);
+ error = priv_check(td, PRIV_DRIVER);
if (error == 0)
error = wi_set_cfg(ifp, cmd, data);
break;
@@ -1291,7 +1292,7 @@
error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
break;
case SIOCSPRISM2DEBUG:
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_DRIVER)))
return (error);
error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
if (error)
@@ -1312,7 +1313,7 @@
case SIOCS80211:
ireq = (struct ieee80211req *) data;
if (ireq->i_type == IEEE80211_IOC_STATIONNAME) {
- error = suser(td);
+ error = priv_check(td, PRIV_NET80211_MANAGE);
if (error)
break;
if (ireq->i_val != 0 ||
Index: sys/dev/wl/if_wl.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/wl/if_wl.c,v
retrieving revision 1.73
diff -u -r1.73 if_wl.c
--- sys/dev/wl/if_wl.c 19 Jun 2006 11:30:36 -0000 1.73
+++ sys/dev/wl/if_wl.c 30 Oct 2006 17:07:55 -0000
@@ -197,6 +197,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1310,7 +1311,7 @@
/* pointer to buffer in user space */
up = (void *)ifr->ifr_data;
/* work out if they're root */
- isroot = (suser(td) == 0);
+ isroot = (priv_check(td, PRIV_NET80211_GETKEY) == 0);

for (i = 0; i < 0x40; i++) {
/* don't hand the DES key out to non-root users */
@@ -1327,7 +1328,7 @@
/* copy the PSA in from the caller; we only copy _some_ values */
case SIOCSWLPSA:
/* root only */
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_DRIVER)))
break;
error = EINVAL; /* assume the worst */
/* pointer to buffer in user space containing data */
@@ -1383,7 +1384,7 @@
*/
case SIOCSWLCNWID:
/* root only */
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_DRIVER)))
break;
if (!(ifp->if_flags & IFF_UP)) {
error = EIO; /* only allowed while up */
@@ -1401,7 +1402,7 @@
/* copy the EEPROM in 2.4 Gz WaveMODEM out to the caller */
case SIOCGWLEEPROM:
/* root only */
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_DRIVER)))
break;
/* pointer to buffer in user space */
up = (void *)ifr->ifr_data;
@@ -1428,7 +1429,7 @@
/* zero (Delete) the wl cache */
case SIOCDWLCACHE:
/* root only */
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_DRIVER)))
break;
wl_cache_zero(sc);
break;
Index: sys/dev/zs/zs.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/zs/zs.c,v
retrieving revision 1.35
diff -u -r1.35 zs.c
--- sys/dev/zs/zs.c 26 May 2006 18:25:34 -0000 1.35
+++ sys/dev/zs/zs.c 30 Oct 2006 17:07:55 -0000
@@ -453,7 +453,7 @@

if ((tp->t_state & TS_ISOPEN) != 0 &&
(tp->t_state & TS_XCLUDE) != 0 &&
- suser(td) != 0)
+ priv_check(td, PRIV_TTY_EXCLUSIVE) != 0)
return (EBUSY);

if ((tp->t_state & TS_ISOPEN) == 0) {
Index: sys/fs/devfs/devfs_rule.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/devfs/devfs_rule.c,v
retrieving revision 1.22
diff -u -r1.22 devfs_rule.c
--- sys/fs/devfs/devfs_rule.c 17 Jul 2006 09:07:01 -0000 1.22
+++ sys/fs/devfs/devfs_rule.c 31 Oct 2006 08:25:32 -0000
@@ -67,6 +67,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -164,11 +165,13 @@
sx_assert(&dm->dm_lock, SX_XLOCKED);

/*
- * XXX: This returns an error regardless of whether we
- * actually support the cmd or not.
+ * XXX: This returns an error regardless of whether we actually
+ * support the cmd or not.
+ *
+ * We could make this privileges finer grained if desired.
*/
- error = suser(td);
- if (error != 0)
+ error = priv_check(td, PRIV_DEVFS_RULE);
+ if (error)
return (error);

sx_xlock(&sx_rules);
Index: sys/fs/devfs/devfs_vnops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/devfs/devfs_vnops.c,v
retrieving revision 1.139
diff -u -r1.139 devfs_vnops.c
--- sys/fs/devfs/devfs_vnops.c 22 Oct 2006 11:52:12 -0000 1.139
+++ sys/fs/devfs/devfs_vnops.c 30 Oct 2006 17:07:55 -0000
@@ -55,6 +55,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1145,19 +1146,25 @@
else
gid = vap->va_gid;
if (uid != de->de_uid || gid != de->de_gid) {
- if (((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid ||
- (gid != de->de_gid && !groupmember(gid, ap->a_cred))) &&
- (error = suser_cred(ap->a_td->td_ucred, SUSER_ALLOWJAIL)) != 0)
- return (error);
+ if ((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid ||
+ (gid != de->de_gid && !groupmember(gid, ap->a_cred))) {
+ error = priv_check_cred(ap->a_td->td_ucred,
+ PRIV_VFS_CHOWN, SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
+ }
de->de_uid = uid;
de->de_gid = gid;
c = 1;
}

if (vap->va_mode != (mode_t)VNOVAL) {
- if ((ap->a_cred->cr_uid != de->de_uid) &&
- (error = suser_cred(ap->a_td->td_ucred, SUSER_ALLOWJAIL)))
- return (error);
+ if (ap->a_cred->cr_uid != de->de_uid) {
+ error = priv_check_cred(ap->a_td->td_ucred,
+ PRIV_VFS_ADMIN, SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
+ }
de->de_mode = vap->va_mode;
c = 1;
}
@@ -1227,7 +1234,8 @@

td = ap->a_cnp->cn_thread;
KASSERT(td == curthread, ("devfs_symlink: td != curthread"));
- error = suser(td);
+
+ error = priv_check(td, PRIV_DEVFS_SYMLINK);
if (error)
return(error);
dmp = VFSTODEVFS(ap->a_dvp->v_mount);
Index: sys/fs/hpfs/hpfs_vnops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/hpfs/hpfs_vnops.c,v
retrieving revision 1.68
diff -u -r1.68 hpfs_vnops.c
--- sys/fs/hpfs/hpfs_vnops.c 17 Jan 2006 17:29:01 -0000 1.68
+++ sys/fs/hpfs/hpfs_vnops.c 30 Oct 2006 17:07:55 -0000
@@ -501,11 +501,12 @@
if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
- if (cred->cr_uid != hp->h_uid &&
- (error = suser_cred(cred, SUSER_ALLOWJAIL)) &&
- ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
- (error = VOP_ACCESS(vp, VWRITE, cred, td))))
- return (error);
+ if (vap->va_vaflags & VA_UTIMES_NULL) {
+ error = VOP_ACCESS(vp, VADMIN, cred, td);
+ if (error)
+ error = VOP_ACCESS(vp, VWRITE, cred, td);
+ } else
+ error = VOP_ACCESS(vp, VADMIN, cred, td);
if (vap->va_atime.tv_sec != VNOVAL)
hp->h_atime = vap->va_atime.tv_sec;
if (vap->va_mtime.tv_sec != VNOVAL)
Index: sys/fs/msdosfs/msdosfs_vfsops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/msdosfs/msdosfs_vfsops.c,v
retrieving revision 1.153
diff -u -r1.153 msdosfs_vfsops.c
--- sys/fs/msdosfs/msdosfs_vfsops.c 26 Sep 2006 04:12:45 -0000 1.153
+++ sys/fs/msdosfs/msdosfs_vfsops.c 30 Oct 2006 17:07:55 -0000
@@ -52,6 +52,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -293,17 +294,17 @@
* If upgrade to read-write by non-root, then verify
* that user has necessary permissions on the device.
*/
- if (suser(td)) {
- devvp = pmp->pm_devvp;
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
- error = VOP_ACCESS(devvp, VREAD | VWRITE,
- td->td_ucred, td);
- if (error) {
- VOP_UNLOCK(devvp, 0, td);
- return (error);
- }
+ devvp = pmp->pm_devvp;
+ vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
+ error = VOP_ACCESS(devvp, VREAD | VWRITE,
+ td->td_ucred, td);
+ if (error)
+ error = priv_check(td, PRIV_VFS_MOUNT_PERM);
+ if (error) {
VOP_UNLOCK(devvp, 0, td);
+ return (error);
}
+ VOP_UNLOCK(devvp, 0, td);
DROP_GIANT();
g_topology_lock();
error = g_access(pmp->pm_cp, 0, 1, 0);
@@ -353,15 +354,15 @@
* If mount by non-root, then verify that user has necessary
* permissions on the device.
*/
- if (suser(td)) {
- accessmode = VREAD;
- if ((mp->mnt_flag & MNT_RDONLY) == 0)
- accessmode |= VWRITE;
- error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td);
- if (error) {
- vput(devvp);
- return (error);
- }
+ accessmode = VREAD;
+ if ((mp->mnt_flag & MNT_RDONLY) == 0)
+ accessmode |= VWRITE;
+ error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td);
+ if (error)
+ error = priv_check(td, PRIV_VFS_MOUNT_PERM);
+ if (error) {
+ vput(devvp);
+ return (error);
}
if ((mp->mnt_flag & MNT_UPDATE) == 0) {
error = mountmsdosfs(devvp, mp, td);
Index: sys/fs/msdosfs/msdosfs_vnops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/msdosfs/msdosfs_vnops.c,v
retrieving revision 1.164
diff -u -r1.164 msdosfs_vnops.c
--- sys/fs/msdosfs/msdosfs_vnops.c 24 Oct 2006 11:14:05 -0000 1.164
+++ sys/fs/msdosfs/msdosfs_vnops.c 30 Oct 2006 17:07:55 -0000
@@ -59,6 +59,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -404,9 +405,12 @@
if (vap->va_flags != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
- if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_cred(cred, SUSER_ALLOWJAIL)))
- return (error);
+ if (cred->cr_uid != pmp->pm_uid) {
+ error = priv_check_cred(cred, PRIV_VFS_ADMIN,
+ SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
+ }
/*
* We are very inconsistent about handling unsupported
* attributes. We ignored the access time and the
@@ -419,9 +423,11 @@
* set ATTR_ARCHIVE for directories `cp -pr' from a more
* sensible filesystem attempts it a lot.
*/
- if (suser_cred(cred, SUSER_ALLOWJAIL)) {
- if (vap->va_flags & SF_SETTABLE)
- return EPERM;
+ if (vap->va_flags & SF_SETTABLE) {
+ error = priv_check_cred(cred, PRIV_VFS_SYSFLAGS,
+ SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
}
if (vap->va_flags & ~SF_ARCHIVED)
return EOPNOTSUPP;
@@ -444,10 +450,13 @@
gid = vap->va_gid;
if (gid == (gid_t)VNOVAL)
gid = pmp->pm_gid;
- if ((cred->cr_uid != pmp->pm_uid || uid != pmp->pm_uid ||
- (gid != pmp->pm_gid && !groupmember(gid, cred))) &&
- (error = suser_cred(cred, SUSER_ALLOWJAIL)))
- return error;
+ if (cred->cr_uid != pmp->pm_uid || uid != pmp->pm_uid ||
+ (gid != pmp->pm_gid && !groupmember(gid, cred))) {
+ error = priv_check_cred(cred, PRIV_VFS_CHOWN,
+ SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
+ }
if (uid != pmp->pm_uid || gid != pmp->pm_gid)
return EINVAL;
}
@@ -477,11 +486,13 @@
if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
- if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_cred(cred, SUSER_ALLOWJAIL)) &&
- ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
- (error = VOP_ACCESS(ap->a_vp, VWRITE, cred, ap->a_td))))
- return (error);
+ if (vap->va_vaflags & VA_UTIMES_NULL) {
+ error = VOP_ACCESS(vp, VADMIN, cred, ap->a_td);
+ if (error)
+ error = VOP_ACCESS(vp, VWRITE, cred,
+ ap->a_td);
+ } else
+ error = VOP_ACCESS(vp, VADMIN, cred, ap->a_td);
if (vp->v_type != VDIR) {
if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&
vap->va_atime.tv_sec != VNOVAL) {
@@ -506,9 +517,12 @@
if (vap->va_mode != (mode_t)VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
- if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_cred(cred, SUSER_ALLOWJAIL)))
- return (error);
+ if (cred->cr_uid != pmp->pm_uid) {
+ error = priv_check_cred(cred, PRIV_VFS_ADMIN,
+ SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
+ }
if (vp->v_type != VDIR) {
/* We ignore the read and execute bits. */
if (vap->va_mode & VWRITE)
Index: sys/fs/procfs/procfs_ioctl.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/procfs/procfs_ioctl.c,v
retrieving revision 1.13
diff -u -r1.13 procfs_ioctl.c
--- sys/fs/procfs/procfs_ioctl.c 27 Sep 2006 19:57:00 -0000 1.13
+++ sys/fs/procfs/procfs_ioctl.c 30 Oct 2006 17:07:55 -0000
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -104,8 +105,19 @@
#endif
case PIOCSFL:
flags = *(unsigned int *)data;
- if (flags & PF_ISUGID && (error = suser(td)) != 0)
- break;
+ if (flags & PF_ISUGID) {
+ /*
+ * XXXRW: Is this specific check required here, as
+ * p_candebug() should implement it, or other checks
+ * are missing.
+ *
+ * XXXRW: Other debugging privileges are granted in
+ * jail, why isn't this?
+ */
+ error = priv_check(td, PRIV_DEBUG_SUGID);
+ if (error)
+ break;
+ }
p->p_pfsflags = flags;
break;
case PIOCGFL:
Index: sys/fs/smbfs/smbfs_vnops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/smbfs/smbfs_vnops.c,v
retrieving revision 1.62
diff -u -r1.62 smbfs_vnops.c
--- sys/fs/smbfs/smbfs_vnops.c 31 May 2006 22:31:08 -0000 1.62
+++ sys/fs/smbfs/smbfs_vnops.c 30 Oct 2006 17:07:55 -0000
@@ -352,11 +352,13 @@
if (vap->va_atime.tv_sec != VNOVAL)
atime = &vap->va_atime;
if (mtime != atime) {
- if (ap->a_cred->cr_uid != VTOSMBFS(vp)->sm_uid &&
- (error = suser_cred(ap->a_cred, SUSER_ALLOWJAIL)) &&
- ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
- (error = VOP_ACCESS(vp, VWRITE, ap->a_cred, ap->a_td))))
- return (error);
+ if (vap->va_vaflags & VA_UTIMES_NULL) {
+ error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td);
+ if (error)
+ error = VOP_ACCESS(vp, VWRITE, ap->a_cred,
+ ap->a_td);
+ } else
+ error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td);
#if 0
if (mtime == NULL)
mtime = &np->n_mtime;
Index: sys/fs/udf/udf_vfsops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/udf/udf_vfsops.c,v
retrieving revision 1.44
diff -u -r1.44 udf_vfsops.c
--- sys/fs/udf/udf_vfsops.c 26 Sep 2006 04:12:46 -0000 1.44
+++ sys/fs/udf/udf_vfsops.c 30 Oct 2006 17:07:55 -0000
@@ -84,6 +84,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -238,7 +239,7 @@
/* Check the access rights on the mount device */
error = VOP_ACCESS(devvp, VREAD, td->td_ucred, td);
if (error)
- error = suser(td);
+ error = priv_check(td, PRIV_VFS_MOUNT_PERM);
if (error) {
vput(devvp);
return (error);
Index: sys/fs/umapfs/umap_vfsops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/umapfs/umap_vfsops.c,v
retrieving revision 1.65
diff -u -r1.65 umap_vfsops.c
--- sys/fs/umapfs/umap_vfsops.c 26 Sep 2006 04:12:46 -0000 1.65
+++ sys/fs/umapfs/umap_vfsops.c 30 Oct 2006 17:07:55 -0000
@@ -88,8 +88,9 @@
/*
* Only for root
*/
- if ((error = suser(td)) != 0)
- return (error);
+ error = priv_check(td, PRIV_VFS_MOUNT);
+ if (error)
+ return (ERROR);

#ifdef DEBUG
printf("umapfs_mount(mp = %p)\n", (void *)mp);
Index: sys/gnu/fs/ext2fs/ext2_vfsops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/gnu/fs/ext2fs/ext2_vfsops.c,v
retrieving revision 1.158
diff -u -r1.158 ext2_vfsops.c
--- sys/gnu/fs/ext2fs/ext2_vfsops.c 26 Sep 2006 04:12:47 -0000 1.158
+++ sys/gnu/fs/ext2fs/ext2_vfsops.c 30 Oct 2006 17:07:55 -0000
@@ -57,6 +57,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -197,15 +198,16 @@
* If upgrade to read-write by non-root, then verify
* that user has necessary permissions on the device.
*/
- if (suser(td)) {
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
- if ((error = VOP_ACCESS(devvp, VREAD | VWRITE,
- td->td_ucred, td)) != 0) {
- VOP_UNLOCK(devvp, 0, td);
- return (error);
- }
+ vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
+ error = VOP_ACCESS(devvp, VREAD | VWRITE,
+ td->td_ucred, td);
+ if (error)
+ error = priv_check(td, PRIV_VFS_MOUNT_PERM);
+ if (error) {
VOP_UNLOCK(devvp, 0, td);
+ return (error);
}
+ VOP_UNLOCK(devvp, 0, td);
DROP_GIANT();
g_topology_lock();
error = g_access(ump->um_cp, 0, 1, 0);
@@ -259,15 +261,18 @@
/*
* If mount by non-root, then verify that user has necessary
* permissions on the device.
+ *
+ * XXXRW: VOP_ACCESS() enough?
*/
- if (suser(td)) {
- accessmode = VREAD;
- if ((mp->mnt_flag & MNT_RDONLY) == 0)
- accessmode |= VWRITE;
- if ((error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td)) != 0) {
- vput(devvp);
- return (error);
- }
+ accessmode = VREAD;
+ if ((mp->mnt_flag & MNT_RDONLY) == 0)
+ accessmode |= VWRITE;
+ error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td);
+ if (error)
+ error = priv_check(td, PRIV_VFS_MOUNT_PERM);
+ if (error) {
+ vput(devvp);
+ return (error);
}

if ((mp->mnt_flag & MNT_UPDATE) == 0) {
Index: sys/gnu/fs/ext2fs/ext2_vnops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/gnu/fs/ext2fs/ext2_vnops.c,v
retrieving revision 1.105
diff -u -r1.105 ext2_vnops.c
--- sys/gnu/fs/ext2fs/ext2_vnops.c 29 Dec 2005 21:34:49 -0000 1.105
+++ sys/gnu/fs/ext2fs/ext2_vnops.c 30 Oct 2006 17:07:55 -0000
@@ -52,6 +52,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -411,7 +412,8 @@
* Privileged non-jail processes may not modify system flags
* if securelevel > 0 and any existing system flags are set.
*/
- if (!suser_cred(cred, SUSER_ALLOWJAIL)) {
+ if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS,
+ SUSER_ALLOWJAIL)) {
if (ip->i_flags
& (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) {
error = securelevel_gt(cred, 0);
@@ -529,11 +531,17 @@
* as well as set the setgid bit on a file with a group that the
* process is not a member of.
*/
- if (suser_cred(cred, SUSER_ALLOWJAIL)) {
- if (vp->v_type != VDIR && (mode & S_ISTXT))
+ if (vp->v_type != VDIR && (mode & S_ISTXT)) {
+ error = priv_check_cred(cred, PRIV_VFS_STICKYFILE,
+ SUSER_ALLOWJAIL);
+ if (error)
return (EFTYPE);
- if (!groupmember(ip->i_gid, cred) && (mode & ISGID))
- return (EPERM);
+ }
+ if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) {
+ error = priv_check_cred(cred, PRIV_VFS_SETGID,
+ SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
}
ip->i_mode &= ~ALLPERMS;
ip->i_mode |= (mode & ALLPERMS);
@@ -573,17 +581,23 @@
* to a group of which we are not a member, the caller must
* have privilege.
*/
- if ((uid != ip->i_uid ||
- (gid != ip->i_gid && !groupmember(gid, cred))) &&
- (error = suser_cred(cred, SUSER_ALLOWJAIL)))
- return (error);
+ if (uid != ip->i_uid || (gid != ip->i_gid &&
+ !groupmember(gid, cred))) {
+ error = priv_check_cred(cred, PRIV_VFS_CHOWN,
+ SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
+ }
ogid = ip->i_gid;
ouid = ip->i_uid;
ip->i_gid = gid;
ip->i_uid = uid;
ip->i_flag |= IN_CHANGE;
- if (suser_cred(cred, SUSER_ALLOWJAIL) && (ouid != uid || ogid != gid))
- ip->i_mode &= ~(ISUID | ISGID);
+ if (ouid != uid || ogid != gid) {
+ if (priv_check_cred(cred, PRIV_VFS_CLEARSUGID,
+ SUSER_ALLOWJAIL) != 0)
+ ip->i_mode &= ~(ISUID | ISGID);
+ }
return (0);
}

@@ -1608,9 +1622,11 @@
ip->i_mode = mode;
tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */
ip->i_nlink = 1;
- if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
- suser_cred(cnp->cn_cred, SUSER_ALLOWJAIL))
- ip->i_mode &= ~ISGID;
+ if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred)) {
+ if (priv_check_cred(cnp->cn_cred, PRIV_VFS_CLEARSUGID,
+ SUSER_ALLOWJAIL))
+ ip->i_mode &= ~ISGID;
+ }

if (cnp->cn_flags & ISWHITEOUT)
ip->i_flags |= UF_OPAQUE;
Index: sys/gnu/fs/reiserfs/reiserfs_fs.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/gnu/fs/reiserfs/reiserfs_fs.h,v
retrieving revision 1.4
diff -u -r1.4 reiserfs_fs.h
--- sys/gnu/fs/reiserfs/reiserfs_fs.h 4 Dec 2005 09:57:09 -0000 1.4
+++ sys/gnu/fs/reiserfs/reiserfs_fs.h 30 Oct 2006 17:07:55 -0000
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include
#include
#include
Index: sys/gnu/fs/reiserfs/reiserfs_vfsops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/gnu/fs/reiserfs/reiserfs_vfsops.c,v
retrieving revision 1.6
diff -u -r1.6 reiserfs_vfsops.c
--- sys/gnu/fs/reiserfs/reiserfs_vfsops.c 26 Sep 2006 04:12:47 -0000 1.6
+++ sys/gnu/fs/reiserfs/reiserfs_vfsops.c 30 Oct 2006 17:07:55 -0000
@@ -125,15 +125,15 @@

/* If mount by non-root, then verify that user has necessary
* permissions on the device. */
- if (suser(td)) {
- accessmode = VREAD;
- if ((mp->mnt_flag & MNT_RDONLY) == 0)
- accessmode |= VWRITE;
- if ((error = VOP_ACCESS(devvp,
- accessmode, td->td_ucred, td)) != 0) {
- vput(devvp);
- return (error);
- }
+ accessmode = VREAD;
+ if ((mp->mnt_flag & MNT_RDONLY) == 0)
+ accessmode |= VWRITE;
+ error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td);
+ if (error)
+ error = priv_check(td, PRIV_VFS_MOUNT_PERM);
+ if (error) {
+ vput(devvp);
+ return (error);
}

if ((mp->mnt_flag & MNT_UPDATE) == 0) {
Index: sys/gnu/fs/xfs/FreeBSD/xfs_super.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/gnu/fs/xfs/FreeBSD/xfs_super.c,v
retrieving revision 1.4
diff -u -r1.4 xfs_super.c
--- sys/gnu/fs/xfs/FreeBSD/xfs_super.c 10 Jun 2006 19:02:13 -0000 1.4
+++ sys/gnu/fs/xfs/FreeBSD/xfs_super.c 30 Oct 2006 17:07:55 -0000
@@ -53,6 +53,8 @@
#include "xfs_version.h"
#include "xfs_buf.h"

+#include
+
#include
#include

@@ -149,14 +151,15 @@
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);

ronly = ((XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) != 0);
- if (suser(td)) {
- accessmode = VREAD;
- if (!ronly)
- accessmode |= VWRITE;
- if ((error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td))!= 0){
- vput(devvp);
- return (error);
- }
+ accessmode = VREAD;
+ if (!ronly)
+ accessmode |= VWRITE;
+ error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td);
+ if (error)
+ error = priv_check(td, PRIV_VFS_MOUNT_PERM);
+ if (error) {
+ vput(devvp);
+ return (error);
}

DROP_GIANT();
Index: sys/i386/i386/io.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/i386/io.c,v
retrieving revision 1.1
diff -u -r1.1 io.c
--- sys/i386/i386/io.c 1 Aug 2004 11:40:52 -0000 1.1
+++ sys/i386/i386/io.c 30 Oct 2006 17:07:55 -0000
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -54,7 +55,7 @@
{
int error;

- error = suser(td);
+ error = priv_check(td, PRIV_IO);
if (error != 0)
return (error);
error = securelevel_gt(td->td_ucred, 0);
Index: sys/i386/i386/sys_machdep.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/i386/sys_machdep.c,v
retrieving revision 1.106
diff -u -r1.106 sys_machdep.c
--- sys/i386/i386/sys_machdep.c 22 Oct 2006 11:52:12 -0000 1.106
+++ sys/i386/i386/sys_machdep.c 30 Oct 2006 17:07:55 -0000
@@ -40,6 +40,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -292,7 +293,7 @@
if ((error = mac_check_sysarch_ioperm(td->td_ucred)) != 0)
return (error);
#endif
- if ((error = suser(td)) != 0)
+ if ((error = priv_check(td, PRIV_IO)) != 0)
return (error);
if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
return (error);
Index: sys/i386/i386/vm86.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/i386/vm86.c,v
retrieving revision 1.59
diff -u -r1.59 vm86.c
--- sys/i386/i386/vm86.c 28 Sep 2005 07:03:03 -0000 1.59
+++ sys/i386/i386/vm86.c 30 Oct 2006 17:07:55 -0000
@@ -29,6 +29,7 @@

#include
#include
+#include
#include
#include
#include
@@ -724,7 +725,7 @@
case VM86_INTCALL: {
struct vm86_intcall_args sa;

- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_VM86_INTCALL)))
return (error);
if ((error = copyin(ua.sub_args, &sa, sizeof(sa))))
return (error);
Index: sys/i386/ibcs2/ibcs2_misc.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/ibcs2/ibcs2_misc.c,v
retrieving revision 1.65
diff -u -r1.65 ibcs2_misc.c
--- sys/i386/ibcs2/ibcs2_misc.c 22 Oct 2006 11:52:12 -0000 1.65
+++ sys/i386/ibcs2/ibcs2_misc.c 30 Oct 2006 17:07:55 -0000
@@ -68,6 +68,7 @@
#include
#include /* Must come after sys/malloc.h */
#include
+#include
#include
#include
#include
@@ -1008,14 +1009,22 @@
#define IBCS2_DATALOCK 4


- if ((error = suser(td)) != 0)
- return EPERM;
switch(uap->cmd) {
case IBCS2_UNLOCK:
+ error = priv_check(td, PRIV_VM_MUNLOCK);
+ if (error)
+ return (error);
+ /* XXX - TODO */
+ return (0);
+
case IBCS2_PROCLOCK:
case IBCS2_TEXTLOCK:
case IBCS2_DATALOCK:
- return 0; /* XXX - TODO */
+ error = priv_check(td, PRIV_VM_MLOCK);
+ if (error)
+ return (error);
+ /* XXX - TODO */
+ return 0;
}
return EINVAL;
}
@@ -1043,9 +1052,6 @@
#define SCO_AD_GETBMAJ 0
#define SCO_AD_GETCMAJ 1

- if (suser(td))
- return EPERM;
-
switch(uap->cmd) {
case SCO_A_REBOOT:
case SCO_A_SHUTDOWN:
@@ -1055,11 +1061,11 @@
case SCO_AD_PWRDOWN:
case SCO_AD_PWRNAP:
r.opt = RB_HALT;
- reboot(td, &r);
+ return (reboot(td, &r));
case SCO_AD_BOOT:
case SCO_AD_IBOOT:
r.opt = RB_AUTOBOOT;
- reboot(td, &r);
+ return (reboot(td, &r));
}
return EINVAL;
case SCO_A_REMOUNT:
Index: sys/i386/ibcs2/ibcs2_socksys.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/ibcs2/ibcs2_socksys.c,v
retrieving revision 1.21
diff -u -r1.21 ibcs2_socksys.c
--- sys/i386/ibcs2/ibcs2_socksys.c 6 Jan 2005 23:22:04 -0000 1.21
+++ sys/i386/ibcs2/ibcs2_socksys.c 30 Oct 2006 17:07:55 -0000
@@ -174,9 +174,6 @@
char hname[MAXHOSTNAMELEN], *ptr;
int error, sctl[2], hlen;

- if ((error = suser(td)))
- return (error);
-
/* W/out a hostname a domain-name is nonsense */
if ( strlen(hostname) == 0 )
return EINVAL;
Index: sys/i386/ibcs2/ibcs2_sysi86.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/ibcs2/ibcs2_sysi86.c,v
retrieving revision 1.22
diff -u -r1.22 ibcs2_sysi86.c
--- sys/i386/ibcs2/ibcs2_sysi86.c 7 Jul 2005 19:30:30 -0000 1.22
+++ sys/i386/ibcs2/ibcs2_sysi86.c 30 Oct 2006 17:07:55 -0000
@@ -76,8 +76,6 @@
int name[2];
int error;

- if ((error = suser(td)))
- return (error);
name[0] = CTL_KERN;
name[1] = KERN_HOSTNAME;
mtx_lock(&Giant);
Index: sys/i386/linux/linux_machdep.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/linux/linux_machdep.c,v
retrieving revision 1.63
diff -u -r1.63 linux_machdep.c
--- sys/i386/linux/linux_machdep.c 20 Oct 2006 10:09:40 -0000 1.63
+++ sys/i386/linux/linux_machdep.c 30 Oct 2006 17:07:55 -0000
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -812,7 +813,7 @@

if (args->level < 0 || args->level > 3)
return (EINVAL);
- if ((error = suser(td)) != 0)
+ if ((error = priv_check(td, PRIV_IO)) != 0)
return (error);
if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
return (error);
Index: sys/i4b/driver/i4b_ipr.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i4b/driver/i4b_ipr.c,v
retrieving revision 1.35
diff -u -r1.35 i4b_ipr.c
--- sys/i4b/driver/i4b_ipr.c 9 Aug 2005 10:19:57 -0000 1.35
+++ sys/i4b/driver/i4b_ipr.c 30 Oct 2006 17:07:55 -0000
@@ -490,7 +490,7 @@
{
struct thread *td = curthread; /* XXX */

- if((error = suser(td)))
+ if((error = priv_check(td, PRIV_DRIVER)))
return (error);
sl_compress_setup(sc->sc_compr, *(int *)data);
}
Index: sys/ia64/ia64/ssc.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ia64/ia64/ssc.c,v
retrieving revision 1.28
diff -u -r1.28 ssc.c
--- sys/ia64/ia64/ssc.c 27 May 2006 17:52:08 -0000 1.28
+++ sys/ia64/ia64/ssc.c 30 Oct 2006 17:07:55 -0000
@@ -147,7 +147,8 @@
ttyconsolemode(tp, 0);

setuptimeout = 1;
- } else if ((tp->t_state & TS_XCLUDE) && suser(td)) {
+ } else if ((tp->t_state & TS_XCLUDE) &&
+ priv_check(td, PRIV_TTY_EXCLUSIVE)) {
splx(s);
return EBUSY;
}
Index: sys/isofs/cd9660/cd9660_vfsops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/isofs/cd9660/cd9660_vfsops.c,v
retrieving revision 1.146
diff -u -r1.146 cd9660_vfsops.c
--- sys/isofs/cd9660/cd9660_vfsops.c 26 Sep 2006 04:12:47 -0000 1.146
+++ sys/isofs/cd9660/cd9660_vfsops.c 30 Oct 2006 17:07:55 -0000
@@ -40,6 +40,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -174,7 +175,7 @@
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td);
if (error)
- error = suser(td);
+ error = priv_check(td, PRIV_VFS_MOUNT_PERM);
if (error) {
vput(devvp);
return (error);
Index: sys/kern/kern_acct.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_acct.c,v
retrieving revision 1.84
diff -u -r1.84 kern_acct.c
--- sys/kern/kern_acct.c 22 Oct 2006 11:52:12 -0000 1.84
+++ sys/kern/kern_acct.c 30 Oct 2006 17:07:55 -0000
@@ -56,6 +56,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -166,8 +167,7 @@
struct nameidata nd;
int error, flags, vfslocked;

- /* Make sure that the caller is root. */
- error = suser(td);
+ error = priv_check(td, PRIV_ACCT);
if (error)
return (error);

Index: sys/kern/kern_descrip.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_descrip.c,v
retrieving revision 1.298
diff -u -r1.298 kern_descrip.c
--- sys/kern/kern_descrip.c 24 Sep 2006 02:29:53 -0000 1.298
+++ sys/kern/kern_descrip.c 30 Oct 2006 17:07:55 -0000
@@ -57,6 +57,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1351,8 +1352,8 @@
sx_xlock(&filelist_lock);

if ((openfiles >= maxuserfiles &&
- suser_cred(td->td_ucred, SUSER_RUID) != 0) ||
- openfiles >= maxfiles) {
+ priv_check_cred(td->td_ucred, PRIV_MAXFILES, SUSER_RUID) != 0)
+ || openfiles >= maxfiles) {
if (ppsratecheck(&lastfail, &curfail, 1)) {
printf("kern.maxfiles limit exceeded by uid %i, please see tuning(7).\n",
td->td_ucred->cr_ruid);
Index: sys/kern/kern_environment.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_environment.c,v
retrieving revision 1.45
diff -u -r1.45 kern_environment.c
--- sys/kern/kern_environment.c 22 Oct 2006 11:52:12 -0000 1.45
+++ sys/kern/kern_environment.c 30 Oct 2006 17:07:55 -0000
@@ -46,6 +46,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -125,11 +126,18 @@
return (error);
}

- if ((uap->what == KENV_SET) ||
- (uap->what == KENV_UNSET)) {
- error = suser(td);
+ switch (uap->what) {
+ case KENV_SET:
+ error = priv_check(td, PRIV_KENV_SET);
+ if (error)
+ return (error);
+ break;
+
+ case KENV_UNSET:
+ error = priv_check(td, PRIV_KENV_UNSET);
if (error)
return (error);
+ break;
}

name = malloc(KENV_MNAMELEN, M_TEMP, M_WAITOK);
Index: sys/kern/kern_exec.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_exec.c,v
retrieving revision 1.298
diff -u -r1.298 kern_exec.c
--- sys/kern/kern_exec.c 22 Oct 2006 21:18:47 -0000 1.298
+++ sys/kern/kern_exec.c 31 Oct 2006 08:28:07 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -571,8 +572,11 @@
* we do not regain any tracing during a possible block.
*/
setsugid(p);
+
#ifdef KTRACE
- if (p->p_tracevp != NULL && suser_cred(oldcred, SUSER_ALLOWJAIL)) {
+ if (p->p_tracevp != NULL &&
+ priv_check_cred(oldcred, PRIV_DEBUG_DIFFCRED,
+ SUSER_ALLOWJAIL)) {
mtx_lock(&ktrace_mtx);
p->p_traceflag = 0;
tracevp = p->p_tracevp;
Index: sys/kern/kern_fork.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_fork.c,v
retrieving revision 1.263
diff -u -r1.263 kern_fork.c
--- sys/kern/kern_fork.c 26 Oct 2006 21:42:19 -0000 1.263
+++ sys/kern/kern_fork.c 30 Oct 2006 17:07:55 -0000
@@ -51,6 +51,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -310,7 +311,7 @@
*/
sx_xlock(&allproc_lock);
if ((nprocs >= maxproc - 10 &&
- suser_cred(td->td_ucred, SUSER_RUID) != 0) ||
+ priv_check_cred(td->td_ucred, PRIV_MAXPROC, SUSER_RUID) != 0) ||
nprocs >= maxproc) {
error = EAGAIN;
goto fail;
@@ -319,8 +320,11 @@
/*
* Increment the count of procs running with this uid. Don't allow
* a nonprivileged user to exceed their current limit.
+ *
+ * XXXRW: Can we avoid privilege here if it's not needed?
*/
- error = suser_cred(td->td_ucred, SUSER_RUID | SUSER_ALLOWJAIL);
+ error = priv_check_cred(td->td_ucred, PRIV_PROC_LIMIT, SUSER_RUID |
+ SUSER_ALLOWJAIL);
if (error == 0)
ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, 0);
else {
Index: sys/kern/kern_jail.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_jail.c,v
retrieving revision 1.53
diff -u -r1.53 kern_jail.c
--- sys/kern/kern_jail.c 22 Oct 2006 11:52:13 -0000 1.53
+++ sys/kern/kern_jail.c 30 Oct 2006 17:07:55 -0000
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -205,7 +206,7 @@
* a process root from one prison, but attached to the jail
* of another.
*/
- error = suser(td);
+ error = priv_check(td, PRIV_JAIL_ATTACH);
if (error)
return (error);

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

+/*
+ * Check with permission for a specific privilege is granted within jail. We
+ * have a specific list of accepted privileges; the rest are denied.
+ */
+int
+prison_priv_check(struct ucred *cred, 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)
{
Index: sys/kern/kern_ktrace.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_ktrace.c,v
retrieving revision 1.111
diff -u -r1.111 kern_ktrace.c
--- sys/kern/kern_ktrace.c 22 Oct 2006 11:52:13 -0000 1.111
+++ sys/kern/kern_ktrace.c 30 Oct 2006 17:07:55 -0000
@@ -47,6 +47,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -807,7 +808,8 @@
p->p_tracecred = crhold(td->td_ucred);
}
p->p_traceflag |= facs;
- if (suser_cred(td->td_ucred, SUSER_ALLOWJAIL) == 0)
+ if (priv_check_cred(td->td_ucred, PRIV_KTRACE,
+ SUSER_ALLOWJAIL) == 0)
p->p_traceflag |= KTRFAC_ROOT;
} else {
/* KTROP_CLEAR */
@@ -1013,7 +1015,7 @@

PROC_LOCK_ASSERT(targetp, MA_OWNED);
if (targetp->p_traceflag & KTRFAC_ROOT &&
- suser_cred(td->td_ucred, SUSER_ALLOWJAIL))
+ priv_check_cred(td->td_ucred, PRIV_KTRACE, SUSER_ALLOWJAIL))
return (0);

if (p_candebug(td, targetp) != 0)
Index: sys/kern/kern_linker.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_linker.c,v
retrieving revision 1.143
diff -u -r1.143 kern_linker.c
--- sys/kern/kern_linker.c 22 Oct 2006 11:52:13 -0000 1.143
+++ sys/kern/kern_linker.c 30 Oct 2006 17:07:55 -0000
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -854,7 +855,7 @@
if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
return (error);

- if ((error = suser(td)) != 0)
+ if ((error = priv_check(td, PRIV_KLD_LOAD)) != 0)
return (error);

/*
@@ -921,7 +922,7 @@
if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
return (error);

- if ((error = suser(td)) != 0)
+ if ((error = priv_check(td, PRIV_KLD_UNLOAD)) != 0)
return (error);

KLD_LOCK();
Index: sys/kern/kern_ntptime.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_ntptime.c,v
retrieving revision 1.59
diff -u -r1.59 kern_ntptime.c
--- sys/kern/kern_ntptime.c 28 May 2005 14:34:41 -0000 1.59
+++ sys/kern/kern_ntptime.c 30 Oct 2006 17:07:55 -0000
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -333,7 +334,7 @@
mtx_lock(&Giant);
modes = ntv.modes;
if (modes)
- error = suser(td);
+ error = priv_check(td, PRIV_NTP_ADJTIME);
if (error)
goto done2;
s = splclock();
@@ -954,7 +955,7 @@
struct timeval atv;
int error;

- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_ADJTIME)))
return (error);

mtx_lock(&Giant);
Index: sys/kern/kern_priv.c
================================================== =================
RCS file: sys/kern/kern_priv.c
diff -N sys/kern/kern_priv.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/kern/kern_priv.c 31 Oct 2006 08:22:47 -0000
@@ -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
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+/*
+ * `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));
+}
Index: sys/kern/kern_prot.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_prot.c,v
retrieving revision 1.205
diff -u -r1.205 kern_prot.c
--- sys/kern/kern_prot.c 22 Oct 2006 11:52:13 -0000 1.205
+++ sys/kern/kern_prot.c 30 Oct 2006 17:07:55 -0000
@@ -55,6 +55,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -547,7 +548,8 @@
#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 @@
#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 @@

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 @@
#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 @@
#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 @@

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 @@
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 @@
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 @@
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 @@
(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 @@
(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 @@
}

/*
- * `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 @@
{

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 @@
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 @@
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 @@
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 @@
return (0);
}

-
/*-
* Determine whether td may deliver the specified signal to p.
* Returns: 0 for permitted, an errno value otherwise
@@ -1683,19 +1647,14 @@
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 @@
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 @@
/*
* 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 @@

/*
* 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 @@
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);
Index: sys/kern/kern_resource.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_resource.c,v
retrieving revision 1.161
diff -u -r1.161 kern_resource.c
--- sys/kern/kern_resource.c 26 Oct 2006 21:42:19 -0000 1.161
+++ sys/kern/kern_resource.c 30 Oct 2006 17:07:55 -0000
@@ -47,6 +47,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -264,7 +265,7 @@
n = PRIO_MAX;
if (n < PRIO_MIN)
n = PRIO_MIN;
- if (n < p->p_nice && suser(td) != 0)
+ if (n < p->p_nice && priv_check(td, PRIV_SCHED_SETPRIORITY) != 0)
return (EACCES);
mtx_lock_spin(&sched_lock);
sched_nice(p, n);
@@ -468,7 +469,7 @@
break;

/* Disallow setting rtprio in most cases if not superuser. */
- if (suser(td) != 0) {
+ if (priv_check(td, PRIV_SCHED_RTPRIO) != 0) {
/* can't set someone else's */
if (uap->pid) {
error = EPERM;
@@ -754,7 +755,8 @@
alimp = &oldlim->pl_rlimit[which];
if (limp->rlim_cur > alimp->rlim_max ||
limp->rlim_max > alimp->rlim_max)
- if ((error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL))) {
+ if ((error = priv_check_cred(td->td_ucred,
+ PRIV_PROC_SETRLIMIT, SUSER_ALLOWJAIL))) {
PROC_UNLOCK(p);
lim_free(newlim);
return (error);
Index: sys/kern/kern_shutdown.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_shutdown.c,v
retrieving revision 1.179
diff -u -r1.179 kern_shutdown.c
--- sys/kern/kern_shutdown.c 22 Oct 2006 11:52:13 -0000 1.179
+++ sys/kern/kern_shutdown.c 30 Oct 2006 17:07:55 -0000
@@ -55,6 +55,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -164,7 +165,7 @@
error = mac_check_system_reboot(td->td_ucred, uap->opt);
#endif
if (error == 0)
- error = suser(td);
+ error = priv_check(td, PRIV_REBOOT);
if (error == 0) {
mtx_lock(&Giant);
boot(uap->opt);
Index: sys/kern/kern_sysctl.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.171
diff -u -r1.171 kern_sysctl.c
--- sys/kern/kern_sysctl.c 22 Oct 2006 11:52:13 -0000 1.171
+++ sys/kern/kern_sysctl.c 30 Oct 2006 17:07:55 -0000
@@ -46,6 +46,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -512,7 +513,7 @@
{
int error;

- error = suser(req->td);
+ error = priv_check(req->td, PRIV_SYSCTL_DEBUG);
if (error)
return (error);
sysctl_sysctl_debug_dump_node(&sysctl__children, 0);
@@ -1253,13 +1254,11 @@

/* Is this sysctl writable by only privileged users? */
if (req->newptr && !(oid->oid_kind & CTLFLAG_ANYBODY)) {
- int flags;
-
if (oid->oid_kind & CTLFLAG_PRISON)
- flags = SUSER_ALLOWJAIL;
+ error = priv_check_cred(req->td->td_ucred,
+ PRIV_SYSCTL_WRITEJAIL, SUSER_ALLOWJAIL);
else
- flags = 0;
- error = suser_cred(req->td->td_ucred, flags);
+ error = priv_check(req->td, PRIV_SYSCTL_WRITE);
if (error)
return (error);
}
Index: sys/kern/kern_thr.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_thr.c,v
retrieving revision 1.54
diff -u -r1.54 kern_thr.c
--- sys/kern/kern_thr.c 26 Oct 2006 21:42:20 -0000 1.54
+++ sys/kern/kern_thr.c 30 Oct 2006 17:07:55 -0000
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -164,7 +165,7 @@
case RTP_PRIO_REALTIME:
case RTP_PRIO_FIFO:
/* Only root can set scheduler policy */
- if (suser(td) != 0)
+ if (priv_check(td, PRIV_SCHED_SETPOLICY) != 0)
return (EPERM);
if (rtp->prio > RTP_PRIO_MAX)
return (EINVAL);
Index: sys/kern/kern_time.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_time.c,v
retrieving revision 1.134
diff -u -r1.134 kern_time.c
--- sys/kern/kern_time.c 22 Oct 2006 11:52:13 -0000 1.134
+++ sys/kern/kern_time.c 30 Oct 2006 17:07:55 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -286,7 +287,7 @@
if (error)
return (error);
#endif
- if ((error = suser(td)) != 0)
+ if ((error = priv_check(td, PRIV_CLOCK_SETTIME)) != 0)
return (error);
if (clock_id != CLOCK_REALTIME)
return (EINVAL);
@@ -504,7 +505,7 @@
if (error)
return (error);
#endif
- error = suser(td);
+ error = priv_check(td, PRIV_SETTIMEOFDAY);
if (error)
return (error);
/* Verify all parameters before changing time. */
Index: sys/kern/kern_umtx.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_umtx.c,v
retrieving revision 1.53
diff -u -r1.53 kern_umtx.c
--- sys/kern/kern_umtx.c 26 Oct 2006 21:42:20 -0000 1.53
+++ sys/kern/kern_umtx.c 30 Oct 2006 17:07:55 -0000
@@ -35,6 +35,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1813,7 +1814,7 @@
if ((error = umtx_key_get(m, TYPE_PP_UMUTEX, GET_SHARE(flags),
&uq->uq_key)) != 0)
return (error);
- su = (suser(td) == 0);
+ su = (priv_check(td, PRIV_SCHED_RTPRIO) == 0);
for (; {
old_inherited_pri = uq->uq_inherited_pri;
umtxq_lock(&uq->uq_key);
@@ -1934,7 +1935,7 @@

id = td->td_tid;
uq = td->td_umtxq;
- su = (suser(td) == 0);
+ su = (priv_check(td, PRIV_SCHED_RTPRIO) == 0);

/*
* Make sure we own this mtx.
Index: sys/kern/kern_xxx.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_xxx.c,v
retrieving revision 1.46
diff -u -r1.46 kern_xxx.c
--- sys/kern/kern_xxx.c 6 Jan 2005 23:35:39 -0000 1.46
+++ sys/kern/kern_xxx.c 30 Oct 2006 17:07:55 -0000
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -139,7 +140,8 @@
{
int error;

- if ((error = suser(td)))
+ error = priv_check(td, PRIV_SETHOSTID);
+ if (error)
return (error);
mtx_lock(&Giant);
hostid = uap->hostid;
@@ -295,9 +297,10 @@
{
int error, domainnamelen;

+ error = priv_check(td, PRIV_SETDOMAINNAME);
+ if (error)
+ return (error);
mtx_lock(&Giant);
- if ((error = suser(td)))
- goto done2;
if ((u_int)uap->len > sizeof (domainname) - 1) {
error = EINVAL;
goto done2;
@@ -309,4 +312,3 @@
mtx_unlock(&Giant);
return (error);
}
-
Index: sys/kern/subr_acl_posix1e.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/subr_acl_posix1e.c,v
retrieving revision 1.50
diff -u -r1.50 subr_acl_posix1e.c
--- sys/kern/subr_acl_posix1e.c 23 Jul 2006 19:35:10 -0000 1.50
+++ sys/kern/subr_acl_posix1e.c 31 Oct 2006 08:30:24 -0000
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -46,9 +47,9 @@

/*
* Implement a version of vaccess() that understands POSIX.1e ACL semantics;
- * the access ACL has already been prepared for evaluation by the file
- * system and is passed via 'uid', 'gid', and 'acl'. Return 0 on success,
- * else an errno value.
+ * the access ACL has already been prepared for evaluation by the file system
+ * and is passed via 'uid', 'gid', and 'acl'. Return 0 on success, else an
+ * errno value.
*/
int
vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid,
@@ -56,14 +57,14 @@
{
struct acl_entry *acl_other, *acl_mask;
mode_t dac_granted;
- mode_t cap_granted;
+ mode_t priv_granted;
mode_t acl_mask_granted;
int group_matched, i;

/*
* Look for a normal, non-privileged way to access the file/directory
* as requested. If it exists, go with that. Otherwise, attempt to
- * use privileges granted via cap_granted. In some cases, which
+ * use privileges granted via priv_granted. In some cases, which
* privileges to use may be ambiguous due to "best match", in which
* case fall back on first match for the time being.
*/
@@ -72,40 +73,34 @@

/*
* Determine privileges now, but don't apply until we've found a DAC
- * entry that matches but has failed to allow access. POSIX.1e
- * capabilities are not implemented, but we document how they would
- * behave here if implemented.
- */
-#ifndef CAPABILITIES
- if (suser_cred(cred, SUSER_ALLOWJAIL) == 0)
- cap_granted = VALLPERM;
- else
- cap_granted = 0;
-#else
- cap_granted = 0;
+ * entry that matches but has failed to allow access.
+ *
+ * XXXRW: Ideally, we'd determine the privileges required before
+ * asking for them.
+ */
+ priv_granted = 0;

if (type == VDIR) {
- if ((acc_mode & VEXEC) && !cap_check(cred, NULL,
- CAP_DAC_READ_SEARCH, SUSER_ALLOWJAIL))
- cap_granted |= VEXEC;
+ if ((acc_mode & VEXEC) && !priv_check_cred(cred,
+ PRIV_VFS_LOOKUP, SUSER_ALLOWJAIL))
+ priv_granted |= VEXEC;
} else {
- if ((acc_mode & VEXEC) && !cap_check(cred, NULL,
- CAP_DAC_EXECUTE, SUSER_ALLOWJAIL))
- cap_granted |= VEXEC;
+ if ((acc_mode & VEXEC) && !priv_check_cred(cred,
+ PRIV_VFS_EXEC, SUSER_ALLOWJAIL))
+ priv_granted |= VEXEC;
}

- if ((acc_mode & VREAD) && !cap_check(cred, NULL, CAP_DAC_READ_SEARCH,
+ if ((acc_mode & VREAD) && !priv_check_cred(cred, PRIV_VFS_READ,
SUSER_ALLOWJAIL))
- cap_granted |= VREAD;
+ priv_granted |= VREAD;

if (((acc_mode & VWRITE) || (acc_mode & VAPPEND)) &&
- !cap_check(cred, NULL, CAP_DAC_WRITE, SUSER_ALLOWJAIL))
- cap_granted |= (VWRITE | VAPPEND);
+ !priv_check_cred(cred, PRIV_VFS_WRITE, SUSER_ALLOWJAIL))
+ priv_granted |= (VWRITE | VAPPEND);

- if ((acc_mode & VADMIN) && !cap_check(cred, NULL, CAP_FOWNER,
+ if ((acc_mode & VADMIN) && !priv_check_cred(cred, PRIV_VFS_ADMIN,
SUSER_ALLOWJAIL))
- cap_granted |= VADMIN;
-#endif /* CAPABILITIES */
+ priv_granted |= VADMIN;

/*
* The owner matches if the effective uid associated with the
@@ -129,7 +124,11 @@
dac_granted |= (VWRITE | VAPPEND);
if ((acc_mode & dac_granted) == acc_mode)
return (0);
- if ((acc_mode & (dac_granted | cap_granted)) ==
+
+ /*
+ * XXXRW: Do privilege lookup here.
+ */
+ if ((acc_mode & (dac_granted | priv_granted)) ==
acc_mode) {
if (privused != NULL)
*privused = 1;
@@ -183,13 +182,9 @@
acl_mask_granted = VEXEC | VREAD | VWRITE | VAPPEND;

/*
- * Iterate through user ACL entries. Do checks twice, first without
- * privilege, and then if a match is found but failed, a second time
- * with privilege.
- */
-
- /*
- * Check ACL_USER ACL entries.
+ * Check ACL_USER ACL entries. There will either be one or no
+ * matches; if there is one, we accept or rejected based on the
+ * match; otherwise, we continue on to groups.
*/
for (i = 0; i < acl->acl_cnt; i++) {
switch (acl->acl_entry[i].ae_tag) {
@@ -206,7 +201,10 @@
dac_granted &= acl_mask_granted;
if ((acc_mode & dac_granted) == acc_mode)
return (0);
- if ((acc_mode & (dac_granted | cap_granted)) !=
+ /*
+ * XXXRW: Do privilege lookup here.
+ */
+ if ((acc_mode & (dac_granted | priv_granted)) !=
acc_mode)
goto error;

@@ -286,8 +284,11 @@
dac_granted |= (VWRITE | VAPPEND);
dac_granted &= acl_mask_granted;

- if ((acc_mode & (dac_granted | cap_granted)) !=
- acc_mode)
+ /*
+ * XXXRW: Do privilege lookup here.
+ */
+ if ((acc_mode & (dac_granted | priv_granted))
+ != acc_mode)
break;

if (privused != NULL)
@@ -307,8 +308,11 @@
dac_granted |= (VWRITE | VAPPEND);
dac_granted &= acl_mask_granted;

- if ((acc_mode & (dac_granted | cap_granted)) !=
- acc_mode)
+ /*
+ * XXXRW: Do privilege lookup here.
+ */
+ if ((acc_mode & (dac_granted | priv_granted))
+ != acc_mode)
break;

if (privused != NULL)
@@ -339,7 +343,10 @@

if ((acc_mode & dac_granted) == acc_mode)
return (0);
- if ((acc_mode & (dac_granted | cap_granted)) == acc_mode) {
+ /*
+ * XXXRW: Do privilege lookup here.
+ */
+ if ((acc_mode & (dac_granted | priv_granted)) == acc_mode) {
if (privused != NULL)
*privused = 1;
return (0);
Index: sys/kern/subr_firmware.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/subr_firmware.c,v
retrieving revision 1.5
diff -u -r1.5 subr_firmware.c
--- sys/kern/subr_firmware.c 25 Jun 2006 12:36:21 -0000 1.5
+++ sys/kern/subr_firmware.c 30 Oct 2006 17:07:55 -0000
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include

@@ -190,7 +191,8 @@
return NULL;
}
td = curthread;
- if (suser(td) != 0 || securelevel_gt(td->td_ucred, 0) != 0) {
+ if (priv_check(td, PRIV_FIRMWARE_LOAD) != 0 ||
+ securelevel_gt(td->td_ucred, 0) != 0) {
printf("%s: insufficient privileges to "
"load firmware image %s\n", __func__, imagename);
return NULL;
Index: sys/kern/subr_prf.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/subr_prf.c,v
retrieving revision 1.125
diff -u -r1.125 subr_prf.c
--- sys/kern/subr_prf.c 17 Sep 2006 20:00:35 -0000 1.125
+++ sys/kern/subr_prf.c 30 Oct 2006 17:07:55 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -870,7 +871,7 @@
int error, len;

if (!unprivileged_read_msgbuf) {
- error = suser(req->td);
+ error = priv_check(req->td, PRIV_MSGBUF);
if (error)
return (error);
}
Index: sys/kern/subr_witness.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/subr_witness.c,v
retrieving revision 1.218
diff -u -r1.218 subr_witness.c
--- sys/kern/subr_witness.c 13 Sep 2006 15:48:15 -0000 1.218
+++ sys/kern/subr_witness.c 30 Oct 2006 17:07:55 -0000
@@ -95,6 +95,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -533,7 +534,10 @@
error = sysctl_handle_int(oidp, &value, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
- error = suser(req->td);
+ /*
+ * XXXRW: Why a priv check here?
+ */
+ error = priv_check(req->td, PRIV_WITNESS);
if (error != 0)
return (error);
if (value == witness_watch)
Index: sys/kern/sysv_ipc.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/sysv_ipc.c,v
retrieving revision 1.29
diff -u -r1.29 sysv_ipc.c
--- sys/kern/sysv_ipc.c 6 Jan 2005 23:35:39 -0000 1.29
+++ sys/kern/sysv_ipc.c 31 Oct 2006 08:31:20 -0000
@@ -1,8 +1,12 @@
/* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */
/*-
* Copyright (c) 1994 Herb Peyerl
+ * 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:
@@ -39,6 +43,7 @@
#include
#include
#include
+#include
#include
#include

@@ -72,50 +77,73 @@
* Note: The MAC Framework does not require any modifications to the
* ipcperm() function, as access control checks are performed throughout the
* implementation of each primitive. Those entry point calls complement the
- * ipcperm() discertionary checks.
+ * ipcperm() discertionary checks. Unlike file system discretionary access
+ * control, the original create of an object is given the same rights as the
+ * current owner.
*/
int
-ipcperm(td, perm, mode)
- struct thread *td;
- struct ipc_perm *perm;
- int mode;
+ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode)
{
struct ucred *cred = td->td_ucred;
- int error;
+ int error, obj_mode, dac_granted, priv_granted;

- if (cred->cr_uid != perm->cuid && cred->cr_uid != perm->uid) {
- /*
- * For a non-create/owner, we require privilege to
- * modify the object protections. Note: some other
- * implementations permit IPC_M to be delegated to
- * unprivileged non-creator/owner uids/gids.
- */
- if (mode & IPC_M) {
- error = suser(td);
- if (error)
- return (error);
- }
- /*
- * Try to match against creator/owner group; if not, fall
- * back on other.
- */
- mode >>= 3;
- if (!groupmember(perm->gid, cred) &&
- !groupmember(perm->cgid, cred))
- mode >>= 3;
+ dac_granted = 0;
+ if (cred->cr_uid == perm->cuid || cred->cr_uid == perm->uid) {
+ obj_mode = perm->mode;
+ dac_granted |= IPC_M;
+ } else if (groupmember(perm->gid, cred) ||
+ groupmember(perm->cgid, cred)) {
+ obj_mode = perm->mode;
+ obj_mode <<= 3;
} else {
- /*
- * Always permit the creator/owner to update the object
- * protections regardless of whether the object mode
- * permits it.
- */
- if (mode & IPC_M)
- return (0);
+ obj_mode = perm->mode;
+ obj_mode <<= 6;
+ }
+
+ /*
+ * While the System V IPC permission model allows IPC_M to be
+ * granted, as part of the mode, our implementation requires
+ * privilege to adminster the object if not the owner or creator.
+ */
+#if 0
+ if (obj_mode & IPC_M)
+ dac_granted |= IPC_M;
+#endif
+ if (obj_mode & IPC_R)
+ dac_granted |= IPC_R;
+ if (obj_mode & IPC_W)
+ dac_granted |= IPC_W;
+
+ /*
+ * Simple case: all required rights are granted by DAC.
+ */
+ if ((dac_granted & acc_mode) == acc_mode)
+ return (0);
+
+ /*
+ * Privilege is required to satisfy the request.
+ */
+ priv_granted = 0;
+ if ((acc_mode & IPC_M) && !(dac_granted & IPC_M)) {
+ error = priv_check(td, PRIV_IPC_ADMIN);
+ if (error == 0)
+ priv_granted |= IPC_M;
}

- if ((mode & perm->mode) != mode) {
- if (suser(td) != 0)
- return (EACCES);
+ if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) {
+ error = priv_check(td, PRIV_IPC_READ);
+ if (error == 0)
+ priv_granted |= IPC_R;
}
- return (0);
+
+ if ((acc_mode & IPC_W) && !(dac_granted & IPC_W)) {
+ error = priv_check(td, PRIV_IPC_WRITE);
+ if (error == 0)
+ priv_granted |= IPC_W;
+ }
+
+ if (((dac_granted | priv_granted) & acc_mode) == acc_mode)
+ return (0);
+ else
+ return (EACCES);
}
Index: sys/kern/sysv_msg.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/sysv_msg.c,v
retrieving revision 1.63
diff -u -r1.63 sysv_msg.c
--- sys/kern/sysv_msg.c 22 Oct 2006 11:52:13 -0000 1.63
+++ sys/kern/sysv_msg.c 30 Oct 2006 17:07:55 -0000
@@ -57,6 +57,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -507,7 +508,7 @@
if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_M)))
goto done2;
if (msqbuf->msg_qbytes > msqkptr->u.msg_qbytes) {
- error = suser(td);
+ error = priv_check(td, PRIV_IPC_MSGSIZE);
if (error)
goto done2;
}
Index: sys/kern/tty.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/tty.c,v
retrieving revision 1.262
diff -u -r1.262 tty.c
--- sys/kern/tty.c 26 Oct 2006 21:42:20 -0000 1.262
+++ sys/kern/tty.c 30 Oct 2006 17:07:55 -0000
@@ -86,6 +86,7 @@
#if defined(COMPAT_43TTY)
#include
#endif
+#include
#include
#define TTYDEFCHARS
#include
@@ -1020,7 +1021,7 @@
break;
case TIOCMSDTRWAIT:
/* must be root since the wait applies to following logins */
- error = suser(td);
+ error = priv_check(td, PRIV_TTY_DTRWAIT);
if (error)
return (error);
tp->t_dtr_wait = *(int *)data * hz / 100;
@@ -1169,9 +1170,9 @@
splx(s);
break;
case TIOCSTI: /* simulate terminal input */
- if ((flag & FREAD) == 0 && suser(td))
+ if ((flag & FREAD) == 0 && priv_check(td, PRIV_TTY_STI))
return (EPERM);
- if (!isctty(p, tp) && suser(td))
+ if (!isctty(p, tp) && priv_check(td, PRIV_TTY_STI))
return (EACCES);
s = spltty();
ttyld_rint(tp, *(u_char *)data);
@@ -1244,7 +1245,7 @@
}
break;
case TIOCSDRAINWAIT:
- error = suser(td);
+ error = priv_check(td, PRIV_TTY_DRAINWAIT);
if (error)
return (error);
tp->t_timeout = *(int *)data * hz;
@@ -3114,7 +3115,8 @@
goto out;
goto open_top;
}
- if (tp->t_state & TS_XCLUDE && suser(td))
+ if (tp->t_state & TS_XCLUDE && priv_check(td,
+ PRIV_TTY_EXCLUSIVE))
return (EBUSY);
} else {
/*
@@ -3340,7 +3342,7 @@
ct = dev->si_drv2;
switch (cmd) {
case TIOCSETA:
- error = suser(td);
+ error = priv_check(td, PRIV_TTY_SETA);
if (error != 0)
return (error);
*ct = *(struct termios *)data;
Index: sys/kern/tty_cons.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/tty_cons.c,v
retrieving revision 1.135
diff -u -r1.135 tty_cons.c
--- sys/kern/tty_cons.c 26 May 2006 11:00:20 -0000 1.135
+++ sys/kern/tty_cons.c 30 Oct 2006 17:07:55 -0000
@@ -49,6 +49,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -506,7 +507,7 @@
* output from the "virtual" console.
*/
if (cmd == TIOCCONS && constty) {
- error = suser(td);
+ error = priv_check(td, PRIV_TTY_CONSOLE);
if (error)
return (error);
constty = NULL;
Index: sys/kern/tty_pts.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/tty_pts.c,v
retrieving revision 1.10
diff -u -r1.10 tty_pts.c
--- sys/kern/tty_pts.c 29 Sep 2006 09:53:19 -0000 1.10
+++ sys/kern/tty_pts.c 30 Oct 2006 17:07:55 -0000
@@ -56,6 +56,7 @@
#if defined(COMPAT_43TTY)
#include
#endif
+#include
#include
#include
#include
@@ -268,9 +269,11 @@
tp = dev->si_tty;
if ((tp->t_state & TS_ISOPEN) == 0)
ttyinitmode(tp, 1, 0);
- else if (tp->t_state & TS_XCLUDE && suser(td)) {
+ else if (tp->t_state & TS_XCLUDE && priv_check(td,
+ PRIV_TTY_EXCLUSIVE)) {
return (EBUSY);
- } else if (pt->pt_prison != td->td_ucred->cr_prison && suser(td)) {
+ } else if (pt->pt_prison != td->td_ucred->cr_prison &&
+ priv_check(td, PRIV_TTY_PRISON)) {
return (EBUSY);
}
if (tp->t_oproc) /* Ctrlr still around. */
Index: sys/kern/tty_pty.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/tty_pty.c,v
retrieving revision 1.150
diff -u -r1.150 tty_pty.c
--- sys/kern/tty_pty.c 4 Oct 2006 05:43:39 -0000 1.150
+++ sys/kern/tty_pty.c 30 Oct 2006 17:07:55 -0000
@@ -46,6 +46,7 @@
#if defined(COMPAT_43TTY)
#include
#endif
+#include
#include
#include
#include
@@ -207,9 +208,11 @@

if ((tp->t_state & TS_ISOPEN) == 0) {
ttyinitmode(tp, 1, 0);
- } else if (tp->t_state & TS_XCLUDE && suser(td))
+ } else if (tp->t_state & TS_XCLUDE && priv_check(td,
+ PRIV_TTY_EXCLUSIVE))
return (EBUSY);
- else if (pt->pt_prison != td->td_ucred->cr_prison && suser(td))
+ else if (pt->pt_prison != td->td_ucred->cr_prison &&
+ priv_check(td, PRIV_TTY_PRISON))
return (EBUSY);
if (tp->t_oproc) /* Ctrlr still around. */
(void)ttyld_modem(tp, 1);
Index: sys/kern/uipc_mqueue.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/uipc_mqueue.c,v
retrieving revision 1.16
diff -u -r1.16 uipc_mqueue.c
--- sys/kern/uipc_mqueue.c 26 Sep 2006 04:12:47 -0000 1.16
+++ sys/kern/uipc_mqueue.c 30 Oct 2006 17:07:55 -0000
@@ -65,6 +65,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -955,8 +956,12 @@

sx_assert(&pn->mn_info->mi_lock, SX_LOCKED);

+ /*
+ * XXXRW: Other instances of the message queue primitive are
+ * allowed in jail?
+ */
if (ucred->cr_uid != pn->mn_uid &&
- (error = suser_cred(ucred, 0)) != 0)
+ (error = priv_check_cred(ucred, PRIV_MQ_ADMIN, 0)) != 0)
error = EACCES;
else if (!pn->mn_deleted) {
parent = pn->mn_parent;
@@ -1207,10 +1212,16 @@
*/
if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td)))
return (error);
+
+ /*
+ * XXXRW: Why is there a privilege check here: shouldn't the
+ * check in VOP_ACCESS() be enough? Also, are the group bits
+ * below definitely right?
+ */
if (((ap->a_cred->cr_uid != pn->mn_uid) || uid != pn->mn_uid ||
(gid != pn->mn_gid && !groupmember(gid, ap->a_cred))) &&
- (error = suser_cred(ap->a_td->td_ucred, SUSER_ALLOWJAIL))
- != 0)
+ (error = priv_check_cred(ap->a_td->td_ucred,
+ PRIV_MQ_ADMIN, SUSER_ALLOWJAIL)) != 0)
return (error);
pn->mn_uid = uid;
pn->mn_gid = gid;
@@ -1219,7 +1230,8 @@

if (vap->va_mode != (mode_t)VNOVAL) {
if ((ap->a_cred->cr_uid != pn->mn_uid) &&
- (error = suser_cred(ap->a_td->td_ucred, SUSER_ALLOWJAIL)))
+ (error = priv_check_cred(ap->a_td->td_ucred,
+ PRIV_MQ_ADMIN, SUSER_ALLOWJAIL)))
return (error);
pn->mn_mode = vap->va_mode;
c = 1;
Index: sys/kern/uipc_sem.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/uipc_sem.c,v
retrieving revision 1.25
diff -u -r1.25 uipc_sem.c
--- sys/kern/uipc_sem.c 22 Oct 2006 11:52:13 -0000 1.25
+++ sys/kern/uipc_sem.c 30 Oct 2006 17:07:55 -0000
@@ -42,6 +42,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -419,15 +420,23 @@
{
struct ucred *uc;

+ /*
+ * XXXRW: This permission routine appears to be incorrect. If the
+ * user matches, we shouldn't go on to the group if the user
+ * permissions don't allow the action? Not changed for now. To fix,
+ * change from a series of if (); if (); to if () else if () else...
+ */
uc = td->td_ucred;
DP(("sem_perm: uc(%d,%d) ks(%d,%d,%o)\n",
uc->cr_uid, uc->cr_gid,
ks->ks_uid, ks->ks_gid, ks->ks_mode));
- if ((uc->cr_uid == ks->ks_uid && (ks->ks_mode & S_IWUSR) != 0) ||
- (uc->cr_gid == ks->ks_gid && (ks->ks_mode & S_IWGRP) != 0) ||
- (ks->ks_mode & S_IWOTH) != 0 || suser(td) == 0)
+ if ((uc->cr_uid == ks->ks_uid) && (ks->ks_mode & S_IWUSR) != 0)
+ return (0);
+ if ((uc->cr_gid == ks->ks_gid) && (ks->ks_mode & S_IWGRP) != 0)
+ return (0);
+ if ((ks->ks_mode & S_IWOTH) != 0)
return (0);
- return (EPERM);
+ return (priv_check(td, PRIV_SEM_WRITE));
}

static void
Index: sys/kern/vfs_mount.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/vfs_mount.c,v
retrieving revision 1.241
diff -u -r1.241 vfs_mount.c
--- sys/kern/vfs_mount.c 22 Oct 2006 11:52:14 -0000 1.241
+++ sys/kern/vfs_mount.c 30 Oct 2006 17:07:55 -0000
@@ -47,6 +47,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -808,23 +809,31 @@
if (jailed(td->td_ucred))
return (EPERM);
if (usermount == 0) {
- if ((error = suser(td)) != 0)
+ if ((error = priv_check(td, PRIV_VFS_MOUNT)) != 0)
return (error);
}

/*
* Do not allow NFS export or MNT_SUIDDIR by unprivileged users.
*/
- if (fsflags & (MNT_EXPORTED | MNT_SUIDDIR)) {
- if ((error = suser(td)) != 0)
+ if (fsflags & MNT_EXPORTED) {
+ error = priv_check(td, PRIV_VFS_MOUNT_EXPORTED);
+ if (error)
return (error);
}
+ if (fsflags & MNT_SUIDDIR) {
+ error = priv_check(td, PRIV_VFS_MOUNT_SUIDDIR);
+ if (error)
+ return (error);
+
+ }
/*
- * Silently enforce MNT_NOSUID and MNT_USER for
- * unprivileged users.
+ * Silently enforce MNT_NOSUID and MNT_USER for unprivileged users.
*/
- if (suser(td) != 0)
- fsflags |= MNT_NOSUID | MNT_USER;
+ if ((fsflags & (MNT_NOSUID | MNT_USER)) != (MNT_NOSUID | MNT_USER)) {
+ if (priv_check(td, PRIV_VFS_MOUNT_NONUSER) != 0)
+ fsflags |= MNT_NOSUID | MNT_USER;
+ }

/* Load KLDs before we lock the covered vnode to avoid reversals. */
vfsp = NULL;
@@ -906,7 +915,9 @@
return (error);
}
if (va.va_uid != td->td_ucred->cr_uid) {
- if ((error = suser(td)) != 0) {
+ error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN,
+ SUSER_ALLOWJAIL);
+ if (error) {
vput(vp);
return (error);
}
@@ -1078,7 +1089,8 @@
if (jailed(td->td_ucred))
return (EPERM);
if (usermount == 0) {
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_VFS_UNMOUNT);
+ if (error)
return (error);
}

Index: sys/kern/vfs_subr.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/vfs_subr.c,v
retrieving revision 1.686
diff -u -r1.686 vfs_subr.c
--- sys/kern/vfs_subr.c 22 Oct 2006 11:52:14 -0000 1.686
+++ sys/kern/vfs_subr.c 30 Oct 2006 17:07:55 -0000
@@ -61,6 +61,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -412,7 +413,7 @@

if ((mp->mnt_flag & MNT_USER) == 0 ||
mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) {
- if ((error = suser(td)) != 0)
+ if ((error = priv_check(td, PRIV_VFS_MOUNT_OWNER)) != 0)
return (error);
}
return (0);
@@ -3176,9 +3177,7 @@
mode_t acc_mode, struct ucred *cred, int *privused)
{
mode_t dac_granted;
-#ifdef CAPABILITIES
- mode_t cap_granted;
-#endif
+ mode_t priv_granted;

/*
* Look for a normal, non-privileged way to access the file/directory
@@ -3232,59 +3231,46 @@
return (0);

privcheck:
- if (!suser_cred(cred, SUSER_ALLOWJAIL)) {
- /* XXX audit: privilege used */
- if (privused != NULL)
- *privused = 1;
- return (0);
- }
-
-#ifdef CAPABILITIES
/*
- * Build a capability mask to determine if the set of capabilities
+ * Build a privilege mask to determine if the set of privileges
* satisfies the requirements when combined with the granted mask
- * from above. For each capability, if the capability is required,
- * bitwise or the request type onto the cap_granted mask.
- *
- * Note: This is never actually used, but is here for reference
- * purposes.
+ * from above. For each privilege, if the privilege is required,
+ * bitwise or the request type onto the priv_granted mask.
*/
- cap_granted = 0;
+ priv_granted = 0;

if (type == VDIR) {
/*
- * For directories, use CAP_DAC_READ_SEARCH to satisfy
- * VEXEC requests, instead of CAP_DAC_EXECUTE.
+ * For directories, use PRIV_VFS_LOOKUP to satisfy VEXEC
+ * requests, instead of PRIV_VFS_EXEC.
*/
if ((acc_mode & VEXEC) && ((dac_granted & VEXEC) == 0) &&
- !cap_check(cred, NULL, CAP_DAC_READ_SEARCH,
- SUSER_ALLOWJAIL))
- cap_granted |= VEXEC;
+ !priv_check_cred(cred, PRIV_VFS_LOOKUP, SUSER_ALLOWJAIL))
+ priv_granted |= VEXEC;
} else {
if ((acc_mode & VEXEC) && ((dac_granted & VEXEC) == 0) &&
- !cap_check(cred, NULL, CAP_DAC_EXECUTE, SUSER_ALLOWJAIL))
- cap_granted |= VEXEC;
+ !priv_check_cred(cred, PRIV_VFS_EXEC, SUSER_ALLOWJAIL))
+ priv_granted |= VEXEC;
}

if ((acc_mode & VREAD) && ((dac_granted & VREAD) == 0) &&
- !cap_check(cred, NULL, CAP_DAC_READ_SEARCH, SUSER_ALLOWJAIL))
- cap_granted |= VREAD;
+ !priv_check_cred(cred, PRIV_VFS_READ, SUSER_ALLOWJAIL))
+ priv_granted |= VREAD;

if ((acc_mode & VWRITE) && ((dac_granted & VWRITE) == 0) &&
- !cap_check(cred, NULL, CAP_DAC_WRITE, SUSER_ALLOWJAIL))
- cap_granted |= (VWRITE | VAPPEND);
+ !priv_check_cred(cred, PRIV_VFS_WRITE, SUSER_ALLOWJAIL))
+ priv_granted |= (VWRITE | VAPPEND);

if ((acc_mode & VADMIN) && ((dac_granted & VADMIN) == 0) &&
- !cap_check(cred, NULL, CAP_FOWNER, SUSER_ALLOWJAIL))
- cap_granted |= VADMIN;
+ !priv_check_cred(cred, PRIV_VFS_ADMIN, SUSER_ALLOWJAIL))
+ priv_granted |= VADMIN;

- if ((acc_mode & (cap_granted | dac_granted)) == acc_mode) {
+ if ((acc_mode & (priv_granted | dac_granted)) == acc_mode) {
/* XXX audit: privilege used */
if (privused != NULL)
*privused = 1;
return (0);
}
-#endif

return ((acc_mode & VADMIN) ? EPERM : EACCES);
}
@@ -3305,16 +3291,13 @@
return (0);

/*
- * Do not allow privileged processes in jail to directly
- * manipulate system attributes.
- *
- * XXX What capability should apply here?
- * Probably CAP_SYS_SETFFLAG.
+ * Do not allow privileged processes in jail to directly manipulate
+ * system attributes.
*/
switch (attrnamespace) {
case EXTATTR_NAMESPACE_SYSTEM:
/* Potentially should be: return (EPERM); */
- return (suser_cred(cred, 0));
+ return (priv_check_cred(cred, PRIV_VFS_EXTATTR_SYSTEM, 0));
case EXTATTR_NAMESPACE_USER:
return (VOP_ACCESS(vp, access, cred, td));
default:
Index: sys/kern/vfs_syscalls.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.427
diff -u -r1.427 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c 26 Oct 2006 13:20:28 -0000 1.427
+++ sys/kern/vfs_syscalls.c 30 Oct 2006 17:07:55 -0000
@@ -60,6 +60,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -272,7 +273,7 @@
error = VFS_STATFS(mp, sp, td);
if (error)
goto out;
- if (suser(td)) {
+ if (priv_check(td, PRIV_VFS_GENERATION)) {
bcopy(sp, &sb, sizeof(sb));
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
prison_enforce_statfs(td->td_ucred, mp, &sb);
@@ -357,7 +358,7 @@
error = VFS_STATFS(mp, sp, td);
if (error)
goto out;
- if (suser(td)) {
+ if (priv_check(td, PRIV_VFS_GENERATION)) {
bcopy(sp, &sb, sizeof(sb));
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
prison_enforce_statfs(td->td_ucred, mp, &sb);
@@ -468,7 +469,7 @@
vfs_unbusy(mp, td);
continue;
}
- if (suser(td)) {
+ if (priv_check(td, PRIV_VFS_GENERATION)) {
bcopy(sp, &sb, sizeof(sb));
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
prison_enforce_statfs(td->td_ucred, mp, &sb);
@@ -842,7 +843,8 @@
struct nameidata nd;
int vfslocked;

- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(td->td_ucred, PRIV_VFS_CHROOT,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
@@ -896,8 +898,8 @@

/*
* Common routine for kern_chroot() and jail_attach(). The caller is
- * responsible for invoking suser() and mac_check_chroot() to authorize this
- * operation.
+ * responsible for invoking priv_check() and mac_check_chroot() to authorize
+ * this operation.
*/
int
change_root(vp, td)
@@ -1186,10 +1188,16 @@
switch (mode & S_IFMT) {
case S_IFCHR:
case S_IFBLK:
- error = suser(td);
+ error = priv_check(td, PRIV_VFS_MKNOD_DEV);
+ break;
+ case S_IFMT:
+ error = priv_check(td, PRIV_VFS_MKNOD_BAD);
+ break;
+ case S_IFWHT:
+ error = priv_check(td, PRIV_VFS_MKNOD_WHT);
break;
default:
- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ error = EINVAL;
break;
}
if (error)
@@ -1234,8 +1242,7 @@
whiteout = 1;
break;
default:
- error = EINVAL;
- break;
+ panic("kern_mknod: invalid mode");
}
}
if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
@@ -1390,9 +1397,6 @@
struct vattr va;
int error;

- if (suser_cred(cred, SUSER_ALLOWJAIL) == 0)
- return (0);
-
if (!hardlink_check_uid && !hardlink_check_gid)
return (0);

@@ -1400,14 +1404,18 @@
if (error != 0)
return (error);

- if (hardlink_check_uid) {
- if (cred->cr_uid != va.va_uid)
- return (EPERM);
+ if (hardlink_check_uid && cred->cr_uid != va.va_uid) {
+ error = priv_check_cred(cred, PRIV_VFS_LINK,
+ SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
}

- if (hardlink_check_gid) {
- if (!groupmember(va.va_gid, cred))
- return (EPERM);
+ if (hardlink_check_gid && !groupmember(va.va_gid, cred)) {
+ error = priv_check_cred(cred, PRIV_VFS_LINK,
+ SUSER_ALLOWJAIL);
+ if (error)
+ return (error);
}

return (0);
@@ -2361,7 +2369,8 @@
* chown can't fail when done as root.
*/
if (vp->v_type == VCHR || vp->v_type == VBLK) {
- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(td->td_ucred, PRIV_VFS_CHFLAGS_DEV,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
}
@@ -3894,7 +3903,8 @@
if (error)
goto out;
if (td->td_ucred->cr_uid != vattr.va_uid) {
- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN,
+ SUSER_ALLOWJAIL);
if (error)
goto out;
}
@@ -3960,7 +3970,7 @@
int vfslocked;
int error;

- error = suser(td);
+ error = priv_check(td, PRIV_VFS_GETFH);
if (error)
return (error);
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
@@ -3999,7 +4009,7 @@
int vfslocked;
int error;

- error = suser(td);
+ error = priv_check(td, PRIV_VFS_GETFH);
if (error)
return (error);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
@@ -4022,10 +4032,10 @@
}

/*
- * syscall for the rpc.lockd to use to translate a NFS file handle into
- * an open descriptor.
+ * syscall for the rpc.lockd to use to translate a NFS file handle into an
+ * open descriptor.
*
- * warning: do not remove the suser() call or this becomes one giant
+ * warning: do not remove the priv_check() call or this becomes one giant
* security hole.
*
* MP SAFE
@@ -4058,7 +4068,7 @@
int vfslocked;
int indx;

- error = suser(td);
+ error = priv_check(td, PRIV_VFS_FHOPEN);
if (error)
return (error);
fmode = FFLAGS(uap->flags);
@@ -4242,7 +4252,7 @@
int vfslocked;
int error;

- error = suser(td);
+ error = priv_check(td, PRIV_VFS_FHSTAT);
if (error)
return (error);
error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
@@ -4307,7 +4317,7 @@
int vfslocked;
int error;

- error = suser(td);
+ error = priv_check(td, PRIV_VFS_FHSTATFS);
if (error)
return (error);
if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
Index: sys/kern/vfs_vnops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.245
diff -u -r1.245 vfs_vnops.c
--- sys/kern/vfs_vnops.c 22 Oct 2006 11:52:14 -0000 1.245
+++ sys/kern/vfs_vnops.c 30 Oct 2006 17:07:55 -0000
@@ -45,6 +45,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -709,7 +710,7 @@
sb->st_blksize = PAGE_SIZE;

sb->st_flags = vap->va_flags;
- if (suser(td))
+ if (priv_check(td, PRIV_VFS_GENERATION))
sb->st_gen = 0;
else
sb->st_gen = vap->va_gen;
Index: sys/net/bpf.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/bpf.c,v
retrieving revision 1.173
diff -u -r1.173 bpf.c
--- sys/net/bpf.c 22 Oct 2006 11:52:15 -0000 1.173
+++ sys/net/bpf.c 30 Oct 2006 17:07:55 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1724,7 +1725,7 @@
* if the users who opened the devices were able to retrieve
* the statistics for them, too.
*/
- error = suser(req->td);
+ error = priv_check(req->td, PRIV_NET_BPF);
if (error)
return (error);
if (req->oldptr == NULL)
Index: sys/net/if.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if.c,v
retrieving revision 1.263
diff -u -r1.263 if.c
--- sys/net/if.c 22 Oct 2006 11:52:15 -0000 1.263
+++ sys/net/if.c 30 Oct 2006 17:07:55 -0000
@@ -44,6 +44,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1489,7 +1490,7 @@
break;

case SIOCSIFFLAGS:
- error = suser(td);
+ error = priv_check(td, PRIV_NET_SETIFFLAGS);
if (error)
return (error);
/*
@@ -1532,7 +1533,7 @@
break;

case SIOCSIFCAP:
- error = suser(td);
+ error = priv_check(td, PRIV_NET_SETIFCAP);
if (error)
return (error);
if (ifp->if_ioctl == NULL)
@@ -1553,8 +1554,8 @@
#endif

case SIOCSIFNAME:
- error = suser(td);
- if (error != 0)
+ error = priv_check(td, PRIV_NET_SETIFNAME);
+ if (error)
return (error);
error = copyinstr(ifr->ifr_data, new_name, IFNAMSIZ, NULL);
if (error != 0)
@@ -1600,7 +1601,7 @@
break;

case SIOCSIFMETRIC:
- error = suser(td);
+ error = priv_check(td, PRIV_NET_SETIFMETRIC);
if (error)
return (error);
ifp->if_metric = ifr->ifr_metric;
@@ -1608,7 +1609,7 @@
break;

case SIOCSIFPHYS:
- error = suser(td);
+ error = priv_check(td, PRIV_NET_SETIFPHYS);
if (error)
return (error);
if (ifp->if_ioctl == NULL)
@@ -1624,7 +1625,7 @@
{
u_long oldmtu = ifp->if_mtu;

- error = suser(td);
+ error = priv_check(td, PRIV_NET_SETIFMTU);
if (error)
return (error);
if (ifr->ifr_mtu < IF_MINMTU || ifr->ifr_mtu > IF_MAXMTU)
@@ -1651,7 +1652,10 @@

case SIOCADDMULTI:
case SIOCDELMULTI:
- error = suser(td);
+ if (cmd == SIOCADDMULTI)
+ error = priv_check(td, PRIV_NET_ADDMULTI);
+ else
+ error = priv_check(td, PRIV_NET_DELMULTI);
if (error)
return (error);

@@ -1681,7 +1685,7 @@
case SIOCSLIFPHYADDR:
case SIOCSIFMEDIA:
case SIOCSIFGENERIC:
- error = suser(td);
+ error = priv_check(td, PRIV_NET_HWIOCTL);
if (error)
return (error);
if (ifp->if_ioctl == NULL)
@@ -1710,7 +1714,7 @@
break;

case SIOCSIFLLADDR:
- error = suser(td);
+ error = priv_check(td, PRIV_NET_SETLLADDR);
if (error)
return (error);
error = if_setlladdr(ifp,
@@ -1721,7 +1725,7 @@
{
struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr;

- error = suser(td);
+ error = priv_check(td, PRIV_NET_ADDIFGROUP);
if (error)
return (error);
if ((error = if_addgroup(ifp, ifgr->ifgr_group)))
@@ -1738,7 +1742,7 @@
{
struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr;

- error = suser(td);
+ error = priv_check(td, PRIV_NET_DELIFGROUP);
if (error)
return (error);
if ((error = if_delgroup(ifp, ifgr->ifgr_group)))
@@ -1777,12 +1781,14 @@
switch (cmd) {
case SIOCIFCREATE:
case SIOCIFCREATE2:
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_IFCREATE);
+ if (error)
return (error);
return (if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name),
cmd == SIOCIFCREATE2 ? ifr->ifr_data : NULL));
case SIOCIFDESTROY:
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_IFDESTROY);
+ if (error)
return (error);
return if_clone_destroy(ifr->ifr_name);

Index: sys/net/if_bridge.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_bridge.c,v
retrieving revision 1.82
diff -u -r1.82 if_bridge.c
--- sys/net/if_bridge.c 9 Oct 2006 00:49:57 -0000 1.82
+++ sys/net/if_bridge.c 30 Oct 2006 17:07:55 -0000
@@ -101,6 +101,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -678,7 +679,7 @@
}

if (bc->bc_flags & BC_F_SUSER) {
- error = suser(td);
+ error = priv_check(td, PRIV_NET_BRIDGE);
if (error)
break;
}
Index: sys/net/if_gre.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_gre.c,v
retrieving revision 1.44
diff -u -r1.44 if_gre.c
--- sys/net/if_gre.c 4 Aug 2006 21:27:37 -0000 1.44
+++ sys/net/if_gre.c 30 Oct 2006 17:07:55 -0000
@@ -57,6 +57,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -452,7 +453,11 @@
case SIOCSIFDSTADDR:
break;
case SIOCSIFFLAGS:
- if ((error = suser(curthread)) != 0)
+ /*
+ * XXXRW: Isn't this suser() redundant to the ifnet layer
+ * check?
+ */
+ if ((error = priv_check(curthread, PRIV_NET_SETIFFLAGS)) != 0)
break;
if ((ifr->ifr_flags & IFF_LINK0) != 0)
sc->g_proto = IPPROTO_GRE;
@@ -464,7 +469,11 @@
sc->wccp_ver = WCCP_V1;
goto recompute;
case SIOCSIFMTU:
- if ((error = suser(curthread)) != 0)
+ /*
+ * XXXRW: Isn't this suser() redundant to the ifnet layer
+ * check?
+ */
+ if ((error = priv_check(curthread, PRIV_NET_SETIFMTU)) != 0)
break;
if (ifr->ifr_mtu < 576) {
error = EINVAL;
@@ -476,8 +485,36 @@
ifr->ifr_mtu = GRE2IFP(sc)->if_mtu;
break;
case SIOCADDMULTI:
+ /*
+ * XXXRW: Isn't this suser() redundant to the ifnet layer
+ * check?
+ */
+ if ((error = priv_check(curthread, PRIV_NET_ADDMULTI)) != 0)
+ break;
+ if (ifr == 0) {
+ error = EAFNOSUPPORT;
+ break;
+ }
+ switch (ifr->ifr_addr.sa_family) {
+#ifdef INET
+ case AF_INET:
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ break;
+#endif
+ default:
+ error = EAFNOSUPPORT;
+ break;
+ }
+ break;
case SIOCDELMULTI:
- if ((error = suser(curthread)) != 0)
+ /*
+ * XXXRW: Isn't this suser() redundant to the ifnet layer
+ * check?
+ */
+ if ((error = priv_check(curthread, PRIV_NET_DELIFGROUP)) != 0)
break;
if (ifr == 0) {
error = EAFNOSUPPORT;
@@ -498,7 +535,11 @@
}
break;
case GRESPROTO:
- if ((error = suser(curthread)) != 0)
+ /*
+ * XXXRW: Isn't this suser() redundant to the ifnet layer
+ * check?
+ */
+ if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0)
break;
sc->g_proto = ifr->ifr_flags;
switch (sc->g_proto) {
@@ -518,8 +559,9 @@
break;
case GRESADDRS:
case GRESADDRD:
- if ((error = suser(curthread)) != 0)
- break;
+ error = priv_check(curthread, PRIV_NET_GRE);
+ if (error)
+ return (error);
/*
* set tunnel endpoints, compute a less specific route
* to the remote end and mark if as up
@@ -584,7 +626,11 @@
ifr->ifr_addr = *sa;
break;
case SIOCSIFPHYADDR:
- if ((error = suser(curthread)) != 0)
+ /*
+ * XXXRW: Isn't this suser() redundant to the ifnet layer
+ * check?
+ */
+ if ((error = priv_check(curthread, PRIV_NET_SETIFPHYS)) != 0)
break;
if (aifr->ifra_addr.sin_family != AF_INET ||
aifr->ifra_dstaddr.sin_family != AF_INET) {
@@ -600,7 +646,11 @@
sc->g_dst = aifr->ifra_dstaddr.sin_addr;
goto recompute;
case SIOCSLIFPHYADDR:
- if ((error = suser(curthread)) != 0)
+ /*
+ * XXXRW: Isn't this suser() redundant to the ifnet layer
+ * check?
+ */
+ if ((error = priv_check(curthread, PRIV_NET_SETIFPHYS)) != 0)
break;
if (lifr->addr.ss_family != AF_INET ||
lifr->dstaddr.ss_family != AF_INET) {
@@ -617,7 +667,11 @@
(satosin(&lifr->dstaddr))->sin_addr;
goto recompute;
case SIOCDIFPHYADDR:
- if ((error = suser(curthread)) != 0)
+ /*
+ * XXXRW: Isn't this suser() redundant to the ifnet layer
+ * check?
+ */
+ if ((error = priv_check(curthread, PRIV_NET_SETIFPHYS)) != 0)
break;
sc->g_src.s_addr = INADDR_ANY;
sc->g_dst.s_addr = INADDR_ANY;
Index: sys/net/if_ppp.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_ppp.c,v
retrieving revision 1.116
diff -u -r1.116 if_ppp.c
--- sys/net/if_ppp.c 22 Oct 2006 11:52:15 -0000 1.116
+++ sys/net/if_ppp.c 30 Oct 2006 17:07:55 -0000
@@ -87,6 +87,7 @@

#include
#include
+#include
#include
#include
#include
@@ -451,7 +452,8 @@
break;

case PPPIOCSFLAGS:
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_PPP);
+ if (error)
break;
flags = *(int *)data & SC_MASK;
s = splsoftnet();
@@ -465,8 +467,9 @@
break;

case PPPIOCSMRU:
- if ((error = suser(td)) != 0)
- return (error);
+ error = priv_check(td, PRIV_NET_PPP);
+ if (error)
+ return (error);
mru = *(int *)data;
if (mru >= PPP_MRU && mru <= PPP_MAXMRU)
sc->sc_mru = mru;
@@ -478,7 +481,8 @@

#ifdef VJC
case PPPIOCSMAXCID:
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_PPP);
+ if (error)
break;
if (sc->sc_comp) {
s = splsoftnet();
@@ -489,14 +493,16 @@
#endif

case PPPIOCXFERUNIT:
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_PPP);
+ if (error)
break;
sc->sc_xfer = p->p_pid;
break;

#ifdef PPP_COMPRESS
case PPPIOCSCOMPRESS:
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_PPP);
+ if (error)
break;
odp = (struct ppp_option_data *) data;
nb = odp->length;
@@ -569,7 +575,8 @@
if (cmd == PPPIOCGNPMODE) {
npi->mode = sc->sc_npmode[npx];
} else {
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_PPP);
+ if (error)
break;
if (npi->mode != sc->sc_npmode[npx]) {
s = splsoftnet();
@@ -695,6 +702,10 @@
break;

case SIOCSIFMTU:
+ /*
+ * XXXRW: Isn't this suser() check redundant to the one at the ifnet
+ * layer?
+ */
if ((error = suser(td)) != 0)
break;
if (ifr->ifr_mtu > PPP_MAXMTU)
Index: sys/net/if_sl.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_sl.c,v
retrieving revision 1.132
diff -u -r1.132 if_sl.c
--- sys/net/if_sl.c 2 Jun 2006 19:59:32 -0000 1.132
+++ sys/net/if_sl.c 30 Oct 2006 17:07:55 -0000
@@ -68,6 +68,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -366,7 +367,7 @@
register struct sl_softc *sc;
int s, error;

- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NET_SLIP);
if (error)
return (error);

Index: sys/net/if_tap.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_tap.c,v
retrieving revision 1.63
diff -u -r1.63 if_tap.c
--- sys/net/if_tap.c 27 Sep 2006 19:57:01 -0000 1.63
+++ sys/net/if_tap.c 30 Oct 2006 17:07:55 -0000
@@ -47,6 +47,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -373,10 +374,13 @@
{
struct tap_softc *tp = NULL;
struct ifnet *ifp = NULL;
- int s;
+ int error, s;

- if (tapuopen == 0 && suser(td) != 0)
- return (EPERM);
+ if (tapuopen == 0) {
+ error = priv_check(td, PRIV_NET_TAP);
+ if (error)
+ return (error);
+ }

if ((dev2unit(dev) & CLONE_UNITMASK) > TAPMAXUNIT)
return (ENXIO);
Index: sys/net/if_tun.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_tun.c,v
retrieving revision 1.159
diff -u -r1.159 if_tun.c
--- sys/net/if_tun.c 22 Oct 2006 11:52:15 -0000 1.159
+++ sys/net/if_tun.c 30 Oct 2006 17:07:55 -0000
@@ -23,6 +23,7 @@
#include "opt_mac.h"

#include
+#include
#include
#include
#include
@@ -597,9 +598,11 @@
tunp = (struct tuninfo *)data;
if (tunp->mtu < IF_MINMTU)
return (EINVAL);
- if (TUN2IFP(tp)->if_mtu != tunp->mtu
- && (error = suser(td)) != 0)
- return (error);
+ if (TUN2IFP(tp)->if_mtu != tunp->mtu) {
+ error = priv_check(td, PRIV_NET_SETIFMTU);
+ if (error)
+ return (error);
+ }
TUN2IFP(tp)->if_mtu = tunp->mtu;
TUN2IFP(tp)->if_type = tunp->type;
TUN2IFP(tp)->if_baudrate = tunp->baudrate;
Index: sys/net/ppp_tty.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/ppp_tty.c,v
retrieving revision 1.69
diff -u -r1.69 ppp_tty.c
--- sys/net/ppp_tty.c 16 Oct 2005 20:44:18 -0000 1.69
+++ sys/net/ppp_tty.c 30 Oct 2006 17:07:55 -0000
@@ -79,6 +79,7 @@

#include
#include
+#include
#include
#include
#include
@@ -179,7 +180,8 @@
register struct ppp_softc *sc;
int error, s;

- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_PPP);
+ if (error)
return (error);

s = spltty();
@@ -423,7 +425,8 @@
error = 0;
switch (cmd) {
case PPPIOCSASYNCMAP:
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_PPP);
+ if (error)
break;
sc->sc_asyncmap[0] = *(u_int *)data;
break;
@@ -433,7 +436,8 @@
break;

case PPPIOCSRASYNCMAP:
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_PPP);
+ if (error)
break;
sc->sc_rasyncmap = *(u_int *)data;
break;
@@ -443,7 +447,8 @@
break;

case PPPIOCSXASYNCMAP:
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_NET_PPP);
+ if (error)
break;
s = spltty();
bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
Index: sys/net/raw_usrreq.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/raw_usrreq.c,v
retrieving revision 1.43
diff -u -r1.43 raw_usrreq.c
--- sys/net/raw_usrreq.c 21 Jul 2006 17:11:12 -0000 1.43
+++ sys/net/raw_usrreq.c 30 Oct 2006 17:07:55 -0000
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -171,8 +172,11 @@
*/
KASSERT(sotorawcb(so) != NULL, ("raw_uattach: so_pcb == NULL"));

- if (td && (error = suser(td)) != 0)
- return error;
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NET_RAW);
+ if (error)
+ return error;
+ }
return raw_attach(so, proto);
}

Index: sys/net/rtsock.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/rtsock.c,v
retrieving revision 1.137
diff -u -r1.137 rtsock.c
--- sys/net/rtsock.c 21 Jul 2006 17:11:12 -0000 1.137
+++ sys/net/rtsock.c 30 Oct 2006 17:07:55 -0000
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -368,8 +369,11 @@
* Verify that the caller has the appropriate privilege; RTM_GET
* is the only operation the non-superuser is allowed.
*/
- if (rtm->rtm_type != RTM_GET && (error = suser(curthread)) != 0)
- senderr(error);
+ if (rtm->rtm_type != RTM_GET) {
+ error = priv_check(curthread, PRIV_NET_ROUTE);
+ if (error)
+ senderr(error);
+ }

switch (rtm->rtm_type) {
struct rtentry *saved_nrt;
Index: sys/net80211/ieee80211_ioctl.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net80211/ieee80211_ioctl.c,v
retrieving revision 1.50
diff -u -r1.50 ieee80211_ioctl.c
--- sys/net80211/ieee80211_ioctl.c 26 Sep 2006 12:41:13 -0000 1.50
+++ sys/net80211/ieee80211_ioctl.c 30 Oct 2006 17:07:55 -0000
@@ -45,6 +45,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -344,7 +345,7 @@
case WI_RID_DEFLT_CRYPT_KEYS:
keys = (struct wi_ltv_keys *)&wreq;
/* do not show keys to non-root user */
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NET80211_GETKEY);
if (error) {
memset(keys, 0, sizeof(*keys));
error = 0;
@@ -861,7 +862,7 @@
ik.ik_flags = wk->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV);
if (wk->wk_keyix == ic->ic_def_txkey)
ik.ik_flags |= IEEE80211_KEY_DEFAULT;
- if (suser(curthread) == 0) {
+ if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) {
/* NB: only root can read key data */
ik.ik_keyrsc = wk->wk_keyrsc;
ik.ik_keytsc = wk->wk_keytsc;
@@ -1510,7 +1511,7 @@
return EINVAL;
len = (u_int) ic->ic_nw_keys[kid].wk_keylen;
/* NB: only root can read WEP keys */
- if (suser(curthread) == 0) {
+ if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) {
bcopy(ic->ic_nw_keys[kid].wk_key, tmpkey, len);
} else {
bzero(tmpkey, len);
@@ -2692,7 +2693,7 @@
(struct ieee80211req *) data);
break;
case SIOCS80211:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NET80211_MANAGE);
if (error == 0)
error = ieee80211_ioctl_set80211(ic, cmd,
(struct ieee80211req *) data);
@@ -2701,7 +2702,7 @@
error = ieee80211_cfgget(ic, cmd, data);
break;
case SIOCSIFGENERIC:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NET80211_MANAGE);
if (error)
break;
error = ieee80211_cfgset(ic, cmd, data);
Index: sys/netatalk/at_control.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netatalk/at_control.c,v
retrieving revision 1.44
diff -u -r1.44 at_control.c
--- sys/netatalk/at_control.c 22 Feb 2005 14:20:29 -0000 1.44
+++ sys/netatalk/at_control.c 30 Oct 2006 17:07:55 -0000
@@ -118,6 +118,8 @@
case SIOCSIFADDR:
/*
* If we are not superuser, then we don't get to do these ops.
+ *
+ * XXXRW: Layering?
*/
if (suser(td))
return (EPERM);
Index: sys/netatalk/ddp_pcb.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netatalk/ddp_pcb.c,v
retrieving revision 1.49
diff -u -r1.49 ddp_pcb.c
--- sys/netatalk/ddp_pcb.c 2 Aug 2006 16:22:34 -0000 1.49
+++ sys/netatalk/ddp_pcb.c 30 Oct 2006 17:07:55 -0000
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -100,7 +101,7 @@
return (EINVAL);
}
if (sat->sat_port < ATPORT_RESERVED &&
- suser(td)) {
+ priv_check(td, PRIV_NETATALK_RESERVEDPORT)) {
return (EACCES);
}
}
Index: sys/netatm/atm_usrreq.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netatm/atm_usrreq.c,v
retrieving revision 1.27
diff -u -r1.27 atm_usrreq.c
--- sys/netatm/atm_usrreq.c 21 Jul 2006 17:11:13 -0000 1.27
+++ sys/netatm/atm_usrreq.c 30 Oct 2006 17:07:55 -0000
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -181,8 +182,11 @@
struct atmcfgreq *acp = (struct atmcfgreq *)data;
struct atm_pif *pip;

- if (td && (suser(td) != 0))
- ATM_RETERR(EPERM);
+ if (td != 0) {
+ err = priv_check(td, PRIV_NETATM_CFG);
+ if (err)
+ ATM_RETERR(err);
+ }

switch (acp->acr_opcode) {

@@ -214,8 +218,11 @@
struct atmaddreq *aap = (struct atmaddreq *)data;
Atm_endpoint *epp;

- if (td && (suser(td) != 0))
- ATM_RETERR(EPERM);
+ if (td != NULL) {
+ err = priv_check(td, PRIV_NETATM_ADD);
+ if (err)
+ ATM_RETERR(err);
+ }

switch (aap->aar_opcode) {

@@ -264,8 +271,11 @@
struct sigmgr *smp;
Atm_endpoint *epp;

- if (td && (suser(td) != 0))
- ATM_RETERR(EPERM);
+ if (td != NULL) {
+ err = priv_check(td, PRIV_NETATM_DEL);
+ if (err)
+ ATM_RETERR(err);
+ }

switch (adp->adr_opcode) {

@@ -317,8 +327,11 @@
struct sigmgr *smp;
struct ifnet *ifp2;

- if (td && (suser(td) != 0))
- ATM_RETERR(EPERM);
+ if (td != NULL) {
+ err = priv_check(td, PRIV_NETATM_SET);
+ if (err)
+ ATM_RETERR(err);
+ }

switch (asp->asr_opcode) {

Index: sys/netgraph/ng_socket.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netgraph/ng_socket.c,v
retrieving revision 1.80
diff -u -r1.80 ng_socket.c
--- sys/netgraph/ng_socket.c 18 Oct 2006 07:47:07 -0000 1.80
+++ sys/netgraph/ng_socket.c 30 Oct 2006 17:07:55 -0000
@@ -57,6 +57,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -167,9 +168,11 @@
ngc_attach(struct socket *so, int proto, struct thread *td)
{
struct ngpcb *const pcbp = sotongpcb(so);
+ int error;

- if (suser(td))
- return (EPERM);
+ error = priv_check(td, PRIV_NETGRAPH_CONTROL);
+ if (error)
+ return (error);
if (pcbp != NULL)
return (EISCONN);
return (ng_attach_cntl(so));
Index: sys/netgraph/ng_tty.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netgraph/ng_tty.c,v
retrieving revision 1.36
diff -u -r1.36 ng_tty.c
--- sys/netgraph/ng_tty.c 16 Oct 2005 20:44:18 -0000 1.36
+++ sys/netgraph/ng_tty.c 30 Oct 2006 17:07:55 -0000
@@ -66,6 +66,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -189,7 +190,8 @@
int error;

/* Super-user only */
- if ((error = suser(td)))
+ error = priv_check(td, PRIV_NETGRAPH_TTY);
+ if (error)
return (error);

/* Initialize private struct */
Index: sys/netgraph/bluetooth/drivers/h4/ng_h4.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netgraph/bluetooth/drivers/h4/ng_h4.c,v
retrieving revision 1.14
diff -u -r1.14 ng_h4.c
--- sys/netgraph/bluetooth/drivers/h4/ng_h4.c 16 Oct 2005 20:44:18 -0000 1.14
+++ sys/netgraph/bluetooth/drivers/h4/ng_h4.c 30 Oct 2006 17:07:55 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -156,7 +157,7 @@
int s, error;

/* Super-user only */
- error = suser(curthread); /* XXX */
+ error = priv_check(curthread, PRIV_NETGRAPH_TTY); /* XXX */
if (error != 0)
return (error);

Index: sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c,v
retrieving revision 1.22
diff -u -r1.22 ng_btsocket_hci_raw.c
--- sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c 21 Jul 2006 17:11:13 -0000 1.22
+++ sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c 30 Oct 2006 17:07:55 -0000
@@ -44,6 +44,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -916,7 +917,7 @@
so->so_pcb = (caddr_t) pcb;
pcb->so = so;

- if (suser(td) == 0)
+ if (priv_check(td, PRIV_NETBLUETOOTH_RAW) == 0)
pcb->flags |= NG_BTSOCKET_HCI_RAW_PRIVILEGED;

/*
Index: sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c,v
retrieving revision 1.19
diff -u -r1.19 ng_btsocket_l2cap_raw.c
--- sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c 21 Jul 2006 17:11:13 -0000 1.19
+++ sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c 30 Oct 2006 17:07:55 -0000
@@ -43,6 +43,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -620,7 +621,7 @@
so->so_pcb = (caddr_t) pcb;
pcb->so = so;

- if (suser(td) == 0)
+ if (priv_check(td, PRIV_NETBLUETOOTH_RAW) == 0)
pcb->flags |= NG_BTSOCKET_L2CAP_RAW_PRIVILEGED;

mtx_init(&pcb->pcb_mtx, "btsocks_l2cap_raw_pcb_mtx", NULL, MTX_DEF);
Index: sys/netinet/in.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/in.c,v
retrieving revision 1.94
diff -u -r1.94 in.c
--- sys/netinet/in.c 28 Sep 2006 10:04:07 -0000 1.94
+++ sys/netinet/in.c 30 Oct 2006 17:07:55 -0000
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -232,10 +233,25 @@

switch (cmd) {
case SIOCALIFADDR:
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NET_ADDIFADDR);
+ if (error)
+ return (error);
+ }
+ if (!ifp)
+ return EINVAL;
+ return in_lifaddr_ioctl(so, cmd, data, ifp, td);
+
case SIOCDLIFADDR:
- if (td && (error = suser(td)) != 0)
- return error;
- /*fall through*/
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NET_DELIFADDR);
+ if (error)
+ return (error);
+ }
+ if (!ifp)
+ return EINVAL;
+ return in_lifaddr_ioctl(so, cmd, data, ifp, td);
+
case SIOCGLIFADDR:
if (!ifp)
return EINVAL;
@@ -292,8 +308,11 @@
case SIOCSIFADDR:
case SIOCSIFNETMASK:
case SIOCSIFDSTADDR:
- if (td && (error = suser(td)) != 0)
- return error;
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NET_ADDIFADDR);
+ if (error)
+ return (error);
+ }

if (ifp == 0)
return (EADDRNOTAVAIL);
@@ -330,8 +349,11 @@
break;

case SIOCSIFBRDADDR:
- if (td && (error = suser(td)) != 0)
- return error;
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NET_ADDIFADDR);
+ if (error)
+ return (error);
+ }
/* FALLTHROUGH */

case SIOCGIFADDR:
Index: sys/netinet/in_pcb.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/in_pcb.c,v
retrieving revision 1.182
diff -u -r1.182 in_pcb.c
--- sys/netinet/in_pcb.c 22 Oct 2006 11:52:16 -0000 1.182
+++ sys/netinet/in_pcb.c 30 Oct 2006 17:07:55 -0000
@@ -42,6 +42,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -331,7 +332,8 @@
/* GROSS */
if (ntohs(lport) <= ipport_reservedhigh &&
ntohs(lport) >= ipport_reservedlow &&
- suser_cred(cred, SUSER_ALLOWJAIL))
+ priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT,
+ SUSER_ALLOWJAIL))
return (EACCES);
if (jailed(cred))
prison = 1;
@@ -400,7 +402,9 @@
last = ipport_hilastauto;
lastport = &pcbinfo->lasthi;
} else if (inp->inp_flags & INP_LOWPORT) {
- if ((error = suser_cred(cred, SUSER_ALLOWJAIL)) != 0)
+ error = priv_check_cred(cred,
+ PRIV_NETINET_RESERVEDPORT, SUSER_ALLOWJAIL);
+ if (error)
return error;
first = ipport_lowfirstauto; /* 1023 */
last = ipport_lowlastauto; /* 600 */
Index: sys/netinet/ip_carp.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/ip_carp.c,v
retrieving revision 1.44
diff -u -r1.44 ip_carp.c
--- sys/netinet/ip_carp.c 7 Oct 2006 10:19:58 -0000 1.44
+++ sys/netinet/ip_carp.c 30 Oct 2006 17:07:55 -0000
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1853,7 +1854,8 @@
break;

case SIOCSVH:
- if ((error = suser(curthread)) != 0)
+ error = priv_check(curthread, PRIV_NETINET_CARP);
+ if (error)
break;
if ((error = copyin(ifr->ifr_data, &carpr, sizeof carpr)))
break;
@@ -1928,7 +1930,8 @@
carpr.carpr_vhid = sc->sc_vhid;
carpr.carpr_advbase = sc->sc_advbase;
carpr.carpr_advskew = sc->sc_advskew;
- if (suser(curthread) == 0)
+ error = priv_check(curthread, PRIV_NETINET_CARP);
+ if (error == 0)
bcopy(sc->sc_key, carpr.carpr_key,
sizeof(carpr.carpr_key));
error = copyout(&carpr, ifr->ifr_data, sizeof(carpr));
Index: sys/netinet/ip_divert.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/ip_divert.c,v
retrieving revision 1.121
diff -u -r1.121 ip_divert.c
--- sys/netinet/ip_divert.c 22 Oct 2006 11:52:16 -0000 1.121
+++ sys/netinet/ip_divert.c 30 Oct 2006 17:07:55 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -420,8 +421,11 @@

inp = sotoinpcb(so);
KASSERT(inp == NULL, ("div_attach: inp != NULL"));
- if (td && (error = suser(td)) != 0)
- return error;
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NETINET_DIVERT);
+ if (error)
+ return (error);
+ }
error = soreserve(so, div_sendspace, div_recvspace);
if (error)
return error;
Index: sys/netinet/ip_fw2.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.152
diff -u -r1.152 ip_fw2.c
--- sys/netinet/ip_fw2.c 22 Oct 2006 11:52:16 -0000 1.152
+++ sys/netinet/ip_fw2.c 30 Oct 2006 17:07:55 -0000
@@ -53,6 +53,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -3980,7 +3981,7 @@
struct ip_fw *buf, *rule;
u_int32_t rulenum[2];

- error = suser(sopt->sopt_td);
+ error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW);
if (error)
return (error);

Index: sys/netinet/ip_mroute.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/ip_mroute.c,v
retrieving revision 1.121
diff -u -r1.121 ip_mroute.c
--- sys/netinet/ip_mroute.c 22 Oct 2006 11:52:16 -0000 1.121
+++ sys/netinet/ip_mroute.c 30 Oct 2006 17:07:56 -0000
@@ -68,6 +68,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -576,7 +577,7 @@
* Typically, only root can create the raw socket in order to execute
* this ioctl method, however the request might be coming from a prison
*/
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NETINET_MROUTE);
if (error)
return (error);
switch (cmd) {
Index: sys/netinet/ip_output.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/ip_output.c,v
retrieving revision 1.267
diff -u -r1.267 ip_output.c
--- sys/netinet/ip_output.c 22 Oct 2006 11:52:16 -0000 1.267
+++ sys/netinet/ip_output.c 30 Oct 2006 17:07:56 -0000
@@ -40,6 +40,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -987,8 +988,20 @@
break;
if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
break;
- priv = (sopt->sopt_td != NULL &&
- suser(sopt->sopt_td) != 0) ? 0 : 1;
+ if (sopt->sopt_td != NULL) {
+ /*
+ * XXXRW: Would be more desirable to do this
+ * one layer down so that we only exercise
+ * privilege if it is needed.
+ */
+ error = priv_check(sopt->sopt_td,
+ PRIV_NETINET_IPSEC);
+ if (error)
+ priv = 0;
+ else
+ priv = 1;
+ } else
+ priv = 1;
req = mtod(m, caddr_t);
len = m->m_len;
optname = sopt->sopt_name;
Index: sys/netinet/raw_ip.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/raw_ip.c,v
retrieving revision 1.166
diff -u -r1.166 raw_ip.c
--- sys/netinet/raw_ip.c 22 Oct 2006 11:52:16 -0000 1.166
+++ sys/netinet/raw_ip.c 30 Oct 2006 17:07:56 -0000
@@ -40,6 +40,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -387,7 +388,11 @@
case IP_FW_GET:
case IP_FW_TABLE_GETSIZE:
case IP_FW_TABLE_LIST:
- error = suser(curthread);
+ /*
+ * XXXRW: Isn't this checked one layer down? Yes, it
+ * is.
+ */
+ error = priv_check(curthread, PRIV_NETINET_IPFW);
if (error != 0)
return (error);
if (ip_fw_ctl_ptr != NULL)
@@ -397,7 +402,7 @@
break;

case IP_DUMMYNET_GET:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NETINET_DUMMYNET);
if (error != 0)
return (error);
if (ip_dn_ctl_ptr != NULL)
@@ -418,7 +423,7 @@
case MRT_API_CONFIG:
case MRT_ADD_BW_UPCALL:
case MRT_DEL_BW_UPCALL:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NETINET_MROUTE);
if (error != 0)
return (error);
error = ip_mrouter_get ? ip_mrouter_get(so, sopt) :
@@ -452,7 +457,10 @@
case IP_FW_TABLE_ADD:
case IP_FW_TABLE_DEL:
case IP_FW_TABLE_FLUSH:
- error = suser(curthread);
+ /*
+ * XXXRW: Isn't this checked one layer down?
+ */
+ error = priv_check(curthread, PRIV_NETINET_IPFW);
if (error != 0)
return (error);
if (ip_fw_ctl_ptr != NULL)
@@ -464,7 +472,7 @@
case IP_DUMMYNET_CONFIGURE:
case IP_DUMMYNET_DEL:
case IP_DUMMYNET_FLUSH:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NETINET_DUMMYNET);
if (error != 0)
return (error);
if (ip_dn_ctl_ptr != NULL)
@@ -474,14 +482,14 @@
break ;

case IP_RSVP_ON:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NETINET_MROUTE);
if (error != 0)
return (error);
error = ip_rsvp_init(so);
break;

case IP_RSVP_OFF:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NETINET_MROUTE);
if (error != 0)
return (error);
error = ip_rsvp_done();
@@ -489,7 +497,7 @@

case IP_RSVP_VIF_ON:
case IP_RSVP_VIF_OFF:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NETINET_MROUTE);
if (error != 0)
return (error);
error = ip_rsvp_vif ?
@@ -508,7 +516,7 @@
case MRT_API_CONFIG:
case MRT_ADD_BW_UPCALL:
case MRT_DEL_BW_UPCALL:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NETINET_MROUTE);
if (error != 0)
return (error);
error = ip_mrouter_set ? ip_mrouter_set(so, sopt) :
@@ -598,9 +606,14 @@

inp = sotoinpcb(so);
KASSERT(inp == NULL, ("rip_attach: inp != NULL"));
+ /*
+ * XXXRW: Centralize privilege decision in kern_jail.c.
+ */
if (jailed(td->td_ucred) && !jail_allow_raw_sockets)
return (EPERM);
- if ((error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0)
+ error = priv_check_cred(td->td_ucred, PRIV_NETINET_RAW,
+ SUSER_ALLOWJAIL);
+ if (error)
return error;
if (proto >= IPPROTO_MAX || proto < 0)
return EPROTONOSUPPORT;
Index: sys/netinet/tcp_subr.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.265
diff -u -r1.265 tcp_subr.c
--- sys/netinet/tcp_subr.c 22 Oct 2006 11:52:16 -0000 1.265
+++ sys/netinet/tcp_subr.c 30 Oct 2006 17:07:56 -0000
@@ -48,6 +48,7 @@
#ifdef INET6
#include
#endif
+#include
#include
#include
#include
@@ -1081,7 +1082,8 @@
struct inpcb *inp;
int error;

- error = suser_cred(req->td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
error = SYSCTL_IN(req, addrs, sizeof(addrs));
@@ -1125,7 +1127,8 @@
struct inpcb *inp;
int error, mapped = 0;

- error = suser_cred(req->td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
error = SYSCTL_IN(req, addrs, sizeof(addrs));
Index: sys/netinet/udp_usrreq.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.195
diff -u -r1.195 udp_usrreq.c
--- sys/netinet/udp_usrreq.c 22 Oct 2006 11:52:17 -0000 1.195
+++ sys/netinet/udp_usrreq.c 30 Oct 2006 17:07:56 -0000
@@ -44,6 +44,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -687,7 +688,8 @@
struct inpcb *inp;
int error;

- error = suser_cred(req->td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
error = SYSCTL_IN(req, addrs, sizeof(addrs));
Index: sys/netinet6/in6.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet6/in6.c,v
retrieving revision 1.64
diff -u -r1.64 in6.c
--- sys/netinet6/in6.c 22 Sep 2006 01:42:22 -0000 1.64
+++ sys/netinet6/in6.c 30 Oct 2006 17:07:56 -0000
@@ -71,6 +71,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -325,12 +326,8 @@
struct in6_ifreq *ifr = (struct in6_ifreq *)data;
struct in6_ifaddr *ia = NULL;
struct in6_aliasreq *ifra = (struct in6_aliasreq *)data;
- int error, privileged;
struct sockaddr_in6 *sa6;
-
- privileged = 0;
- if (td == NULL || !suser(td))
- privileged++;
+ int error;

switch (cmd) {
case SIOCGETSGCNT_IN6:
@@ -341,8 +338,11 @@
switch(cmd) {
case SIOCAADDRCTL_POLICY:
case SIOCDADDRCTL_POLICY:
- if (!privileged)
- return (EPERM);
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NETINET_ADDRCTRL6);
+ if (error)
+ return (error);
+ }
return (in6_src_ioctl(cmd, data));
}

@@ -355,8 +355,11 @@
case SIOCSRTRFLUSH_IN6:
case SIOCSDEFIFACE_IN6:
case SIOCSIFINFO_FLAGS:
- if (!privileged)
- return (EPERM);
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NETINET_ND6);
+ if (error)
+ return (error);
+ }
/* FALLTHROUGH */
case OSIOCGIFINFO_IN6:
case SIOCGIFINFO_IN6:
@@ -383,8 +386,11 @@

switch (cmd) {
case SIOCSSCOPE6:
- if (!privileged)
- return (EPERM);
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NETINET_SCOPE6);
+ if (error)
+ return (error);
+ }
return (scope6_set(ifp,
(struct scope6_id *)ifr->ifr_ifru.ifru_scope_id));
case SIOCGSCOPE6:
@@ -398,8 +404,15 @@
switch (cmd) {
case SIOCALIFADDR:
case SIOCDLIFADDR:
- if (!privileged)
- return (EPERM);
+ /*
+ * XXXRW: Is this checked at another layer? What priv to use
+ * here?
+ */
+ if (td != NULL) {
+ error = suser(td);
+ if (error)
+ return (error);
+ }
/* FALLTHROUGH */
case SIOCGLIFADDR:
return in6_lifaddr_ioctl(so, cmd, data, ifp, td);
@@ -488,8 +501,16 @@
if (ifra->ifra_addr.sin6_family != AF_INET6 ||
ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6))
return (EAFNOSUPPORT);
- if (!privileged)
- return (EPERM);
+
+ /*
+ * XXXRW: Is this checked at another layer? What priv to use
+ * here?
+ */
+ if (td != NULL) {
+ error = suser(td);
+ if (error)
+ return (error);
+ }

break;

@@ -508,8 +529,11 @@
{
struct in6_addrlifetime *lt;

- if (!privileged)
- return (EPERM);
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NETINET_ALIFETIME6);
+ if (error)
+ return (error);
+ }
if (ia == NULL)
return (EADDRNOTAVAIL);
/* sanity for overflow - beware unsigned */
Index: sys/netinet6/in6_pcb.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet6/in6_pcb.c,v
retrieving revision 1.73
diff -u -r1.73 in6_pcb.c
--- sys/netinet6/in6_pcb.c 18 Jul 2006 22:34:27 -0000 1.73
+++ sys/netinet6/in6_pcb.c 30 Oct 2006 17:07:56 -0000
@@ -77,6 +77,7 @@
#include
#include
#include
+#include
#include
#include

@@ -190,8 +191,12 @@
/* GROSS */
if (ntohs(lport) <= ipport_reservedhigh &&
ntohs(lport) >= ipport_reservedlow &&
- suser_cred(cred, SUSER_ALLOWJAIL))
+ priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT,
+ SUSER_ALLOWJAIL))
return (EACCES);
+ /*
+ * XXXRW: What priv to use here?
+ */
if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) &&
suser_cred(so->so_cred, SUSER_ALLOWJAIL) != 0) {
t = in6_pcblookup_local(pcbinfo,
Index: sys/netinet6/in6_src.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet6/in6_src.c,v
retrieving revision 1.39
diff -u -r1.39 in6_src.c
--- sys/netinet6/in6_src.c 4 Aug 2006 21:27:38 -0000 1.39
+++ sys/netinet6/in6_src.c 30 Oct 2006 17:07:56 -0000
@@ -68,6 +68,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -772,7 +773,9 @@
last = ipport_hilastauto;
lastport = &pcbinfo->lasthi;
} else if (inp->inp_flags & INP_LOWPORT) {
- if ((error = suser_cred(cred, 0)))
+ error = priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT,
+ SUSER_ALLOWJAIL);
+ if (error)
return error;
first = ipport_lowfirstauto; /* 1023 */
last = ipport_lowlastauto; /* 600 */
Index: sys/netinet6/ipsec.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet6/ipsec.c,v
retrieving revision 1.46
diff -u -r1.46 ipsec.c
--- sys/netinet6/ipsec.c 4 Aug 2006 21:27:39 -0000 1.46
+++ sys/netinet6/ipsec.c 30 Oct 2006 17:07:56 -0000
@@ -43,6 +43,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1221,8 +1222,14 @@
}
bzero(new, sizeof(*new));

- if (so->so_cred != NULL &&
- suser_cred(so->so_cred, SUSER_ALLOWJAIL) == 0)
+ /*
+ * XXXRW: Can we avoid caching the privilege decision here, and
+ * instead cache the credential?
+ *
+ * XXXRW: Why is suser_allowjail set here?
+ */
+ if (so->so_cred != NULL && priv_check_cred(so->so_cred,
+ PRIV_NETINET_IPSEC, 0) == 0)
new->priv = 1;
else
new->priv = 0;
Index: sys/netinet6/udp6_usrreq.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet6/udp6_usrreq.c,v
retrieving revision 1.68
diff -u -r1.68 udp6_usrreq.c
--- sys/netinet6/udp6_usrreq.c 7 Sep 2006 18:44:54 -0000 1.68
+++ sys/netinet6/udp6_usrreq.c 30 Oct 2006 17:07:56 -0000
@@ -70,6 +70,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -434,7 +435,8 @@
struct inpcb *inp;
int error;

- error = suser(req->td);
+ error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED,
+ SUSER_ALLOWJAIL);
if (error)
return (error);

Index: sys/netipsec/ipsec_osdep.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netipsec/ipsec_osdep.h,v
retrieving revision 1.3
diff -u -r1.3 ipsec_osdep.h
--- sys/netipsec/ipsec_osdep.h 27 Jun 2006 11:41:21 -0000 1.3
+++ sys/netipsec/ipsec_osdep.h 30 Oct 2006 17:07:56 -0000
@@ -215,11 +215,13 @@
* NetBSD (1.6N) tests (so)->so_uid == 0).
* This difference is wrapped inside the IPSEC_PRIVILEGED_SO() macro.
*
+ * XXXRW: Why was this suser_allowjail?
*/
#ifdef __FreeBSD__
#define IPSEC_IS_PRIVILEGED_SO(_so) \
((_so)->so_cred != NULL && \
- suser_cred((_so)->so_cred, SUSER_ALLOWJAIL) == 0)
+ priv_check_cred((_so)->so_cred, PRIV_NETINET_IPSEC, 0) \
+ == 0)
#endif /* __FreeBSD__ */

#ifdef __NetBSD__
Index: sys/netipx/ipx_pcb.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netipx/ipx_pcb.c,v
retrieving revision 1.45
diff -u -r1.45 ipx_pcb.c
--- sys/netipx/ipx_pcb.c 25 Mar 2006 17:28:42 -0000 1.45
+++ sys/netipx/ipx_pcb.c 30 Oct 2006 17:07:56 -0000
@@ -42,6 +42,7 @@
#include
#include
#include
+#include
#include
#include

@@ -107,11 +108,10 @@
lport = sipx->sipx_port;
if (lport) {
u_short aport = ntohs(lport);
- int error;

- if (aport < IPXPORT_RESERVED &&
- td != NULL && (error = suser(td)) != 0)
- return (error);
+ if (aport < IPXPORT_RESERVED && td != NULL &&
+ priv_check(td, PRIV_NETIPX_RESERVEDPORT))
+ return (EACCES);
if (ipx_pcblookup(&zeroipx_addr, lport, 0))
return (EADDRINUSE);
}
Index: sys/netipx/ipx_usrreq.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netipx/ipx_usrreq.c,v
retrieving revision 1.57
diff -u -r1.57 ipx_usrreq.c
--- sys/netipx/ipx_usrreq.c 21 Jul 2006 17:11:14 -0000 1.57
+++ sys/netipx/ipx_usrreq.c 30 Oct 2006 17:07:56 -0000
@@ -45,6 +45,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -658,8 +659,13 @@
struct ipxpcb *ipxp = sotoipxpcb(so);

KASSERT(ipxp == NULL, ("ripx_attach: ipxp != NULL"));
- if (td != NULL && (error = suser(td)) != 0)
- return (error);
+
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NETIPX_RAW);
+ if (error)
+ return (error);
+ }
+
/*
* We hold the IPX list lock for the duration as address parameters
* of the IPX pcb are changed. Since no one else holds a reference
Index: sys/netncp/ncp_conn.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netncp/ncp_conn.c,v
retrieving revision 1.28
diff -u -r1.28 ncp_conn.c
--- sys/netncp/ncp_conn.c 14 Jan 2006 11:40:32 -0000 1.28
+++ sys/netncp/ncp_conn.c 30 Oct 2006 17:07:56 -0000
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
#include
Index: sys/netncp/ncp_mod.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netncp/ncp_mod.c,v
retrieving revision 1.15
diff -u -r1.15 ncp_mod.c
--- sys/netncp/ncp_mod.c 7 Jan 2005 01:45:48 -0000 1.15
+++ sys/netncp/ncp_mod.c 30 Oct 2006 17:07:56 -0000
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include
#include
#include
Index: sys/netncp/ncp_subr.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netncp/ncp_subr.h,v
retrieving revision 1.9
diff -u -r1.9 ncp_subr.h
--- sys/netncp/ncp_subr.h 7 Jan 2005 01:45:49 -0000 1.9
+++ sys/netncp/ncp_subr.h 30 Oct 2006 17:07:56 -0000
@@ -84,7 +84,7 @@

#define checkbad(fn) {error=(fn);if(error) goto bad;}

-#define ncp_suser(cred) suser_cred(cred, 0)
+#define ncp_suser(cred) priv_check_cred(cred, PRIV_NETNCP, 0)

#define ncp_isowner(conn,cred) ((cred)->cr_uid == (conn)->nc_owner->cr_uid)

Index: sys/netsmb/smb_conn.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netsmb/smb_conn.c,v
retrieving revision 1.17
diff -u -r1.17 smb_conn.c
--- sys/netsmb/smb_conn.c 17 Jul 2006 16:12:59 -0000 1.17
+++ sys/netsmb/smb_conn.c 30 Oct 2006 17:07:56 -0000
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
#include
#include
#include
Index: sys/netsmb/smb_subr.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netsmb/smb_subr.h,v
retrieving revision 1.12
diff -u -r1.12 smb_subr.h
--- sys/netsmb/smb_subr.h 7 Jan 2005 01:45:49 -0000 1.12
+++ sys/netsmb/smb_subr.h 30 Oct 2006 17:07:56 -0000
@@ -68,7 +68,7 @@
SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) || \
SIGISMEMBER(set, SIGQUIT))

-#define smb_suser(cred) suser_cred(cred, 0)
+#define smb_suser(cred) priv_check_cred(cred, PRIV_NETSMB, 0)

/*
* Compatibility wrappers for simple locks
Index: sys/nfsserver/nfs_syscalls.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/nfsserver/nfs_syscalls.c,v
retrieving revision 1.107
diff -u -r1.107 nfs_syscalls.c
--- sys/nfsserver/nfs_syscalls.c 22 Oct 2006 11:52:17 -0000 1.107
+++ sys/nfsserver/nfs_syscalls.c 30 Oct 2006 17:07:56 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -142,7 +143,7 @@
if (error)
return (error);
#endif
- error = suser(td);
+ error = priv_check(td, PRIV_NFSD);
if (error)
return (error);
NET_LOCK_GIANT();
Index: sys/pc98/cbus/fdc.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/pc98/cbus/fdc.c,v
retrieving revision 1.167
diff -u -r1.167 fdc.c
--- sys/pc98/cbus/fdc.c 8 Sep 2006 21:46:01 -0000 1.167
+++ sys/pc98/cbus/fdc.c 30 Oct 2006 17:07:56 -0000
@@ -68,6 +68,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -2512,7 +2513,7 @@
#endif

case FD_CLRERR:
- if (suser(td) != 0)
+ if (priv_check(td, PRIV_DRIVER) != 0)
return (EPERM);
fd->fdc->fdc_errs = 0;
return (0);
@@ -2556,7 +2557,7 @@

case FD_STYPE: /* set drive type */
/* this is considered harmful; only allow for superuser */
- if (suser(td) != 0)
+ if (priv_check(td, PRIV_DRIVER) != 0)
return (EPERM);
*fd->ft = *(struct fd_type *)addr;
break;
@@ -2580,7 +2581,7 @@
#endif

case FD_CLRERR:
- if (suser(td) != 0)
+ if (priv_check(td, PRIV_DRIVER) != 0)
return (EPERM);
fd->fdc->fdc_errs = 0;
break;
Index: sys/posix4/p1003_1b.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/posix4/p1003_1b.c,v
retrieving revision 1.30
diff -u -r1.30 p1003_1b.c
--- sys/posix4/p1003_1b.c 13 Jul 2006 06:41:26 -0000 1.30
+++ sys/posix4/p1003_1b.c 30 Oct 2006 17:07:56 -0000
@@ -44,6 +44,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -186,9 +187,10 @@
struct thread *targettd;
struct proc *targetp;

- /* Don't allow non root user to set a scheduler policy */
- if (suser(td) != 0)
- return (EPERM);
+ /* Don't allow non root user to set a scheduler policy. */
+ e = priv_check(td, PRIV_SCHED_SET);
+ if (e)
+ return (e);

e = copyin(uap->param, &sched_param, sizeof(sched_param));
if (e)
Index: sys/security/audit/audit.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/audit/audit.c,v
retrieving revision 1.21
diff -u -r1.21 audit.c
--- sys/security/audit/audit.c 2 Oct 2006 11:32:23 -0000 1.21
+++ sys/security/audit/audit.c 30 Oct 2006 17:07:56 -0000
@@ -42,6 +42,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -509,7 +510,8 @@
* audit record is still required for this event by
* re-calling au_preselect().
*/
- if (audit_in_failure && suser(td) != 0) {
+ if (audit_in_failure &&
+ priv_check(td, PRIV_AUDIT_FAILSTOP) != 0) {
cv_wait(&audit_fail_cv, &audit_mtx);
panic("audit_failing_stop: thread continued");
}
Index: sys/security/audit/audit_pipe.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/audit/audit_pipe.c,v
retrieving revision 1.9
diff -u -r1.9 audit_pipe.c
--- sys/security/audit/audit_pipe.c 26 Aug 2006 17:59:31 -0000 1.9
+++ sys/security/audit/audit_pipe.c 30 Oct 2006 17:07:56 -0000
@@ -626,9 +626,9 @@
}

/*
- * Audit pipe open method. Explicit suser check isn't used as this allows
- * file permissions on the special device to be used to grant audit review
- * access.
+ * Audit pipe open method. Explicit privilege check isn't used as this
+ * allows file permissions on the special device to be used to grant audit
+ * review access. Those file permissions should be managed carefully.
*/
static int
audit_pipe_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
Index: sys/security/audit/audit_syscalls.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/audit/audit_syscalls.c,v
retrieving revision 1.8
diff -u -r1.8 audit_syscalls.c
--- sys/security/audit/audit_syscalls.c 10 Oct 2006 15:49:10 -0000 1.8
+++ sys/security/audit/audit_syscalls.c 30 Oct 2006 17:07:56 -0000
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -66,7 +67,7 @@

if (jailed(td->td_ucred))
return (ENOSYS);
- error = suser(td);
+ error = priv_check(td, PRIV_AUDIT_SUBMIT);
if (error)
return (error);

@@ -156,7 +157,7 @@
if (jailed(td->td_ucred))
return (ENOSYS);
AUDIT_ARG(cmd, uap->cmd);
- error = suser(td);
+ error = priv_check(td, PRIV_AUDIT_CONTROL);
if (error)
return (error);

@@ -404,7 +405,7 @@

if (jailed(td->td_ucred))
return (ENOSYS);
- error = suser(td);
+ error = priv_check(td, PRIV_AUDIT_GETAUDIT);
if (error)
return (error);

@@ -428,7 +429,7 @@

if (jailed(td->td_ucred))
return (ENOSYS);
- error = suser(td);
+ error = priv_check(td, PRIV_AUDIT_SETAUDIT);
if (error)
return (error);

@@ -468,7 +469,7 @@

if (jailed(td->td_ucred))
return (ENOSYS);
- error = suser(td);
+ error = priv_check(td, PRIV_AUDIT_GETAUDIT);
if (error)
return (error);

@@ -489,7 +490,7 @@

if (jailed(td->td_ucred))
return (ENOSYS);
- error = suser(td);
+ error = priv_check(td, PRIV_AUDIT_SETAUDIT);
if (error)
return (error);

@@ -518,7 +519,7 @@

if (jailed(td->td_ucred))
return (ENOSYS);
- error = suser(td);
+ error = priv_check(td, PRIV_AUDIT_GETAUDIT);
if (error)
return (error);
return (ENOSYS);
@@ -533,7 +534,7 @@

if (jailed(td->td_ucred))
return (ENOSYS);
- error = suser(td);
+ error = priv_check(td, PRIV_AUDIT_SETAUDIT);
if (error)
return (error);
return (ENOSYS);
@@ -557,7 +558,7 @@

if (jailed(td->td_ucred))
return (ENOSYS);
- error = suser(td);
+ error = priv_check(td, PRIV_AUDIT_CONTROL);
if (error)
return (error);

Index: sys/security/mac/mac_framework.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac/mac_framework.h,v
retrieving revision 1.74
diff -u -r1.74 mac_framework.h
--- sys/security/mac/mac_framework.h 25 Oct 2006 13:14:25 -0000 1.74
+++ sys/security/mac/mac_framework.h 30 Oct 2006 17:07:56 -0000
@@ -407,6 +407,8 @@
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
Index: sys/security/mac/mac_internal.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac/mac_internal.h,v
retrieving revision 1.114
diff -u -r1.114 mac_internal.h
--- sys/security/mac/mac_internal.h 20 Sep 2006 13:33:40 -0000 1.114
+++ sys/security/mac/mac_internal.h 30 Oct 2006 17:07:56 -0000
@@ -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 @@
} 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
Index: sys/security/mac/mac_net.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac/mac_net.c,v
retrieving revision 1.119
diff -u -r1.119 mac_net.c
--- sys/security/mac/mac_net.c 22 Oct 2006 11:52:18 -0000 1.119
+++ sys/security/mac/mac_net.c 30 Oct 2006 17:07:56 -0000
@@ -45,6 +45,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -470,11 +471,11 @@
}

/*
- * XXX: Note that this is a redundant privilege check, since
- * policies impose this check themselves if required by the
- * policy. Eventually, this should go away.
+ * XXX: Note that this is a redundant privilege check, since policies
+ * impose this check themselves if required by the policy.
+ * Eventually, this should go away.
*/
- error = suser_cred(cred, 0);
+ error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0);
if (error) {
mac_ifnet_label_free(intlabel);
return (error);
Index: sys/security/mac/mac_priv.c
================================================== =================
RCS file: sys/security/mac/mac_priv.c
diff -N sys/security/mac/mac_priv.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/security/mac/mac_priv.c 30 Oct 2006 18:53:30 -0000
@@ -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
+#include
+#include
+#include
+
+#include
+#include
+
+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);
+}
Index: sys/security/mac/mac_system.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac/mac_system.c,v
retrieving revision 1.106
diff -u -r1.106 mac_system.c
--- sys/security/mac/mac_system.c 22 Oct 2006 11:52:18 -0000 1.106
+++ sys/security/mac/mac_system.c 30 Oct 2006 17:07:56 -0000
@@ -60,6 +60,12 @@
&mac_enforce_system, 0, "Enforce MAC policy on system operations");
TUNABLE_INT("security.mac.enforce_system", &mac_enforce_system);

+/*
+ * XXXRW: Some of these checks now duplicate privilege checks. However,
+ * others provide additional security context that may be useful to policies.
+ * We need to review these and remove ones that are pure duplicates.
+ */
+
int
mac_check_kenv_dump(struct ucred *cred)
{
Index: sys/security/mac_bsdextended/mac_bsdextended.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac_bsdextended/mac_bsdextended.c,v
retrieving revision 1.29
diff -u -r1.29 mac_bsdextended.c
--- sys/security/mac_bsdextended/mac_bsdextended.c 23 Apr 2006 17:06:18 -0000 1.29
+++ sys/security/mac_bsdextended/mac_bsdextended.c 30 Oct 2006 17:07:56 -0000
@@ -456,6 +456,9 @@
{
int error, i;

+ /*
+ * XXXRW: More specific privilege selection needed?
+ */
if (suser_cred(cred, 0) == 0)
return (0);

Index: sys/security/mac_lomac/mac_lomac.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac_lomac/mac_lomac.c,v
retrieving revision 1.41
diff -u -r1.41 mac_lomac.c
--- sys/security/mac_lomac/mac_lomac.c 22 Oct 2006 11:52:19 -0000 1.41
+++ sys/security/mac_lomac/mac_lomac.c 30 Oct 2006 17:07:56 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1697,8 +1698,10 @@
* Rely on the traditional superuser status for the LOMAC
* interface relabel requirements. XXXMAC: This will go
* away.
+ *
+ * XXXRW: This is also redundant to a higher layer check.
*/
- error = suser_cred(cred, 0);
+ error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0);
if (error)
return (EPERM);

Index: sys/security/mac_partition/mac_partition.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac_partition/mac_partition.c,v
retrieving revision 1.11
diff -u -r1.11 mac_partition.c
--- sys/security/mac_partition/mac_partition.c 19 Sep 2005 18:52:50 -0000 1.11
+++ sys/security/mac_partition/mac_partition.c 30 Oct 2006 17:07:56 -0000
@@ -45,6 +45,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -191,7 +192,7 @@
* in a partition in the first place, but this didn't
* interact well with sendmail.
*/
- error = suser_cred(cred, 0);
+ error = priv_check_cred(cred, PRIV_MAC_PARTITION, 0);
}

return (error);
Index: sys/security/mac_portacl/mac_portacl.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac_portacl/mac_portacl.c,v
retrieving revision 1.9
diff -u -r1.9 mac_portacl.c
--- sys/security/mac_portacl/mac_portacl.c 10 Oct 2006 17:04:19 -0000 1.9
+++ sys/security/mac_portacl/mac_portacl.c 30 Oct 2006 17:07:56 -0000
@@ -66,6 +66,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -427,7 +428,8 @@
mtx_unlock(&rule_mtx);

if (error != 0 && mac_portacl_suser_exempt != 0)
- error = suser_cred(cred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT,
+ SUSER_ALLOWJAIL);

return (error);
}
Index: sys/security/mac_seeotheruids/mac_seeotheruids.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac_seeotheruids/mac_seeotheruids.c,v
retrieving revision 1.8
diff -u -r1.8 mac_seeotheruids.c
--- sys/security/mac_seeotheruids/mac_seeotheruids.c 30 Sep 2005 23:41:10 -0000 1.8
+++ sys/security/mac_seeotheruids/mac_seeotheruids.c 30 Oct 2006 17:07:56 -0000
@@ -46,6 +46,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -126,7 +127,7 @@
return (0);

if (suser_privileged) {
- if (suser_cred(u1, 0) == 0)
+ if (priv_check_cred(u1, PRIV_SEEOTHERUIDS, 0) == 0)
return (0);
}

Index: sys/sun4v/sun4v/hvcons.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/sun4v/sun4v/hvcons.c,v
retrieving revision 1.2
diff -u -r1.2 hvcons.c
--- sys/sun4v/sun4v/hvcons.c 13 Oct 2006 06:45:50 -0000 1.2
+++ sys/sun4v/sun4v/hvcons.c 30 Oct 2006 17:07:56 -0000
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#include
#include

@@ -118,7 +119,8 @@
ttyconsolemode(tp, 0);

setuptimeout = 1;
- } else if ((tp->t_state & TS_XCLUDE) && suser(td)) {
+ } else if ((tp->t_state & TS_XCLUDE) && priv_check(td,
+ PRIV_TTY_EXCLUSIVE)) {
return (EBUSY);
}

Index: sys/sys/jail.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/sys/jail.h,v
retrieving revision 1.26
diff -u -r1.26 jail.h
--- sys/sys/jail.h 9 Jun 2005 18:49:19 -0000 1.26
+++ sys/sys/jail.h 30 Oct 2006 18:52:31 -0000
@@ -110,6 +110,7 @@
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 */
Index: sys/sys/mac_policy.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/sys/mac_policy.h,v
retrieving revision 1.77
diff -u -r1.77 mac_policy.h
--- sys/sys/mac_policy.h 30 Oct 2006 15:20:49 -0000 1.77
+++ sys/sys/mac_policy.h 30 Oct 2006 17:07:56 -0000
@@ -596,6 +596,8 @@
struct ucred *file_cred, struct vnode *vp,
struct label *label);
typedef void (*mpo_associate_nfsd_label_t)(struct ucred *cred);
+typedef int (*mpo_priv_check_t)(struct ucred *cred, int priv);
+typedef int (*mpo_priv_grant_t)(struct ucred *cred, int priv);

struct mac_policy_ops {
/*
@@ -886,6 +888,8 @@
mpo_check_vnode_write_t mpo_check_vnode_write;
mpo_associate_nfsd_label_t mpo_associate_nfsd_label;
mpo_create_mbuf_from_firewall_t mpo_create_mbuf_from_firewall;
+ mpo_priv_check_t mpo_priv_check;
+ mpo_priv_grant_t mpo_priv_grant;
};

/*
Index: sys/sys/priv.h
================================================== =================
RCS file: sys/sys/priv.h
diff -N sys/sys/priv.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/sys/priv.h 31 Oct 2006 08:20:40 -0000
@@ -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_ */
Index: sys/sys/systm.h
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/sys/systm.h,v
retrieving revision 1.245
diff -u -r1.245 systm.h
--- sys/sys/systm.h 17 Oct 2006 02:24:47 -0000 1.245
+++ sys/sys/systm.h 30 Oct 2006 17:07:56 -0000
@@ -230,7 +230,7 @@
#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);

Index: sys/ufs/ffs/ffs_alloc.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ffs/ffs_alloc.c,v
retrieving revision 1.140
diff -u -r1.140 ffs_alloc.c
--- sys/ufs/ffs/ffs_alloc.c 18 Jul 2006 07:03:43 -0000 1.140
+++ sys/ufs/ffs/ffs_alloc.c 30 Oct 2006 17:07:56 -0000
@@ -71,6 +71,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -171,7 +172,7 @@
#endif
if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0)
goto nospace;
- if (suser_cred(cred, SUSER_ALLOWJAIL) &&
+ if (priv_check_cred(cred, PRIV_VFS_BLOCKRESERVE, SUSER_ALLOWJAIL) &&
freespace(fs, fs->fs_minfree) - numfrags(fs, size) < 0)
goto nospace;
if (bpref >= fs->fs_size)
@@ -259,7 +260,7 @@
#endif /* DIAGNOSTIC */
reclaimed = 0;
retry:
- if (suser_cred(cred, SUSER_ALLOWJAIL) &&
+ if (priv_check_cred(cred, PRIV_VFS_BLOCKRESERVE, SUSER_ALLOWJAIL) &&
freespace(fs, fs->fs_minfree) - numfrags(fs, nsize - osize) < 0) {
goto nospace;
}
Index: sys/ufs/ffs/ffs_vfsops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.321
diff -u -r1.321 ffs_vfsops.c
--- sys/ufs/ffs/ffs_vfsops.c 22 Oct 2006 11:52:19 -0000 1.321
+++ sys/ufs/ffs/ffs_vfsops.c 30 Oct 2006 17:07:56 -0000
@@ -40,6 +40,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -257,15 +258,16 @@
* If upgrade to read-write by non-root, then verify
* that user has necessary permissions on the device.
*/
- if (suser(td)) {
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
- if ((error = VOP_ACCESS(devvp, VREAD | VWRITE,
- td->td_ucred, td)) != 0) {
- VOP_UNLOCK(devvp, 0, td);
- return (error);
- }
+ vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
+ error = VOP_ACCESS(devvp, VREAD | VWRITE,
+ td->td_ucred, td);
+ if (error)
+ error = priv_check(td, PRIV_VFS_MOUNT_PERM);
+ if (error) {
VOP_UNLOCK(devvp, 0, td);
+ return (error);
}
+ VOP_UNLOCK(devvp, 0, td);
fs->fs_flags &= ~FS_UNCLEAN;
if (fs->fs_clean == 0) {
fs->fs_flags |= FS_UNCLEAN;
@@ -364,14 +366,15 @@
* If mount by non-root, then verify that user has necessary
* permissions on the device.
*/
- if (suser(td)) {
- accessmode = VREAD;
- if ((mp->mnt_flag & MNT_RDONLY) == 0)
- accessmode |= VWRITE;
- if ((error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td))!= 0){
- vput(devvp);
- return (error);
- }
+ accessmode = VREAD;
+ if ((mp->mnt_flag & MNT_RDONLY) == 0)
+ accessmode |= VWRITE;
+ error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td);
+ if (error)
+ error = priv_check(td, PRIV_VFS_MOUNT_PERM);
+ if (error) {
+ vput(devvp);
+ return (error);
}

if (mp->mnt_flag & MNT_UPDATE) {
Index: sys/ufs/ffs/ffs_vnops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ffs/ffs_vnops.c,v
retrieving revision 1.161
diff -u -r1.161 ffs_vnops.c
--- sys/ufs/ffs/ffs_vnops.c 10 Oct 2006 09:20:54 -0000 1.161
+++ sys/ufs/ffs/ffs_vnops.c 30 Oct 2006 17:07:56 -0000
@@ -74,6 +74,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -781,7 +782,8 @@
* tampering.
*/
if (resid > uio->uio_resid && ap->a_cred &&
- suser_cred(ap->a_cred, SUSER_ALLOWJAIL)) {
+ priv_check_cred(ap->a_cred, PRIV_VFS_CLEARSUGID,
+ SUSER_ALLOWJAIL)) {
ip->i_mode &= ~(ISUID | ISGID);
DIP_SET(ip, i_mode, ip->i_mode);
}
@@ -1107,7 +1109,7 @@
* tampering.
*/
if (resid > uio->uio_resid && ucred &&
- suser_cred(ucred, SUSER_ALLOWJAIL)) {
+ priv_check_cred(ucred, PRIV_VFS_CLEARSUGID, SUSER_ALLOWJAIL)) {
ip->i_mode &= ~(ISUID | ISGID);
dp->di_mode = ip->i_mode;
}
Index: sys/ufs/ufs/ufs_extattr.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ufs/ufs_extattr.c,v
retrieving revision 1.84
diff -u -r1.84 ufs_extattr.c
--- sys/ufs/ufs/ufs_extattr.c 1 Feb 2006 00:25:26 -0000 1.84
+++ sys/ufs/ufs/ufs_extattr.c 30 Oct 2006 17:07:56 -0000
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -699,7 +700,8 @@
* Processes with privilege, but in jail, are not allowed to
* configure extended attributes.
*/
- if ((error = suser(td))) {
+ error = priv_check(td, PRIV_UFS_EXTATTRCTL);
+ if (error) {
if (filename_vp != NULL)
VOP_UNLOCK(filename_vp, 0, td);
return (error);
Index: sys/ufs/ufs/ufs_quota.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ufs/ufs_quota.c,v
retrieving revision 1.84
diff -u -r1.84 ufs_quota.c
--- sys/ufs/ufs/ufs_quota.c 26 Sep 2006 04:12:49 -0000 1.84
+++ sys/ufs/ufs/ufs_quota.c 30 Oct 2006 17:07:56 -0000
@@ -46,6 +46,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -165,7 +166,8 @@
}
return (0);
}
- if ((flags & FORCE) == 0 && suser_cred(cred, 0)) {
+ if ((flags & FORCE) == 0 && priv_check_cred(cred,
+ PRIV_UFS_EXCEEDQUOTA, 0)) {
for (i = 0; i < MAXQUOTAS; i++) {
if ((dq = ip->i_dquot[i]) == NODQUOT)
continue;
@@ -288,7 +290,8 @@
}
return (0);
}
- if ((flags & FORCE) == 0 && suser_cred(cred, 0)) {
+ if ((flags & FORCE) == 0 && priv_check_cred(cred,
+ PRIV_UFS_EXCEEDQUOTA, 0)) {
for (i = 0; i < MAXQUOTAS; i++) {
if ((dq = ip->i_dquot[i]) == NODQUOT)
continue;
@@ -423,7 +426,11 @@
int error, flags;
struct nameidata nd;

- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ /*
+ * XXXRW: Can this be right? Jail is allowed to do this?
+ */
+ error = priv_check_cred(td->td_ucred, PRIV_UFS_QUOTAON,
+ SUSER_ALLOWJAIL);
if (error)
return (error);

@@ -517,7 +524,11 @@
struct inode *ip;
int error;

- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ /*
+ * XXXRW: This also seems wrong to allow in a jail?
+ */
+ error = priv_check_cred(td->td_ucred, PRIV_UFS_QUOTAOFF,
+ SUSER_ALLOWJAIL);
if (error)
return (error);

@@ -589,15 +600,18 @@
switch (type) {
case USRQUOTA:
if ((td->td_ucred->cr_uid != id) && !unprivileged_get_quota) {
- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(td->td_ucred,
+ PRIV_UFS_GETQUOTA, SUSER_ALLOWJAIL);
if (error)
return (error);
}
break;

case GRPQUOTA:
- if (!groupmember(id, td->td_ucred) && !unprivileged_get_quota) {
- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ if (!groupmember(id, td->td_ucred) &&
+ !unprivileged_get_quota) {
+ error = priv_check_cred(td->td_ucred,
+ PRIV_UFS_GETQUOTA, SUSER_ALLOWJAIL);
if (error)
return (error);
}
@@ -632,7 +646,8 @@
struct dqblk newlim;
int error;

- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(td->td_ucred, PRIV_UFS_SETQUOTA,
+ SUSER_ALLOWJAIL);
if (error)
return (error);

@@ -698,7 +713,8 @@
struct dqblk usage;
int error;

- error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(td->td_ucred, PRIV_UFS_SETUSE,
+ SUSER_ALLOWJAIL);
if (error)
return (error);

Index: sys/ufs/ufs/ufs_vnops.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.281
diff -u -r1.281 ufs_vnops.c
--- sys/ufs/ufs/ufs_vnops.c 22 Oct 2006 11:52:19 -0000 1.281
+++ sys/ufs/ufs/ufs_vnops.c 30 Oct 2006 17:07:56 -0000
@@ -53,6 +53,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -490,8 +491,11 @@
* processes if the security.jail.chflags_allowed sysctl is
* is non-zero; otherwise, they behave like unprivileged
* processes.
+ *
+ * XXXRW: Move implementation of jail_chflags_allowed to
+ * kern_jail.c.
*/
- if (!suser_cred(cred,
+ if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS,
jail_chflags_allowed ? SUSER_ALLOWJAIL : 0)) {
if (ip->i_flags
& (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) {
@@ -582,10 +586,19 @@
* super-user.
* If times is non-NULL, ... The caller must be the owner of
* the file or be the super-user.
+ *
+ * Possibly for historical reasons, try to use VADMIN in
+ * preference to VADMIN for a NULL timestamp. This means we
+ * will return EACCES in preference to EPERM if neither
+ * check succeeds.
*/
- if ((error = VOP_ACCESS(vp, VADMIN, cred, td)) &&
- ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
- (error = VOP_ACCESS(vp, VWRITE, cred, td))))
+ if (vap->va_vaflags & VA_UTIMES_NULL) {
+ error = VOP_ACCESS(vp, VADMIN, cred, td);
+ if (error)
+ error = VOP_ACCESS(vp, VWRITE, cred, td);
+ } else
+ error = VOP_ACCESS(vp, VADMIN, cred, td);
+ if (error)
return (error);
if (vap->va_atime.tv_sec != VNOVAL)
ip->i_flag |= IN_ACCESS;
@@ -651,11 +664,13 @@
* jail(8).
*/
if (vp->v_type != VDIR && (mode & S_ISTXT)) {
- if (suser_cred(cred, SUSER_ALLOWJAIL))
+ if (priv_check_cred(cred, PRIV_VFS_STICKYFILE,
+ SUSER_ALLOWJAIL))
return (EFTYPE);
}
if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) {
- error = suser_cred(cred, SUSER_ALLOWJAIL);
+ error = priv_check_cred(cred, PRIV_VFS_SETGID,
+ SUSER_ALLOWJAIL);
if (error)
return (error);
}
@@ -692,19 +707,19 @@
if (gid == (gid_t)VNOVAL)
gid = ip->i_gid;
/*
- * To modify the ownership of a file, must possess VADMIN
- * for that file.
+ * To modify the ownership of a file, must possess VADMIN for that
+ * file.
*/
if ((error = VOP_ACCESS(vp, VADMIN, cred, td)))
return (error);
/*
- * To change the owner of a file, or change the group of a file
- * to a group of which we are not a member, the caller must
- * have privilege.
+ * To change the owner of a file, or change the group of a file to a
+ * group of which we are not a member, the caller must have
+ * privilege.
*/
if ((uid != ip->i_uid ||
(gid != ip->i_gid && !groupmember(gid, cred))) &&
- (error = suser_cred(cred, SUSER_ALLOWJAIL)))
+ (error = priv_check_cred(cred, PRIV_VFS_CHOWN, SUSER_ALLOWJAIL)))
return (error);
ogid = ip->i_gid;
ouid = ip->i_uid;
@@ -775,7 +790,8 @@
panic("ufs_chown: lost quota");
#endif /* QUOTA */
ip->i_flag |= IN_CHANGE;
- if (suser_cred(cred, SUSER_ALLOWJAIL) && (ouid != uid || ogid != gid)) {
+ if (priv_check_cred(cred, PRIV_VFS_CLEARSUGID, SUSER_ALLOWJAIL) &&
+ (ouid != uid || ogid != gid)) {
ip->i_mode &= ~(ISUID | ISGID);
DIP_SET(ip, i_mode, ip->i_mode);
}
@@ -2348,7 +2364,8 @@
if (DOINGSOFTDEP(tvp))
softdep_change_linkcnt(ip);
if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
- suser_cred(cnp->cn_cred, SUSER_ALLOWJAIL)) {
+ priv_check_cred(cnp->cn_cred, PRIV_VFS_SETGID,
+ SUSER_ALLOWJAIL)) {
ip->i_mode &= ~ISGID;
DIP_SET(ip, i_mode, ip->i_mode);
}
Index: sys/vm/swap_pager.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/vm/swap_pager.c,v
retrieving revision 1.284
diff -u -r1.284 swap_pager.c
--- sys/vm/swap_pager.c 23 Oct 2006 05:27:31 -0000 1.284
+++ sys/vm/swap_pager.c 30 Oct 2006 17:07:56 -0000
@@ -77,6 +77,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1966,11 +1967,11 @@
struct nameidata nd;
int error;

- mtx_lock(&Giant);
- error = suser(td);
+ error = priv_check(td, PRIV_SWAPON);
if (error)
- goto done2;
+ return (error);

+ mtx_lock(&Giant);
while (swdev_syscall_active)
tsleep(&swdev_syscall_active, PUSER - 1, "swpon", 0);
swdev_syscall_active = 1;
@@ -2009,7 +2010,6 @@
done:
swdev_syscall_active = 0;
wakeup_one(&swdev_syscall_active);
-done2:
mtx_unlock(&Giant);
return (error);
}
@@ -2105,7 +2105,7 @@
struct swdevt *sp;
int error;

- error = suser(td);
+ error = priv_check(td, PRIV_SWAPOFF);
if (error)
return (error);

Index: sys/vm/vm_mmap.c
================================================== =================
RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/vm/vm_mmap.c,v
retrieving revision 1.207
diff -u -r1.207 vm_mmap.c
--- sys/vm/vm_mmap.c 22 Oct 2006 11:52:19 -0000 1.207
+++ sys/vm/vm_mmap.c 30 Oct 2006 17:07:56 -0000
@@ -54,6 +54,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -684,7 +685,7 @@
* "immortal."
*/
if (uap->behav == MADV_PROTECT) {
- error = suser(td);
+ error = priv_check(td, PRIV_VM_MADV_PROTECT);
if (error == 0) {
p = td->td_proc;
PROC_LOCK(p);
@@ -951,7 +952,7 @@
vm_size_t npages, size;
int error;

- error = suser(td);
+ error = priv_check(td, PRIV_VM_MLOCK);
if (error)
return (error);
addr = (vm_offset_t)uap->addr;
@@ -1016,7 +1017,7 @@
}
PROC_UNLOCK(td->td_proc);
#else
- error = suser(td);
+ error = priv_check(td, PRIV_VM_MLOCK);
if (error)
return (error);
#endif
@@ -1061,7 +1062,7 @@
int error;

map = &td->td_proc->p_vmspace->vm_map;
- error = suser(td);
+ error = priv_check(td, PRIV_VM_MUNLOCK);
if (error)
return (error);

@@ -1095,7 +1096,7 @@
vm_size_t size;
int error;

- error = suser(td);
+ error = priv_check(td, PRIV_VM_MUNLOCK);
if (error)
return (error);
addr = (vm_offset_t)uap->addr;
_______________________________________________
freebsd-arch@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "freebsd-arch-unsubscribe@freebsd.org"