Index: share/man/man9/Makefile =================================================================== RCS file: /home/ncvs/src/share/man/man9/Makefile,v retrieving revision 1.277 diff -u -r1.277 Makefile --- share/man/man9/Makefile 12 Jul 2006 19:12:16 -0000 1.277 +++ share/man/man9/Makefile 13 Sep 2006 09:02:40 -0000 @@ -185,6 +185,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 13 Sep 2006 09:02:29 -0000 @@ -0,0 +1,112 @@ +.\"- +.\" 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 +.Vt enum priv {}; +.Ft int +.Fn priv_check "struct thread *td" "enum priv priv" +.Ft int +.Fn priv_check_cred "struct ucred *cred" "enum priv 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. +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 ucred 9 +.Sh AUTHORS +The +.Xr priv 9 +API and implementation were created by Robert Watson under contract to +nCircle Network Security, Inc. Index: sys/amd64/amd64/io.c =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/src/sys/compat/linux/linux_misc.c,v retrieving revision 1.186 diff -u -r1.186 linux_misc.c --- sys/compat/linux/linux_misc.c 25 Aug 2006 11:02:42 -0000 1.186 +++ sys/compat/linux/linux_misc.c 13 Sep 2006 08:56:13 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -1011,7 +1012,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/linux/linux_uid16.c =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/src/sys/compat/svr4/svr4_fcntl.c,v retrieving revision 1.37 diff -u -r1.37 svr4_fcntl.c --- sys/compat/svr4/svr4_fcntl.c 28 Sep 2005 07:03:02 -0000 1.37 +++ sys/compat/svr4/svr4_fcntl.c 13 Sep 2006 08:56:13 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -279,7 +280,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: /home/ncvs/src/sys/compat/svr4/svr4_misc.c,v retrieving revision 1.89 diff -u -r1.89 svr4_misc.c --- sys/compat/svr4/svr4_misc.c 21 Jul 2006 20:28:56 -0000 1.89 +++ sys/compat/svr4/svr4_misc.c 13 Sep 2006 08:56:13 -0000 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -610,7 +611,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/NOTES =================================================================== RCS file: /home/ncvs/src/sys/conf/NOTES,v retrieving revision 1.1380 diff -u -r1.1380 NOTES --- sys/conf/NOTES 27 Aug 2006 12:57:37 -0000 1.1380 +++ sys/conf/NOTES 13 Sep 2006 08:56:13 -0000 @@ -1001,6 +1001,7 @@ options MAC_NONE options MAC_PARTITION options MAC_PORTACL +options MAC_PRIVS options MAC_SEEOTHERUIDS options MAC_STUB options MAC_TEST Index: sys/conf/files =================================================================== RCS file: /home/ncvs/src/sys/conf/files,v retrieving revision 1.1140 diff -u -r1.1140 files --- sys/conf/files 14 Aug 2006 21:09:37 -0000 1.1140 +++ sys/conf/files 13 Sep 2006 08:56:13 -0000 @@ -1335,6 +1335,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 @@ -1911,6 +1912,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 @@ -1926,6 +1928,7 @@ security/mac_none/mac_none.c optional mac_none security/mac_partition/mac_partition.c optional mac_partition security/mac_portacl/mac_portacl.c optional mac_portacl +security/mac_privs/mac_privs.c optional mac_privs security/mac_seeotheruids/mac_seeotheruids.c optional mac_seeotheruids security/mac_stub/mac_stub.c optional mac_stub security/mac_test/mac_test.c optional mac_test Index: sys/conf/options =================================================================== RCS file: /home/ncvs/src/sys/conf/options,v retrieving revision 1.557 diff -u -r1.557 options --- sys/conf/options 17 Aug 2006 00:37:03 -0000 1.557 +++ sys/conf/options 13 Sep 2006 08:56:13 -0000 @@ -110,6 +110,7 @@ MAC_NONE opt_dontuse.h MAC_PARTITION opt_dontuse.h MAC_PORTACL opt_dontuse.h +MAC_PRIVS opt_dontuse.h MAC_SEEOTHERUIDS opt_dontuse.h MAC_STATIC opt_mac.h MAC_STUB opt_dontuse.h Index: sys/contrib/altq/altq/altq_cbq.c =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/src/sys/dev/asr/asr.c,v retrieving revision 1.78 diff -u -r1.78 asr.c --- sys/dev/asr/asr.c 12 May 2006 05:04:40 -0000 1.78 +++ sys/dev/asr/asr.c 13 Sep 2006 08:56:13 -0000 @@ -117,6 +117,7 @@ #include #include #include +#include #include #include #include @@ -3114,7 +3115,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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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/cp/if_cp.c =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/src/sys/dev/hwpmc/hwpmc_mod.c,v retrieving revision 1.24 diff -u -r1.24 hwpmc_mod.c --- sys/dev/hwpmc/hwpmc_mod.c 17 Apr 2006 18:20:37 -0000 1.24 +++ sys/dev/hwpmc/hwpmc_mod.c 13 Sep 2006 08:56:13 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -252,8 +253,6 @@ * per-process measurements. This feature is turned off by default. */ -SYSCTL_DECL(_security_bsd); - static int pmc_unprivileged_syspmcs = 0; TUNABLE_INT("security.bsd.unprivileged_syspmcs", &pmc_unprivileged_syspmcs); SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_syspmcs, CTLFLAG_RW, @@ -2784,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; @@ -2920,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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/src/sys/dev/syscons/syscons.c,v retrieving revision 1.445 diff -u -r1.445 syscons.c --- sys/dev/syscons/syscons.c 26 May 2006 13:52:44 -0000 1.445 +++ sys/dev/syscons/syscons.c 13 Sep 2006 08:56:13 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -516,7 +517,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); @@ -1066,7 +1067,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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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. + * + * XXXRW: 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: /home/ncvs/src/sys/fs/devfs/devfs_vnops.c,v retrieving revision 1.133 diff -u -r1.133 devfs_vnops.c --- sys/fs/devfs/devfs_vnops.c 17 Jul 2006 09:07:01 -0000 1.133 +++ sys/fs/devfs/devfs_vnops.c 13 Sep 2006 08:56:13 -0000 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -1023,19 +1024,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; } @@ -1105,7 +1112,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: /home/ncvs/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 13 Sep 2006 08:56:13 -0000 @@ -501,6 +501,10 @@ if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); + /* + * XXXRW: Why not just rely on the VOP_ACCESS() check here + * instead of calling suser()? + */ if (cred->cr_uid != hp->h_uid && (error = suser_cred(cred, SUSER_ALLOWJAIL)) && ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || Index: sys/fs/msdosfs/msdosfs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/fs/msdosfs/msdosfs_vfsops.c,v retrieving revision 1.152 diff -u -r1.152 msdosfs_vfsops.c --- sys/fs/msdosfs/msdosfs_vfsops.c 3 Aug 2006 03:55:52 -0000 1.152 +++ sys/fs/msdosfs/msdosfs_vfsops.c 13 Sep 2006 08:56:13 -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: /home/ncvs/src/sys/fs/msdosfs/msdosfs_vnops.c,v retrieving revision 1.163 diff -u -r1.163 msdosfs_vnops.c --- sys/fs/msdosfs/msdosfs_vnops.c 1 Feb 2006 00:25:25 -0000 1.163 +++ sys/fs/msdosfs/msdosfs_vnops.c 13 Sep 2006 08:56:13 -0000 @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -402,9 +403,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 @@ -417,9 +421,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; @@ -442,10 +448,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; } @@ -475,6 +484,10 @@ if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); + /* + * XXXRW: Isn't VOP_ACCESS() enough here? Why is suser() + * required? + */ if (cred->cr_uid != pmp->pm_uid && (error = suser_cred(cred, SUSER_ALLOWJAIL)) && ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || @@ -504,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: /home/ncvs/src/sys/fs/procfs/procfs_ioctl.c,v retrieving revision 1.12 diff -u -r1.12 procfs_ioctl.c --- sys/fs/procfs/procfs_ioctl.c 30 Jun 2005 07:49:21 -0000 1.12 +++ sys/fs/procfs/procfs_ioctl.c 13 Sep 2006 08:56:13 -0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -86,8 +87,19 @@ #endif case PIOCSFL: flags = *(uintptr_t *)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: /home/ncvs/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 13 Sep 2006 08:56:13 -0000 @@ -352,6 +352,9 @@ if (vap->va_atime.tv_sec != VNOVAL) atime = &vap->va_atime; if (mtime != atime) { + /* + * XXXRW: Isn't VOP_ACCESS() here sufficient? Why suser()? + */ 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 || Index: sys/fs/udf/udf_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/fs/udf/udf_vfsops.c,v retrieving revision 1.43 diff -u -r1.43 udf_vfsops.c --- sys/fs/udf/udf_vfsops.c 25 Jul 2006 14:15:50 -0000 1.43 +++ sys/fs/udf/udf_vfsops.c 13 Sep 2006 08:56:13 -0000 @@ -84,6 +84,7 @@ #include #include #include +#include #include #include #include @@ -236,7 +237,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: /home/ncvs/src/sys/fs/umapfs/umap_vfsops.c,v retrieving revision 1.64 diff -u -r1.64 umap_vfsops.c --- sys/fs/umapfs/umap_vfsops.c 31 Oct 2005 15:41:21 -0000 1.64 +++ sys/fs/umapfs/umap_vfsops.c 13 Sep 2006 08:56:13 -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: /home/ncvs/src/sys/gnu/fs/ext2fs/ext2_vfsops.c,v retrieving revision 1.157 diff -u -r1.157 ext2_vfsops.c --- sys/gnu/fs/ext2fs/ext2_vfsops.c 26 May 2006 00:32:20 -0000 1.157 +++ sys/gnu/fs/ext2fs/ext2_vfsops.c 13 Sep 2006 08:56:13 -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); @@ -257,15 +259,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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -0000 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include Index: sys/gnu/fs/reiserfs/reiserfs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/gnu/fs/reiserfs/reiserfs_vfsops.c,v retrieving revision 1.5 diff -u -r1.5 reiserfs_vfsops.c --- sys/gnu/fs/reiserfs/reiserfs_vfsops.c 26 May 2006 11:58:30 -0000 1.5 +++ sys/gnu/fs/reiserfs/reiserfs_vfsops.c 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/src/sys/i386/i386/sys_machdep.c,v retrieving revision 1.105 diff -u -r1.105 sys_machdep.c --- sys/i386/i386/sys_machdep.c 9 Sep 2006 10:20:31 -0000 1.105 +++ sys/i386/i386/sys_machdep.c 13 Sep 2006 08:56:13 -0000 @@ -41,6 +41,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: /home/ncvs/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 13 Sep 2006 08:56:13 -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: /home/ncvs/src/sys/i386/ibcs2/ibcs2_misc.c,v retrieving revision 1.64 diff -u -r1.64 ibcs2_misc.c --- sys/i386/ibcs2/ibcs2_misc.c 11 Jul 2006 20:52:08 -0000 1.64 +++ sys/i386/ibcs2/ibcs2_misc.c 13 Sep 2006 08:56:14 -0000 @@ -69,6 +69,7 @@ #include #include /* Must come after sys/malloc.h */ #include +#include #include #include #include @@ -1007,14 +1008,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; } @@ -1042,9 +1051,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: @@ -1054,11 +1060,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/i386/linux/linux_machdep.c,v retrieving revision 1.55 diff -u -r1.55 linux_machdep.c --- sys/i386/linux/linux_machdep.c 27 Aug 2006 18:51:32 -0000 1.55 +++ sys/i386/linux/linux_machdep.c 13 Sep 2006 08:56:14 -0000 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -756,7 +757,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/isofs/cd9660/cd9660_vfsops.c,v retrieving revision 1.145 diff -u -r1.145 cd9660_vfsops.c --- sys/isofs/cd9660/cd9660_vfsops.c 26 May 2006 00:32:20 -0000 1.145 +++ sys/isofs/cd9660/cd9660_vfsops.c 13 Sep 2006 08:56:14 -0000 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -172,7 +173,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: /home/ncvs/src/sys/kern/kern_acct.c,v retrieving revision 1.82 diff -u -r1.82 kern_acct.c --- sys/kern/kern_acct.c 5 Jun 2006 13:02:34 -0000 1.82 +++ sys/kern/kern_acct.c 13 Sep 2006 08:56:14 -0000 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,7 @@ * acct_sx protects against changes to the active vnode and credentials * while accounting records are being committed to disk. */ +static int acct_configured; static int acct_suspended; static struct vnode *acct_vp; static struct ucred *acct_cred; @@ -146,6 +148,9 @@ &acctchkfreq, 0, sysctl_acct_chkfreq, "I", "frequency for checking the free space"); +SYSCTL_INT(_kern, OID_AUTO, acct_configured, CTLFLAG_RD, &acct_configured, 0, + "Accounting configured or not"); + SYSCTL_INT(_kern, OID_AUTO, acct_suspended, CTLFLAG_RD, &acct_suspended, 0, "Accounting suspended or not"); @@ -161,8 +166,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); @@ -252,6 +256,7 @@ (void) vn_close(acct_vp, acct_flags, acct_cred, td); VFS_UNLOCK_GIANT(vfslocked); crfree(acct_cred); + acct_configured = 0; acct_vp = NULL; acct_cred = NULL; acct_flags = 0; @@ -260,6 +265,7 @@ return (error); } } + acct_configured = 1; sx_xunlock(&acct_sx); log(LOG_NOTICE, "Accounting enabled\n"); return (error); @@ -277,6 +283,7 @@ sx_assert(&acct_sx, SX_XLOCKED); error = vn_close(acct_vp, acct_flags, acct_cred, td); crfree(acct_cred); + acct_configured = 0; acct_vp = NULL; acct_cred = NULL; acct_flags = 0; Index: sys/kern/kern_descrip.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.297 diff -u -r1.297 kern_descrip.c --- sys/kern/kern_descrip.c 21 Jul 2006 20:24:00 -0000 1.297 +++ sys/kern/kern_descrip.c 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/kern/kern_environment.c,v retrieving revision 1.44 diff -u -r1.44 kern_environment.c --- sys/kern/kern_environment.c 9 Jul 2006 21:42:58 -0000 1.44 +++ sys/kern/kern_environment.c 13 Sep 2006 08:56:14 -0000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -124,11 +125,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: /home/ncvs/src/sys/kern/kern_exec.c,v retrieving revision 1.295 diff -u -r1.295 kern_exec.c --- sys/kern/kern_exec.c 1 Sep 2006 11:45:39 -0000 1.295 +++ sys/kern/kern_exec.c 13 Sep 2006 08:56:14 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -571,8 +572,14 @@ * we do not regain any tracing during a possible block. */ setsugid(p); + + /* + * XXXRW: Make sure that this priv is the right one. + */ #ifdef KTRACE - if (p->p_tracevp != NULL && suser_cred(oldcred, SUSER_ALLOWJAIL)) { + if (p->p_tracevp != NULL && + priv_check_cred(oldcred, PRIV_DEBUG_SUGID, + SUSER_ALLOWJAIL)) { mtx_lock(&ktrace_mtx); p->p_traceflag = 0; tracevp = p->p_tracevp; Index: sys/kern/kern_fork.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v retrieving revision 1.261 diff -u -r1.261 kern_fork.c --- sys/kern/kern_fork.c 15 Aug 2006 12:10:57 -0000 1.261 +++ sys/kern/kern_fork.c 13 Sep 2006 08:56:14 -0000 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -308,7 +309,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; @@ -317,8 +318,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: /home/ncvs/src/sys/kern/kern_jail.c,v retrieving revision 1.51 diff -u -r1.51 kern_jail.c --- sys/kern/kern_jail.c 28 Sep 2005 00:30:56 -0000 1.51 +++ sys/kern/kern_jail.c 13 Sep 2006 08:56:14 -0000 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,6 @@ MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); -SYSCTL_DECL(_security); SYSCTL_NODE(_security, OID_AUTO, jail, CTLFLAG_RW, 0, "Jail rules"); @@ -205,7 +205,7 @@ * a process root from one prison, but attached to the jail * of another. */ - error = suser(td); + error = priv_check(td, PRIV_JAIL_ATTACH); if (error) return (error); @@ -523,6 +523,210 @@ } } +/* + * Check with permission for a specific privilege is granted within jail. We + * have a specific list of accepted privileges; the rest are denied. + */ +int +prison_priv_check(struct ucred *cred, enum priv priv) +{ + + if (!(jailed(cred))) + return (0); + + switch (priv) { + /* case PRIV_ROOT: */ + /* case PRIV_ACCT: */ + /* case PRIV_MAXFILES: */ + /* case PRIV_MAXPROC: */ + case PRIV_KTRACE: + /* case PRIV_SETDUMPER: */ + /* case PRIV_NFSD: */ + /* case PRIV_REBOOT: */ + /* case PRIV_SWAPON: */ + /* case PRIV_SWAPOFF: */ + /* case PRIV_MSGBUF: */ + /* case PRIV_WITNESS: */ + /* case PRIV_IO: */ + /* case PRIV_KEYBOARD: */ + /* case PRIV_DRIVER: */ + /* case PRIV_ADJTIME: */ + /* case PRIV_NTP_ADJTIME: */ + /* case PRIV_CLOCK_SETTIME: */ + /* case PRIV_SETTIMEOFDAY: */ + /* case PRIV_SETHOSTID: */ + /* case PRIV_SETDOMAINNAME: */ + /* case PRIV_AUDIT_CONTROL: */ + /* case PRIV_AUDIT_FAILSTOP: */ + case PRIV_AUDIT_GETAUDIT: + case PRIV_AUDIT_SETAUDIT: + case PRIV_AUDIT_SUBMIT: + 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: + case PRIV_SEEOTHERGIDS: + case PRIV_SEEOTHERUIDS: + case PRIV_DEBUG_DIFFCRED: + case PRIV_DEBUG_SUGID: + case PRIV_DEBUG_UNPRIV: + /* case PRIV_FIRMWARE_LOAD: */ + /* case PRIV_JAIL_ATTACH: */ + /* case PRIV_KENV_SET: */ + /* case PRIV_KENV_UNSET: */ + /* case PRIV_KLD_LOAD: */ + /* case PRIV_KLD_UNLOAD: */ + /* case PRIV_MAC_PARTITION: */ + case PRIV_PROC_LIMIT: + case PRIV_PROC_SETLOGIN: + case PRIV_PROC_SETRLIMIT: + + /* XXXRW: Not yet. */ + /* case PRIV_IPC_READ: */ + /* case PRIV_IPC_WRITE: */ + /* case PRIV_IPC_EXEC: */ + /* case PRIV_IPC_ADMIN: */ + /* case PRIV_IPC_MSGSIZE: */ + /* case PRIV_MQ_ADMIN: */ + /* case PRIV_PMC_MANAGE: */ + /* case PRIV_PMC_SYSTEM: */ + case PRIV_SCHED_DIFFCRED: + /* case PRIV_SCHED_SETPRIORITY: */ + /* case PRIV_SCHED_RTPRIO: */ + /* case PRIV_SCHED_SETPOLICY: */ + /* case PRIV_SCHED_SET: */ + /* case PRIV_SCHED_SETPARAM: */ + /* case PRIV_SEM_WRITE: */ + case PRIV_SIGNAL_DIFFCRED: + case PRIV_SIGNAL_SUGID: + /* case PRIV_SYSCTL_DEBUG: */ + /* case PRIV_SYSCTL_WRITE: */ + case PRIV_SYSCTL_WRITEJAIL: + /* case PRIV_TTY_CONSOLE: */ + /* case PRIV_TTY_DRAINWAIT: */ + /* case PRIV_TTY_DTRWAIT: */ + /* case PRIV_TTY_EXCLUSIVE: */ + /* case PRIV_TTY_PRISON: */ + /* case PRIV_TTY_STI: */ + /* case PRIV_TTY_SETA: */ + /* case PRIV_UFS_EXTATTRCTL: */ + 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. */ + /* case PRIV_UFS_EXCEEDQUOTA: */ + 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_EXTATTR_SYSTEM: */ + case PRIV_VFS_FCHROOT: + /* case PRIV_VFS_FHOPEN: */ + /* case PRIV_VFS_FHSTAT: */ + /* case PRIV_VFS_FHSTATFS: */ + /* case PRIV_VFS_GENERATION: */ + /* case PRIV_VFS_GETFH: */ + case PRIV_VFS_LINK: + /* case PRIV_VFS_MKNOD_DEV: */ + /* case PRIV_VFS_MOUNT: */ + /* case PRIV_VFS_MOUNT_OWNER: */ + /* case PRIV_VFS_MOUNT_EXPORTED: */ + /* case PRIV_VFS_MOUNT_PERM: */ + /* case PRIV_VFS_MOUNT_SUIDDIR: */ + case PRIV_VFS_SETGID: + case PRIV_VFS_STICKYFILE: + return (0); + + case PRIV_VFS_SYSFLAGS: + if (jail_chflags_allowed) + return (0); + else + return (EPERM); + + /* case PRIV_VFS_UNMOUNT: */ + /* case PRIV_VM_MADV_PROTECT: */ + /* case PRIV_VM_MLOCK: */ + /* case PRIV_VM_MUNLOCK: */ + /* case PRIV_DEVFS_RULE: */ + /* case PRIV_DEVFS_SYMLINK: */ + /* case PRIV_RANDOM_RESEED: */ + /* case PRIV_NET_BRIDGE: */ + /* case PRIV_NET_GRE: */ + /* case PRIV_NET_PPP: */ + /* case PRIV_NET_SLIP: */ + /* case PRIV_NET_BPF: */ + /* case PRIV_NET_RAW: */ + /* case PRIV_NET_ROUTE: */ + /* case PRIV_NET_TAP: */ + /* case PRIV_NET_SETIFMTU: */ + /* case PRIV_NET_SETIFFLAGS: */ + /* case PRIV_NET_SETIFCAP: */ + /* case PRIV_NET_SETIFNAME: */ + /* case PRIV_NET_SETIFMETRIC: */ + /* case PRIV_NET_SETIFPHYS: */ + /* case PRIV_NET_SETIFMAC: */ + /* case PRIV_NET_ADDMULTI: */ + /* case PRIV_NET_DELMULTI: */ + /* case PRIV_NET_HWIOCTL: */ + /* case PRIV_NET_SETLLADDR: */ + /* case PRIV_NET_ADDIFGROUP: */ + /* case PRIV_NET_DELIFGROUP: */ + /* case PRIV_NET_IFCREATE: */ + /* case PRIV_NET_IFDESTROY: */ + /* case PRIV_NET80211_GETKEY: */ + /* case PRIV_NET80211_MANAGE: */ + /* case PRIV_NETATALK_RESERVEDPORT: */ + /* case PRIV_NETATM_CFG: */ + /* case PRIV_NETATM_ADD: */ + /* case PRIV_NETATM_DEL: */ + /* case PRIV_NETATM_SET: */ + /* case PRIV_NETGRAPH_CONTROL: */ + /* case PRIV_NETGRAPH_TTY: */ + case PRIV_NETINET_RESERVEDPORT: + return (0); + /* case PRIV_NETINET_IPFW: */ + /* case PRIV_NETINET_DIVERT: */ + /* case PRIV_NETINET_PF: */ + /* case PRIV_NETINET_DUMMYNET: */ + /* case PRIV_NETINET_CARP: */ + /* case PRIV_NETINET_MROUTE: */ + case PRIV_NETINET_RAW: + if (jail_allow_raw_sockets) + return (0); + else + return (EPERM); + case PRIV_NETINET_GETCRED: + /* case PRIV_NETINET_ADDRCTRL6: */ + /* case PRIV_NETINET_ND6: */ + /* case PRIV_NETINET_SCOPE6: */ + /* case PRIV_NETINET_ALIFETIME6: */ + /* case PRIV_NETINET_IPSEC: */ + /* case PRIV_NETIPX_RESERVEDPORT: */ + /* case PRIV_NETIPX_RAW: */ + /* case PRIV_NETNCP: */ + /* case PRIV_NETSMB: */ + /* case PRIV_VM86_INTCALL: */ + + default: + /* + * In all remaining cases, deny the privilege request. + */ + return (EPERM); + } +} + static int sysctl_jail_list(SYSCTL_HANDLER_ARGS) { Index: sys/kern/kern_ktrace.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_ktrace.c,v retrieving revision 1.110 diff -u -r1.110 kern_ktrace.c --- sys/kern/kern_ktrace.c 31 Jul 2006 15:31:43 -0000 1.110 +++ sys/kern/kern_ktrace.c 13 Sep 2006 08:56:14 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -806,7 +807,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 */ @@ -1012,7 +1014,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: /home/ncvs/src/sys/kern/kern_linker.c,v retrieving revision 1.142 diff -u -r1.142 kern_linker.c --- sys/kern/kern_linker.c 10 Jul 2006 19:28:57 -0000 1.142 +++ sys/kern/kern_linker.c 13 Sep 2006 08:56:14 -0000 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -853,7 +854,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); /* @@ -920,7 +921,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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 13 Sep 2006 09:01:42 -0000 @@ -0,0 +1,153 @@ +/*- + * 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. + * + * XXXRW: Update this comment as needed. + */ +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, enum priv 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); + 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")); + 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 uility. + */ + 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, enum priv 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 + * list of global privileges is not yet complete. + */ +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: /home/ncvs/src/sys/kern/kern_prot.c,v retrieving revision 1.203 diff -u -r1.203 kern_prot.c --- sys/kern/kern_prot.c 6 Jul 2006 21:32:20 -0000 1.203 +++ sys/kern/kern_prot.c 13 Sep 2006 08:56:14 -0000 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +71,6 @@ static MALLOC_DEFINE(M_CRED, "cred", "credentials"); -SYSCTL_DECL(_security); SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy"); @@ -549,7 +549,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; /* @@ -565,7 +566,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 { /* @@ -641,7 +643,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; /* @@ -713,7 +716,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); @@ -726,7 +730,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 { /* @@ -798,7 +803,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); @@ -861,7 +867,8 @@ goto fail; #endif - error = suser_cred(oldcred, SUSER_ALLOWJAIL); + error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, + SUSER_ALLOWJAIL); if (error) goto fail; @@ -933,7 +940,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); @@ -1001,7 +1009,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); @@ -1081,7 +1090,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); @@ -1162,7 +1172,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); @@ -1326,65 +1337,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 @@ -1437,7 +1397,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); @@ -1476,7 +1437,8 @@ break; } if (!match) { - if (suser_cred(u1, SUSER_ALLOWJAIL) != 0) + if (priv_check_cred(u1, PRIV_SEEOTHERGIDS, + SUSER_ALLOWJAIL) != 0) return (ESRCH); } } @@ -1593,7 +1555,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); } @@ -1608,7 +1571,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); } @@ -1616,7 +1580,6 @@ return (0); } - /*- * Determine whether td may deliver the specified signal to p. * Returns: 0 for permitted, an errno value otherwise @@ -1685,19 +1648,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); } /* @@ -1732,7 +1690,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); } @@ -1780,11 +1739,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); } @@ -1798,6 +1764,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(). @@ -2059,7 +2026,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: /home/ncvs/src/sys/kern/kern_resource.c,v retrieving revision 1.159 diff -u -r1.159 kern_resource.c --- sys/kern/kern_resource.c 4 Aug 2006 07:56:35 -0000 1.159 +++ sys/kern/kern_resource.c 13 Sep 2006 08:56:14 -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); @@ -352,7 +353,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; @@ -573,7 +574,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: /home/ncvs/src/sys/kern/kern_shutdown.c,v retrieving revision 1.178 diff -u -r1.178 kern_shutdown.c --- sys/kern/kern_shutdown.c 10 Apr 2006 10:03:40 -0000 1.178 +++ sys/kern/kern_shutdown.c 13 Sep 2006 08:56:14 -0000 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -163,7 +164,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: /home/ncvs/src/sys/kern/kern_sysctl.c,v retrieving revision 1.170 diff -u -r1.170 kern_sysctl.c --- sys/kern/kern_sysctl.c 16 Jun 2006 07:36:18 -0000 1.170 +++ sys/kern/kern_sysctl.c 13 Sep 2006 08:56:14 -0000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -510,7 +511,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); @@ -1251,13 +1252,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: /home/ncvs/src/sys/kern/kern_thr.c,v retrieving revision 1.51 diff -u -r1.51 kern_thr.c --- sys/kern/kern_thr.c 25 Aug 2006 10:05:30 -0000 1.51 +++ sys/kern/kern_thr.c 13 Sep 2006 08:56:14 -0000 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -137,7 +138,7 @@ case SCHED_FIFO: case SCHED_RR: /* Only root can set scheduler policy */ - if (suser(td) != 0) + if (priv_check(td, PRIV_SCHED_SETPOLICY) != 0) return (EPERM); if (sched->param.sched_priority < RTP_PRIO_MIN || sched->param.sched_priority > RTP_PRIO_MAX) @@ -453,7 +454,7 @@ if (ret != 0) return (ret); - ret = suser(td); + ret = priv_check(td, PRIV_SCHED_SET); if (ret != 0) return (ret); @@ -556,7 +557,7 @@ ret = copyin(uap->param, ¶m, sizeof(struct sched_param)); if (ret != 0) return (ret); - ret = suser(td); + ret = priv_check(td, PRIV_SCHED_SETPARAM); if (ret != 0) return (ret); p = td->td_proc; Index: sys/kern/kern_time.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_time.c,v retrieving revision 1.131 diff -u -r1.131 kern_time.c --- sys/kern/kern_time.c 15 Aug 2006 12:10:57 -0000 1.131 +++ sys/kern/kern_time.c 13 Sep 2006 08:56:14 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -287,7 +288,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); @@ -505,7 +506,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_xxx.c =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/kern/subr_prf.c,v retrieving revision 1.124 diff -u -r1.124 subr_prf.c --- sys/kern/subr_prf.c 12 Jul 2006 21:22:44 -0000 1.124 +++ sys/kern/subr_prf.c 13 Sep 2006 08:56:14 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -856,8 +857,6 @@ oldp = msgbufp; } -SYSCTL_DECL(_security_bsd); - static int unprivileged_read_msgbuf = 1; SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_read_msgbuf, CTLFLAG_RW, &unprivileged_read_msgbuf, 0, @@ -872,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: /home/ncvs/src/sys/kern/subr_witness.c,v retrieving revision 1.217 diff -u -r1.217 subr_witness.c --- sys/kern/subr_witness.c 26 Aug 2006 11:21:25 -0000 1.217 +++ sys/kern/subr_witness.c 13 Sep 2006 08:56:14 -0000 @@ -95,6 +95,7 @@ #include #include #include +#include #include #include #include @@ -532,7 +533,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_msg.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sysv_msg.c,v retrieving revision 1.61 diff -u -r1.61 sysv_msg.c --- sys/kern/sysv_msg.c 10 Jun 2006 14:34:07 -0000 1.61 +++ sys/kern/sysv_msg.c 13 Sep 2006 08:56:14 -0000 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -516,7 +517,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: /home/ncvs/src/sys/kern/tty.c,v retrieving revision 1.258 diff -u -r1.258 tty.c --- sys/kern/tty.c 10 Sep 2006 16:51:56 -0000 1.258 +++ sys/kern/tty.c 13 Sep 2006 08:56:14 -0000 @@ -86,6 +86,7 @@ #if defined(COMPAT_43TTY) #include #endif +#include #include #define TTYDEFCHARS #include @@ -1012,7 +1013,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; @@ -1161,9 +1162,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); @@ -1236,7 +1237,7 @@ } break; case TIOCSDRAINWAIT: - error = suser(td); + error = priv_check(td, PRIV_TTY_DRAINWAIT); if (error) return (error); tp->t_timeout = *(int *)data * hz; @@ -3094,7 +3095,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 { /* @@ -3320,7 +3322,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/kern/tty_pts.c,v retrieving revision 1.8 diff -u -r1.8 tty_pts.c --- sys/kern/tty_pts.c 28 Apr 2006 21:39:57 -0000 1.8 +++ sys/kern/tty_pts.c 13 Sep 2006 08:56:14 -0000 @@ -56,6 +56,7 @@ #if defined(COMPAT_43TTY) #include #endif +#include #include #include #include @@ -263,9 +264,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: /home/ncvs/src/sys/kern/tty_pty.c,v retrieving revision 1.145 diff -u -r1.145 tty_pty.c --- sys/kern/tty_pty.c 2 Feb 2006 20:35:45 -0000 1.145 +++ sys/kern/tty_pty.c 13 Sep 2006 08:56:14 -0000 @@ -46,6 +46,7 @@ #if defined(COMPAT_43TTY) #include #endif +#include #include #include #include @@ -198,9 +199,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. */ (void)ttyld_modem(tp, 1); Index: sys/kern/uipc_mqueue.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_mqueue.c,v retrieving revision 1.15 diff -u -r1.15 uipc_mqueue.c --- sys/kern/uipc_mqueue.c 17 Apr 2006 18:20:37 -0000 1.15 +++ sys/kern/uipc_mqueue.c 13 Sep 2006 08:56:14 -0000 @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -953,8 +954,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; @@ -1205,10 +1210,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; @@ -1217,7 +1228,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: /home/ncvs/src/sys/kern/uipc_sem.c,v retrieving revision 1.24 diff -u -r1.24 uipc_sem.c --- sys/kern/uipc_sem.c 16 Aug 2006 08:25:40 -0000 1.24 +++ sys/kern/uipc_sem.c 13 Sep 2006 08:56:14 -0000 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -418,15 +419,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: /home/ncvs/src/sys/kern/vfs_mount.c,v retrieving revision 1.231 diff -u -r1.231 vfs_mount.c --- sys/kern/vfs_mount.c 26 Aug 2006 16:28:19 -0000 1.231 +++ sys/kern/vfs_mount.c 13 Sep 2006 08:56:14 -0000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -804,20 +805,29 @@ 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. + * + * XXXRW: Which privileges to map this to? Wouldn't it be better + * to see if they weren't already set and only then check privilege? */ if (suser(td) != 0) fsflags |= MNT_NOSUID | MNT_USER; @@ -898,7 +908,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); } @@ -1055,7 +1067,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: /home/ncvs/src/sys/kern/vfs_subr.c,v retrieving revision 1.682 diff -u -r1.682 vfs_subr.c --- sys/kern/vfs_subr.c 4 Sep 2006 22:15:44 -0000 1.682 +++ sys/kern/vfs_subr.c 13 Sep 2006 08:56:14 -0000 @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -410,7 +411,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); @@ -3169,9 +3170,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 @@ -3225,59 +3224,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); } @@ -3298,16 +3284,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: /home/ncvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.420 diff -u -r1.420 vfs_syscalls.c --- sys/kern/vfs_syscalls.c 2 Aug 2006 15:27:48 -0000 1.420 +++ sys/kern/vfs_syscalls.c 13 Sep 2006 08:56:14 -0000 @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -266,7 +267,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); @@ -351,7 +352,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); @@ -462,7 +463,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); @@ -836,7 +837,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, @@ -890,8 +892,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) @@ -1180,9 +1182,10 @@ switch (mode & S_IFMT) { case S_IFCHR: case S_IFBLK: - error = suser(td); + error = priv_check(td, PRIV_VFS_MKNOD_DEV); break; default: + /* XXXRW: Should do a full enumeration here. */ error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); break; } @@ -1367,8 +1370,6 @@ return (error); } -SYSCTL_DECL(_security_bsd); - static int hardlink_check_uid = 0; SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW, &hardlink_check_uid, 0, @@ -1386,9 +1387,6 @@ struct vattr va; int error; - if (suser_cred(cred, SUSER_ALLOWJAIL) == 0) - return (0); - if (!hardlink_check_uid && !hardlink_check_gid) return (0); @@ -1396,14 +1394,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); @@ -2357,7 +2359,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); } @@ -3889,7 +3892,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; } @@ -3955,7 +3959,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, @@ -3994,7 +3998,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, @@ -4017,10 +4021,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 @@ -4053,7 +4057,7 @@ int vfslocked; int indx; - error = suser(td); + error = priv_check(td, PRIV_VFS_FHOPEN); if (error) return (error); fmode = FFLAGS(uap->flags); @@ -4237,7 +4241,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)); @@ -4302,7 +4306,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: /home/ncvs/src/sys/kern/vfs_vnops.c,v retrieving revision 1.244 diff -u -r1.244 vfs_vnops.c --- sys/kern/vfs_vnops.c 24 Jun 2006 22:55:43 -0000 1.244 +++ sys/kern/vfs_vnops.c 13 Sep 2006 08:56:14 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -708,7 +709,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/modules/Makefile =================================================================== RCS file: /home/ncvs/src/sys/modules/Makefile,v retrieving revision 1.510 diff -u -r1.510 Makefile --- sys/modules/Makefile 9 Sep 2006 16:58:22 -0000 1.510 +++ sys/modules/Makefile 13 Sep 2006 08:56:14 -0000 @@ -148,6 +148,7 @@ mac_none \ mac_partition \ mac_portacl \ + mac_privs \ mac_seeotheruids \ mac_stub \ mac_test \ Index: sys/net/bpf.c =================================================================== RCS file: /home/ncvs/src/sys/net/bpf.c,v retrieving revision 1.172 diff -u -r1.172 bpf.c --- sys/net/bpf.c 9 Aug 2006 16:30:26 -0000 1.172 +++ sys/net/bpf.c 13 Sep 2006 08:56:14 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -1723,7 +1724,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: /home/ncvs/src/sys/net/if.c,v retrieving revision 1.262 diff -u -r1.262 if.c --- sys/net/if.c 6 Sep 2006 17:12:10 -0000 1.262 +++ sys/net/if.c 13 Sep 2006 08:56:14 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -1488,7 +1489,7 @@ break; case SIOCSIFFLAGS: - error = suser(td); + error = priv_check(td, PRIV_NET_SETIFFLAGS); if (error) return (error); /* @@ -1531,7 +1532,7 @@ break; case SIOCSIFCAP: - error = suser(td); + error = priv_check(td, PRIV_NET_SETIFCAP); if (error) return (error); if (ifp->if_ioctl == NULL) @@ -1552,8 +1553,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) @@ -1599,7 +1600,7 @@ break; case SIOCSIFMETRIC: - error = suser(td); + error = priv_check(td, PRIV_NET_SETIFMETRIC); if (error) return (error); ifp->if_metric = ifr->ifr_metric; @@ -1607,7 +1608,7 @@ break; case SIOCSIFPHYS: - error = suser(td); + error = priv_check(td, PRIV_NET_SETIFPHYS); if (error) return (error); if (ifp->if_ioctl == NULL) @@ -1623,7 +1624,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) @@ -1650,7 +1651,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); @@ -1680,7 +1684,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) @@ -1709,7 +1713,7 @@ break; case SIOCSIFLLADDR: - error = suser(td); + error = priv_check(td, PRIV_NET_SETLLADDR); if (error) return (error); error = if_setlladdr(ifp, @@ -1720,7 +1724,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))) @@ -1737,7 +1741,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))) @@ -1776,12 +1780,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: /home/ncvs/src/sys/net/if_bridge.c,v retrieving revision 1.79 diff -u -r1.79 if_bridge.c --- sys/net/if_bridge.c 25 Aug 2006 20:11:56 -0000 1.79 +++ sys/net/if_bridge.c 13 Sep 2006 08:56:14 -0000 @@ -101,6 +101,7 @@ #include #include #include +#include #include #include #include @@ -675,7 +676,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: /home/ncvs/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 13 Sep 2006 08:56:14 -0000 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -452,6 +453,10 @@ case SIOCSIFDSTADDR: break; case SIOCSIFFLAGS: + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ if ((error = suser(curthread)) != 0) break; if ((ifr->ifr_flags & IFF_LINK0) != 0) @@ -464,6 +469,10 @@ sc->wccp_ver = WCCP_V1; goto recompute; case SIOCSIFMTU: + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ if ((error = suser(curthread)) != 0) break; if (ifr->ifr_mtu < 576) { @@ -477,6 +486,10 @@ break; case SIOCADDMULTI: case SIOCDELMULTI: + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ if ((error = suser(curthread)) != 0) break; if (ifr == 0) { @@ -498,6 +511,10 @@ } break; case GRESPROTO: + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ if ((error = suser(curthread)) != 0) break; sc->g_proto = ifr->ifr_flags; @@ -518,8 +535,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,6 +602,10 @@ ifr->ifr_addr = *sa; break; case SIOCSIFPHYADDR: + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ if ((error = suser(curthread)) != 0) break; if (aifr->ifra_addr.sin_family != AF_INET || @@ -600,6 +622,10 @@ sc->g_dst = aifr->ifra_dstaddr.sin_addr; goto recompute; case SIOCSLIFPHYADDR: + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ if ((error = suser(curthread)) != 0) break; if (lifr->addr.ss_family != AF_INET || @@ -617,6 +643,10 @@ (satosin(&lifr->dstaddr))->sin_addr; goto recompute; case SIOCDIFPHYADDR: + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ if ((error = suser(curthread)) != 0) break; sc->g_src.s_addr = INADDR_ANY; Index: sys/net/if_ppp.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_ppp.c,v retrieving revision 1.114 diff -u -r1.114 if_ppp.c --- sys/net/if_ppp.c 9 Jul 2006 06:04:00 -0000 1.114 +++ sys/net/if_ppp.c 13 Sep 2006 08:56:14 -0000 @@ -87,6 +87,7 @@ #include #include +#include #include #include #include @@ -450,7 +451,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(); @@ -464,8 +466,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; @@ -477,7 +480,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(); @@ -488,14 +492,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; @@ -568,7 +574,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(); @@ -694,6 +701,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/net/if_tap.c,v retrieving revision 1.62 diff -u -r1.62 if_tap.c --- sys/net/if_tap.c 15 Jul 2006 02:13:05 -0000 1.62 +++ sys/net/if_tap.c 13 Sep 2006 08:56:14 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -372,10 +373,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: /home/ncvs/src/sys/net/if_tun.c,v retrieving revision 1.158 diff -u -r1.158 if_tun.c --- sys/net/if_tun.c 8 Aug 2006 19:22:25 -0000 1.158 +++ sys/net/if_tun.c 13 Sep 2006 08:56:14 -0000 @@ -23,6 +23,7 @@ #include "opt_mac.h" #include +#include #include #include #include @@ -596,9 +597,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/net80211/ieee80211_ioctl.c,v retrieving revision 1.49 diff -u -r1.49 ieee80211_ioctl.c --- sys/net80211/ieee80211_ioctl.c 10 Aug 2006 06:04:00 -0000 1.49 +++ sys/net80211/ieee80211_ioctl.c 13 Sep 2006 08:56:14 -0000 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -342,7 +343,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; @@ -859,7 +860,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; @@ -1509,7 +1510,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); @@ -2691,7 +2692,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); @@ -2700,7 +2701,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/netgraph/ng_socket.c,v retrieving revision 1.77 diff -u -r1.77 ng_socket.c --- sys/netgraph/ng_socket.c 21 Jul 2006 17:11:13 -0000 1.77 +++ sys/netgraph/ng_socket.c 13 Sep 2006 08:56:14 -0000 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -178,9 +179,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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/netinet/in_pcb.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.181 diff -u -r1.181 in_pcb.c --- sys/netinet/in_pcb.c 6 Sep 2006 13:56:35 -0000 1.181 +++ sys/netinet/in_pcb.c 13 Sep 2006 08:56:14 -0000 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -330,7 +331,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; @@ -399,7 +401,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: /home/ncvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.42 diff -u -r1.42 ip_carp.c --- sys/netinet/ip_carp.c 9 Jul 2006 06:04:01 -0000 1.42 +++ sys/netinet/ip_carp.c 13 Sep 2006 08:56:14 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1847,7 +1848,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; @@ -1922,7 +1924,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: /home/ncvs/src/sys/netinet/ip_divert.c,v retrieving revision 1.120 diff -u -r1.120 ip_divert.c --- sys/netinet/ip_divert.c 18 Jul 2006 22:34:27 -0000 1.120 +++ sys/netinet/ip_divert.c 13 Sep 2006 08:56:14 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -419,8 +420,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: /home/ncvs/src/sys/netinet/ip_fw2.c,v retrieving revision 1.146 diff -u -r1.146 ip_fw2.c --- sys/netinet/ip_fw2.c 12 Sep 2006 04:25:12 -0000 1.146 +++ sys/netinet/ip_fw2.c 13 Sep 2006 08:56:14 -0000 @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -3935,7 +3936,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: /home/ncvs/src/sys/netinet/ip_mroute.c,v retrieving revision 1.118 diff -u -r1.118 ip_mroute.c --- sys/netinet/ip_mroute.c 18 May 2006 19:51:08 -0000 1.118 +++ sys/netinet/ip_mroute.c 13 Sep 2006 08:56:14 -0000 @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -567,7 +568,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: /home/ncvs/src/sys/netinet/ip_output.c,v retrieving revision 1.263 diff -u -r1.263 ip_output.c --- sys/netinet/ip_output.c 11 Sep 2006 19:56:10 -0000 1.263 +++ sys/netinet/ip_output.c 13 Sep 2006 08:56:14 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -979,8 +980,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: /home/ncvs/src/sys/netinet/raw_ip.c,v retrieving revision 1.165 diff -u -r1.165 raw_ip.c --- sys/netinet/raw_ip.c 6 Sep 2006 19:04:36 -0000 1.165 +++ sys/netinet/raw_ip.c 13 Sep 2006 08:56:14 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -386,7 +387,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) @@ -396,7 +401,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) @@ -417,7 +422,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) : @@ -451,7 +456,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) @@ -463,7 +471,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) @@ -473,14 +481,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(); @@ -488,7 +496,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 ? @@ -507,7 +515,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) : @@ -597,9 +605,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: /home/ncvs/src/sys/netinet/tcp_subr.c,v retrieving revision 1.262 diff -u -r1.262 tcp_subr.c --- sys/netinet/tcp_subr.c 8 Sep 2006 13:09:15 -0000 1.262 +++ sys/netinet/tcp_subr.c 13 Sep 2006 08:56:14 -0000 @@ -49,6 +49,7 @@ #ifdef INET6 #include #endif +#include #include #include #include @@ -1064,7 +1065,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)); @@ -1108,7 +1110,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: /home/ncvs/src/sys/netinet/udp_usrreq.c,v retrieving revision 1.194 diff -u -r1.194 udp_usrreq.c --- sys/netinet/udp_usrreq.c 6 Sep 2006 19:04:36 -0000 1.194 +++ sys/netinet/udp_usrreq.c 13 Sep 2006 08:56:14 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -686,7 +687,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: /home/ncvs/src/sys/netinet6/in6.c,v retrieving revision 1.63 diff -u -r1.63 in6.c --- sys/netinet6/in6.c 4 Aug 2006 21:27:38 -0000 1.63 +++ sys/netinet6/in6.c 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -0000 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include Index: sys/netncp/ncp_mod.c =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:14 -0000 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include Index: sys/netncp/ncp_subr.h =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include Index: sys/netsmb/smb_subr.h =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/nfsserver/nfs_syscalls.c,v retrieving revision 1.106 diff -u -r1.106 nfs_syscalls.c --- sys/nfsserver/nfs_syscalls.c 1 Aug 2006 15:32:25 -0000 1.106 +++ sys/nfsserver/nfs_syscalls.c 13 Sep 2006 08:56:14 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -141,7 +142,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/security/audit/audit.c,v retrieving revision 1.19 diff -u -r1.19 audit.c --- sys/security/audit/audit.c 9 Sep 2006 10:23:00 -0000 1.19 +++ sys/security/audit/audit.c 13 Sep 2006 08:56:14 -0000 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -511,7 +512,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/security/audit/audit_syscalls.c,v retrieving revision 1.5 diff -u -r1.5 audit_syscalls.c --- sys/security/audit/audit_syscalls.c 1 Sep 2006 11:45:40 -0000 1.5 +++ sys/security/audit/audit_syscalls.c 13 Sep 2006 08:56:14 -0000 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -63,7 +64,7 @@ void * rec; struct kaudit_record *ar; - error = suser(td); + error = priv_check(td, PRIV_AUDIT_SUBMIT); if (error) return (error); @@ -143,7 +144,7 @@ struct proc *tp; AUDIT_ARG(cmd, uap->cmd); - error = suser(td); + error = priv_check(td, PRIV_AUDIT_CONTROL); if (error) return (error); @@ -389,7 +390,7 @@ int error; au_id_t id; - error = suser(td); + error = priv_check(td, PRIV_AUDIT_GETAUDIT); if (error) return (error); @@ -411,7 +412,7 @@ int error; au_id_t id; - error = suser(td); + error = priv_check(td, PRIV_AUDIT_SETAUDIT); if (error) return (error); @@ -449,7 +450,7 @@ struct auditinfo ai; int error; - error = suser(td); + error = priv_check(td, PRIV_AUDIT_GETAUDIT); if (error) return (error); @@ -468,7 +469,7 @@ struct auditinfo ai; int error; - error = suser(td); + error = priv_check(td, PRIV_AUDIT_SETAUDIT); if (error) return (error); @@ -495,7 +496,7 @@ { int error; - error = suser(td); + error = priv_check(td, PRIV_AUDIT_GETAUDIT); if (error) return (error); return (ENOSYS); @@ -508,7 +509,7 @@ { int error; - error = suser(td); + error = priv_check(td, PRIV_AUDIT_SETAUDIT); if (error) return (error); return (ENOSYS); @@ -530,7 +531,7 @@ int error = 0; int flags, vfslocked; - error = suser(td); + error = priv_check(td, PRIV_AUDIT_CONTROL); if (error) return (error); Index: sys/security/mac/mac_internal.h =================================================================== RCS file: /home/ncvs/src/sys/security/mac/mac_internal.h,v retrieving revision 1.112 diff -u -r1.112 mac_internal.h --- sys/security/mac/mac_internal.h 22 Oct 2004 11:07:18 -0000 1.112 +++ sys/security/mac/mac_internal.h 13 Sep 2006 08:56:14 -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: @@ -40,7 +44,6 @@ * MAC Framework sysctl namespace. */ #ifdef SYSCTL_DECL -SYSCTL_DECL(_security); SYSCTL_DECL(_security_mac); #ifdef MAC_DEBUG SYSCTL_DECL(_security_mac_debug); @@ -169,6 +172,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: /home/ncvs/src/sys/security/mac/mac_net.c,v retrieving revision 1.117 diff -u -r1.117 mac_net.c --- sys/security/mac/mac_net.c 5 Jul 2005 23:39:50 -0000 1.117 +++ sys/security/mac/mac_net.c 13 Sep 2006 08:56:14 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -487,11 +488,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 13 Sep 2006 13:46:32 -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, enum priv priv) +{ + int error; + + MAC_CHECK(priv_check, cred, priv); + + return (error); +} + +int +mac_priv_grant(struct ucred *cred, enum priv priv) +{ + int error; + + MAC_GRANT(priv_grant, cred, priv); + + return (error); +} Index: sys/security/mac_bsdextended/mac_bsdextended.c =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/security/mac_lomac/mac_lomac.c,v retrieving revision 1.40 diff -u -r1.40 mac_lomac.c --- sys/security/mac_lomac/mac_lomac.c 12 Sep 2006 04:25:12 -0000 1.40 +++ sys/security/mac_lomac/mac_lomac.c 13 Sep 2006 08:56:14 -0000 @@ -49,6 +49,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: /home/ncvs/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 13 Sep 2006 08:56:14 -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: /home/ncvs/src/sys/security/mac_portacl/mac_portacl.c,v retrieving revision 1.8 diff -u -r1.8 mac_portacl.c --- sys/security/mac_portacl/mac_portacl.c 31 Oct 2005 15:41:28 -0000 1.8 +++ sys/security/mac_portacl/mac_portacl.c 13 Sep 2006 08:56:14 -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, 0); + error = priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT, + SUSER_ALLOWJAIL); return (error); } Index: sys/security/mac_seeotheruids/mac_seeotheruids.c =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:14 -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/sys/jail.h =================================================================== RCS file: /home/ncvs/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 13 Sep 2006 08:56:14 -0000 @@ -40,6 +40,7 @@ #include #include #include +#include #define JAIL_MAX 999999 @@ -110,6 +111,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, enum priv priv); void prison_remote_ip(struct ucred *cred, int flags, u_int32_t *ip); #endif /* _KERNEL */ Index: sys/sys/mac.h =================================================================== RCS file: /home/ncvs/src/sys/sys/mac.h,v retrieving revision 1.71 diff -u -r1.71 mac.h --- sys/sys/mac.h 12 Sep 2006 04:25:13 -0000 1.71 +++ sys/sys/mac.h 13 Sep 2006 08:56:14 -0000 @@ -47,8 +47,6 @@ #ifndef _SYS_MAC_H_ #define _SYS_MAC_H_ -#include - #ifndef _POSIX_MAC #define _POSIX_MAC #endif @@ -107,6 +105,9 @@ #else /* _KERNEL */ +#include +#include /* XXXRW: Until name space issues resolved. */ + /* * Kernel functions to manage and evaluate labels. */ @@ -465,6 +466,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, enum priv priv); +int mac_priv_grant(struct ucred *cred, enum priv priv); /* * Calls to help various file systems implement labeling functionality Index: sys/sys/mac_policy.h =================================================================== RCS file: /home/ncvs/src/sys/sys/mac_policy.h,v retrieving revision 1.75 diff -u -r1.75 mac_policy.h --- sys/sys/mac_policy.h 12 Sep 2006 04:25:13 -0000 1.75 +++ sys/sys/mac_policy.h 13 Sep 2006 08:57:21 -0000 @@ -593,6 +593,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, enum priv priv); +typedef int (*mpo_priv_grant_t)(struct ucred *cred, enum priv priv); struct mac_policy_ops { /* @@ -883,6 +885,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 13 Sep 2006 08:59:50 -0000 @@ -0,0 +1,309 @@ +/*- + * 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. + */ +enum priv { + /* Track beginning of privilege list. */ + _PRIV_LOWEST, + + /* + * PRIV_ROOT is a catch-all for as yet unnamed privileges. No new + * references to this privilege should be added. + */ + PRIV_ROOT, /* 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. + */ + PRIV_ACCT, /* Manage process accounting. */ + PRIV_MAXFILES, /* Exceed system open files limit. */ + PRIV_MAXPROC, /* Exceed system processes limit. */ + PRIV_KTRACE, /* Set/accept KTRFAC_ROOT on ktrace. */ + PRIV_SETDUMPER, /* Configure dump device (XXX: needs work). */ + PRIV_NFSD, /* Can become NFS daemon. */ + PRIV_REBOOT, /* Can reboot system. */ + PRIV_SWAPON, /* Can swapon(). */ + PRIV_SWAPOFF, /* Can swapoff(). */ + PRIV_MSGBUF, /* Can read kernel message buffer. */ + PRIV_WITNESS, /* Can configure WITNESS. */ + PRIV_IO, /* Can perform low-level I/O. */ + PRIV_KEYBOARD, /* Reprogram keyboard. */ + PRIV_DRIVER, /* Low-level driver privilege. */ + PRIV_ADJTIME, /* Set time adjustment. */ + PRIV_NTP_ADJTIME, /* Set NTP time adjustment. */ + PRIV_CLOCK_SETTIME, /* Can call clock_settime. */ + PRIV_SETTIMEOFDAY, /* Can call settimeofday. */ + PRIV_SETHOSTID, /* Can call sethostid. */ + PRIV_SETDOMAINNAME, /* Can call setdomainname. */ + PRIV_AUDIT_CONTROL, /* Can configure audit. */ + PRIV_AUDIT_FAILSTOP, /* Can run during audit fail stop. */ + PRIV_AUDIT_GETAUDIT, /* Can get proc audit properties. */ + PRIV_AUDIT_SETAUDIT, /* Can set proc audit properties. */ + PRIV_AUDIT_SUBMIT, /* Can submit an audit record. */ + PRIV_CRED_SETUID, /* setuid. */ + PRIV_CRED_SETEUID, /* seteuid to !ruid and !svuid. */ + PRIV_CRED_SETGID, /* setgid. */ + PRIV_CRED_SETEGID, /* setgid to !rgid and !svgid. */ + PRIV_CRED_SETGROUPS, /* Set process additional groups. */ + PRIV_CRED_SETREUID, /* setreuid. */ + PRIV_CRED_SETREGID, /* setregid. */ + PRIV_CRED_SETRESUID, /* setresuid. */ + PRIV_CRED_SETRESGID, /* setresgid. */ + PRIV_SEEOTHERGIDS, /* Exempt bsd.seeothergids. */ + PRIV_SEEOTHERUIDS, /* Exempt bsd.seeotheruids. */ + PRIV_DEBUG_DIFFCRED, /* Exempt debugging other users. */ + PRIV_DEBUG_SUGID, /* Exempt debugging setuid proc. */ + PRIV_DEBUG_UNPRIV, /* Exempt unprivileged debug limit. */ + PRIV_FIRMWARE_LOAD, /* Can load firmware. */ + PRIV_JAIL_ATTACH, /* Attach to a jail. */ + PRIV_KENV_SET, /* Set kernel env. variables. */ + PRIV_KENV_UNSET, /* Unset kernel env. variables. */ + PRIV_KLD_LOAD, /* Load a kernel module. */ + PRIV_KLD_UNLOAD, /* Unload a kernel module. */ + PRIV_MAC_PARTITION, /* Privilege in mac_partition policy. */ + PRIV_MAC_PRIVS, /* Privilege in the mac_privs policy. */ + PRIV_PROC_LIMIT, /* Exceed user process limit. */ + PRIV_PROC_SETLOGIN, /* Can call setlogin. */ + PRIV_PROC_SETRLIMIT, /* Can raise resources limits. */ + PRIV_IPC_READ, /* Can override IPC read perm. */ + PRIV_IPC_WRITE, /* Can override IPC write perm. */ + PRIV_IPC_EXEC, /* Can override IPC exec perm. */ + PRIV_IPC_ADMIN, /* Can override IPC owner-only perm. */ + PRIV_IPC_MSGSIZE, /* Exempt IPC message queue limit. */ + PRIV_MQ_ADMIN, /* Can override msgq owner-only perm. */ + PRIV_PMC_MANAGE, /* Can administer PMC. */ + PRIV_PMC_SYSTEM, /* Can allocate a system-wide PMC. */ + PRIV_SCHED_DIFFCRED, /* Exempt scheduling other users. */ + PRIV_SCHED_SETPRIORITY, /* Can set lower nice value for proc. */ + PRIV_SCHED_RTPRIO, /* Can set real time scheduling. */ + PRIV_SCHED_SETPOLICY, /* Can set scheduler policy. */ + PRIV_SCHED_SET, /* Can set thread scheduler. */ + PRIV_SCHED_SETPARAM, /* Can set thread scheduler params. */ + PRIV_SEM_WRITE, /* Can override sem write perm. */ + PRIV_SIGNAL_DIFFCRED, /* Exempt signalling other users. */ + PRIV_SIGNAL_SUGID, /* Non-conserv signal setuid proc. */ + PRIV_SYSCTL_DEBUG, /* Can invoke sysctl.debug. */ + PRIV_SYSCTL_WRITE, /* Can write sysctls. */ + PRIV_SYSCTL_WRITEJAIL, /* Can write sysctls, jail permitted. */ + PRIV_TTY_CONSOLE, /* Set console to tty. */ + PRIV_TTY_DRAINWAIT, /* Set tty drain wait time. */ + PRIV_TTY_DTRWAIT, /* Set DTR wait on tty. */ + PRIV_TTY_EXCLUSIVE, /* Override tty exclusive flag. */ + PRIV_TTY_PRISON, /* Can open pts across jails. */ + PRIV_TTY_STI, /* Simulate input on another tty. */ + PRIV_TTY_SETA, /* Set tty termios structure. */ + PRIV_UFS_EXTATTRCTL, /* Can configure EAs on UFS1. */ + PRIV_UFS_GETQUOTA, /* getquota(). */ + PRIV_UFS_QUOTAOFF, /* quotaoff(). */ + PRIV_UFS_QUOTAON, /* quotaon(). */ + PRIV_UFS_SETQUOTA, /* setquota(). */ + PRIV_UFS_SETUSE, /* setuse(). */ + PRIV_UFS_EXCEEDQUOTA, /* Exempt from quota restrictions. */ + PRIV_VFS_READ, /* Override vnode DAC read perm. */ + PRIV_VFS_WRITE, /* Override vnode DAC write perm. */ + PRIV_VFS_ADMIN, /* Override vnode DAC admin perm. */ + PRIV_VFS_EXEC, /* Override vnode DAC exec perm. */ + PRIV_VFS_LOOKUP, /* Override vnode DAC lookup perm. */ + PRIV_VFS_BLOCKRESERVE, /* Can use free block reserve. */ + PRIV_VFS_CHFLAGS_DEV, /* Can chflags() a device node. */ + PRIV_VFS_CHOWN, /* Can set user; group to non-member. */ + PRIV_VFS_CHROOT, /* chroot(). */ + PRIV_VFS_CLEARSUGID, /* Don't clear sugid on change. */ + PRIV_VFS_EXTATTR_SYSTEM, /* Operate on system EA namespace. */ + PRIV_VFS_FCHROOT, /* fchrot(). */ + PRIV_VFS_FHOPEN, /* Can fhopen(). */ + PRIV_VFS_FHSTAT, /* Can fhstat(). */ + PRIV_VFS_FHSTATFS, /* Can fhstatfs(). */ + PRIV_VFS_GENERATION, /* stat() returns generation number. */ + PRIV_VFS_GETFH, /* Can retrieve file handles. */ + PRIV_VFS_LINK, /* bsd.hardlink_check_uid */ + PRIV_VFS_MKNOD_DEV, /* Can create device nodes. */ + PRIV_VFS_MOUNT, /* Can mount(). */ + PRIV_VFS_MOUNT_OWNER, /* Override owner on user mounts. */ + PRIV_VFS_MOUNT_EXPORTED, /* Can set MNT_EXPORTED on mount. */ + PRIV_VFS_MOUNT_PERM, /* Override device node perms at mount. */ + PRIV_VFS_MOUNT_SUIDDIR, /* Can set MNT_SUIDDIR on mount. */ + PRIV_VFS_SETGID, /* Can setgid if not in group. */ + PRIV_VFS_STICKYFILE, /* Can set sticky bit on file. */ + PRIV_VFS_SYSFLAGS, /* Can modify system flags. */ + PRIV_VFS_UNMOUNT, /* Can unmount(). */ + PRIV_VM_MADV_PROTECT, /* Can set MADV_PROTECT. */ + PRIV_VM_MLOCK, /* Can mlock(), mlockall(). */ + PRIV_VM_MUNLOCK, /* Can munlock(), munlockall(). */ + PRIV_DEVFS_RULE, /* Can manage devfs rules. */ + PRIV_DEVFS_SYMLINK, /* Can create symlinks in devfs. */ + PRIV_RANDOM_RESEED, /* Closing /dev/random reseeds. */ + PRIV_NET_BRIDGE, /* Administer bridge. */ + PRIV_NET_GRE, /* Administer GRE. */ + PRIV_NET_PPP, /* Administer PPP. */ + PRIV_NET_SLIP, /* Administer SLIP. */ + PRIV_NET_BPF, /* Monitor BPF. */ + PRIV_NET_RAW, /* Open raw socket. */ + PRIV_NET_ROUTE, /* Administer routing. */ + PRIV_NET_TAP, /* Can open tap device. */ + PRIV_NET_SETIFMTU, /* Set interface MTU. */ + PRIV_NET_SETIFFLAGS, /* Set interface flags. */ + PRIV_NET_SETIFCAP, /* Set interface capabilities. */ + PRIV_NET_SETIFNAME, /* Set interface name. */ + PRIV_NET_SETIFMETRIC, /* Set interface metrics. */ + PRIV_NET_SETIFPHYS, /* Set interface physical layer prop. */ + PRIV_NET_SETIFMAC, /* Set interface MAC label. */ + PRIV_NET_ADDMULTI, /* Add multicast addr. to ifnet. */ + PRIV_NET_DELMULTI, /* Delete multicast addr. from ifnet. */ + PRIV_NET_HWIOCTL, /* Issue hardware ioctl on ifnet. */ + PRIV_NET_SETLLADDR, + PRIV_NET_ADDIFGROUP, /* Add new interface group. */ + PRIV_NET_DELIFGROUP, /* Delete interface group. */ + PRIV_NET_IFCREATE, /* Create cloned interface. */ + PRIV_NET_IFDESTROY, /* Destroy cloned interface. */ + PRIV_NET80211_GETKEY, /* Query 802.11 keys. */ + PRIV_NET80211_MANAGE, /* Administer 802.11. */ + PRIV_NETATALK_RESERVEDPORT, /* Bind low port number. */ + PRIV_NETATM_CFG, + PRIV_NETATM_ADD, + PRIV_NETATM_DEL, + PRIV_NETATM_SET, + PRIV_NETGRAPH_CONTROL, /* Open netgraph control socket. */ + PRIV_NETGRAPH_TTY, /* Configure tty for netgraph. */ + PRIV_NETINET_RESERVEDPORT, /* Bind low port number. */ + PRIV_NETINET_IPFW, /* Administer IPFW firewall. */ + PRIV_NETINET_DIVERT, /* Open IP divert socket. */ + PRIV_NETINET_PF, /* Administer pf firewall. */ + PRIV_NETINET_DUMMYNET, /* Administer DUMMYNET. */ + PRIV_NETINET_CARP, /* Administer CARP. */ + PRIV_NETINET_MROUTE, /* Administer multicast routing. */ + PRIV_NETINET_RAW, /* Open netinet raw socket. */ + PRIV_NETINET_GETCRED, /* Query netinet pcb credentials. */ + PRIV_NETINET_ADDRCTRL6, /* Administer IPv6 address scopes. */ + PRIV_NETINET_ND6, /* Administer IPv6 neighbor disc. */ + PRIV_NETINET_SCOPE6, /* Administer IPv6 address scopes. */ + PRIV_NETINET_ALIFETIME6, /* Administer IPv6 address lifetimes. */ + PRIV_NETINET_IPSEC, /* Administer IPSEC. */ + PRIV_NETIPX_RESERVEDPORT, /* Bind low port number. */ + PRIV_NETIPX_RAW, /* Open netipx raw socket. */ + PRIV_NETNCP, /* Allow use of connection owned by another user. */ + PRIV_NETSMB, /* Allow use of connection owned by another user. */ + PRIV_VM86_INTCALL, /* 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. + */ + _PRIV_RESERVED0, + _PRIV_RESERVED1, + _PRIV_RESERVED2, + _PRIV_RESERVED3, + _PRIV_RESERVED4, + _PRIV_RESERVED5, + _PRIV_RESERVED6, + _PRIV_RESERVED7, + _PRIV_RESERVED8, + _PRIV_RESERVED9, + _PRIV_RESERVED10, + _PRIV_RESERVED11, + _PRIV_RESERVED12, + _PRIV_RESERVED13, + _PRIV_RESERVED14, + _PRIV_RESERVED15, + + /* + * 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. + */ + PRIV_MODULE0, + PRIV_MODULE1, + PRIV_MODULE2, + PRIV_MODULE3, + PRIV_MODULE4, + PRIV_MODULE5, + PRIV_MODULE6, + PRIV_MODULE7, + PRIV_MODULE8, + PRIV_MODULE9, + PRIV_MODULE10, + PRIV_MODULE11, + PRIV_MODULE12, + PRIV_MODULE13, + PRIV_MODULE14, + PRIV_MODULE15, + + /* Track end of privilege list. */ + _PRIV_HIGHEST +}; + +/* + * 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. + */ +#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, enum priv priv); +int priv_check_cred(struct ucred *cred, enum priv priv, int flags); +#endif + +#endif /* !_SYS_PRIV_H_ */ Index: sys/sys/sysctl.h =================================================================== RCS file: /home/ncvs/src/sys/sys/sysctl.h,v retrieving revision 1.144 diff -u -r1.144 sysctl.h --- sys/sys/sysctl.h 21 Aug 2006 06:27:27 -0000 1.144 +++ sys/sys/sysctl.h 13 Sep 2006 08:56:40 -0000 @@ -628,6 +628,8 @@ SYSCTL_DECL(_user); SYSCTL_DECL(_compat); SYSCTL_DECL(_regression); +SYSCTL_DECL(_security); +SYSCTL_DECL(_security_bsd); extern char machine[]; extern char osrelease[]; Index: sys/sys/systm.h =================================================================== RCS file: /home/ncvs/src/sys/sys/systm.h,v retrieving revision 1.243 diff -u -r1.243 systm.h --- sys/sys/systm.h 28 Aug 2006 02:28:14 -0000 1.243 +++ sys/sys/systm.h 13 Sep 2006 08:56:40 -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: /home/ncvs/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 13 Sep 2006 08:56:40 -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: /home/ncvs/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.318 diff -u -r1.318 ffs_vfsops.c --- sys/ufs/ffs/ffs_vfsops.c 9 Jul 2006 14:11:09 -0000 1.318 +++ sys/ufs/ffs/ffs_vfsops.c 13 Sep 2006 08:56:40 -0000 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -248,15 +249,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; @@ -345,14 +347,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: /home/ncvs/src/sys/ufs/ffs/ffs_vnops.c,v retrieving revision 1.160 diff -u -r1.160 ffs_vnops.c --- sys/ufs/ffs/ffs_vnops.c 5 May 2006 19:58:36 -0000 1.160 +++ sys/ufs/ffs/ffs_vnops.c 13 Sep 2006 08:56:40 -0000 @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -778,7 +779,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); } @@ -1101,7 +1103,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: /home/ncvs/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 13 Sep 2006 08:56:40 -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: /home/ncvs/src/sys/ufs/ufs/ufs_quota.c,v retrieving revision 1.82 diff -u -r1.82 ufs_quota.c --- sys/ufs/ufs/ufs_quota.c 5 May 2006 20:10:04 -0000 1.82 +++ sys/ufs/ufs/ufs_quota.c 13 Sep 2006 08:56:40 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -58,8 +59,6 @@ #include #include -SYSCTL_DECL(_security_bsd); - static int unprivileged_get_quota = 0; SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_get_quota, CTLFLAG_RW, &unprivileged_get_quota, 0, @@ -167,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; @@ -290,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; @@ -425,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 +522,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); @@ -586,15 +595,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); } @@ -629,7 +641,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); @@ -695,7 +708,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: /home/ncvs/src/sys/ufs/ufs/ufs_vnops.c,v retrieving revision 1.278 diff -u -r1.278 ufs_vnops.c --- sys/ufs/ufs/ufs_vnops.c 20 Aug 2006 10:52:44 -0000 1.278 +++ sys/ufs/ufs/ufs_vnops.c 13 Sep 2006 08:56:40 -0000 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -465,8 +466,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)) { @@ -557,10 +561,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; @@ -626,11 +639,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); } @@ -667,19 +682,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; @@ -750,7 +765,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); } @@ -2321,7 +2337,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: /home/ncvs/src/sys/vm/swap_pager.c,v retrieving revision 1.282 diff -u -r1.282 swap_pager.c --- sys/vm/swap_pager.c 9 Aug 2006 17:43:27 -0000 1.282 +++ sys/vm/swap_pager.c 13 Sep 2006 08:56:40 -0000 @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -1965,11 +1966,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; @@ -2008,7 +2009,6 @@ done: swdev_syscall_active = 0; wakeup_one(&swdev_syscall_active); -done2: mtx_unlock(&Giant); return (error); } @@ -2104,7 +2104,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: /home/ncvs/src/sys/vm/vm_mmap.c,v retrieving revision 1.206 diff -u -r1.206 vm_mmap.c --- sys/vm/vm_mmap.c 21 Jun 2006 12:59:05 -0000 1.206 +++ sys/vm/vm_mmap.c 13 Sep 2006 08:56:40 -0000 @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -683,7 +684,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); @@ -950,7 +951,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; @@ -1015,7 +1016,7 @@ } PROC_UNLOCK(td->td_proc); #else - error = suser(td); + error = priv_check(td, PRIV_VM_MLOCK); if (error) return (error); #endif @@ -1060,7 +1061,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); @@ -1094,7 +1095,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;