Index: share/man/man9/Makefile =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/share/man/man9/Makefile,v retrieving revision 1.282 diff -u -r1.282 Makefile --- share/man/man9/Makefile 5 Oct 2006 12:40:44 -0000 1.282 +++ share/man/man9/Makefile 31 Oct 2006 09:06:00 -0000 @@ -188,6 +188,7 @@ pmap_zero_page.9 \ printf.9 \ prison_check.9 \ + priv.9 \ pseudofs.9 \ psignal.9 \ random.9 \ Index: share/man/man9/priv.9 =================================================================== RCS file: share/man/man9/priv.9 diff -N share/man/man9/priv.9 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ share/man/man9/priv.9 31 Oct 2006 09:03:48 -0000 @@ -0,0 +1,115 @@ +.\"- +.\" Copyright (c) 2006 nCircle Network Security, Inc. +.\" All rights reserved. +.\" +.\" This software was developed by Robert N. M. Watson for the TrustedBSD +.\" Project under contract to nCircle Network Security, Inc. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY, +.\" INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +.\" TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +.\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 30, 2007 +.Dt priv 9 +.Os +.Sh NAME +.Nm priv +.Nd kernel privilege checking API +.Sh SYNOPSIS +.In sys/priv.h +.Ft int +.Fn priv_check "struct thread *td" "int priv" +.Ft int +.Fn priv_check_cred "struct ucred *cred" "int priv" "int flags" +.Sh DESCRIPTION +The +.Xr priv 9 +interfaces check to see if specific system privileges are granted to the +passed thread, +.Va td , +or credential, +.Va cred. +This interface replaces the +.Xr suser 9 +privilege checking interface. +Privileges typically represent rights in one of two categories: the right to +manage a particular component of the system, or an exemption to a specific +policy or access control list. +The caller identifies the desired privilege via the +.Fa priv +argument. +Additional access control context may also be passed using the +.Va flags . +.Ss Privilege Policies +Privileges are typically granted based on one of two base system policies: +the superuser policy, which grants privilege based on the effective (or +sometimes real) uid having a value of 0, and the +.Xr jail 2 +policy, which permits only certain privileges to be granted to processes in a +jail. +The set of available privileges may also be influenced by the TrustedBSD MAC +Framework, described in +.Xr mac 9 . +.Sh IMPLEMENTATION NOTES +When adding a new privilege check to a code path, first check the complete +list of current privileges in +.Pa sys/priv.h +to see if one already exists for the class of privilege required. +Only if there is not an exact match should a new privilege be added to the +privilege list. +As the privilege number becomes encoded in the kernel module ABI, privileges +should only be appended to the list, not inserted in the list, and the list +sort order should not be changed. +.Pp +Certain catch-all privileges exist, such as +.Dv PRIV_DRIVER , +intended to be used by device drivers, rather than adding a new +driver-specific privilege. +.Sh RETURN VALUES +Typically, 0 will be returned for success, and +.Dv EPERM +will be returned on failure. +Most consumers of +.Xr priv 9 +will wish to directly return the error code from a failed privilege check to +user space; a small number will wish to translate it to another error code +appropriate to a specific context. +.Pp +When designing new APIs, it is preferable to return explicit errors from a +call if privilege is not granted rather than changing the semantics of the +call but returning success. +For example, the behavior exhibited by +.Xr stat 2 , +in which the generation field is optionally zero'd out when insufficient +privilege is not present is highly undesirable, as it results in frequent +privilege checks, and the caller is unable to tell if an access control +failure occured. +.Sh SEE ALSO +.Xr jail 2 , +.Xr mac 9 , +.Xr suser 9 , +.Xr ucred 9 +.Sh AUTHORS +The +.Xr priv 9 +API and implementation were created by Robert Watson under contract to +nCircle Network Security, Inc. Index: share/man/man9/suser.9 =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/share/man/man9/suser.9,v retrieving revision 1.29 diff -u -r1.29 suser.9 --- share/man/man9/suser.9 16 May 2006 22:58:43 -0000 1.29 +++ share/man/man9/suser.9 31 Oct 2006 09:05:47 -0000 @@ -54,6 +54,12 @@ .Fn suser_cred functions check if the credentials given include superuser powers. .Pp +These interfaces have now been obsoleted by +.Xr priv 9 , +and are provided only for compatibility with third party kernel modules that +have not yet been updated to the new interface. +They should not be used in any new kernel code. +.Pp The .Fn suser function is the most common, and should be used unless special @@ -123,7 +129,8 @@ in which a TRUE response indicates superuser powers. .Sh SEE ALSO .Xr chroot 2 , -.Xr jail 2 +.Xr jail 2 , +.Xr priv 9 .Sh BUGS The .Fn suser Index: sys/amd64/amd64/io.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/amd64/amd64/io.c,v retrieving revision 1.1 diff -u -r1.1 io.c --- sys/amd64/amd64/io.c 1 Aug 2004 11:40:50 -0000 1.1 +++ sys/amd64/amd64/io.c 30 Oct 2006 17:07:54 -0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +55,7 @@ { int error; - error = suser(td); + error = priv_check(td, PRIV_IO); if (error != 0) return (error); error = securelevel_gt(td->td_ucred, 0); Index: sys/compat/linux/linux_misc.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/compat/linux/linux_misc.c,v retrieving revision 1.191 diff -u -r1.191 linux_misc.c --- sys/compat/linux/linux_misc.c 28 Oct 2006 16:47:38 -0000 1.191 +++ sys/compat/linux/linux_misc.c 30 Oct 2006 17:07:54 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -1020,7 +1021,8 @@ * Keep cr_groups[0] unchanged to prevent that. */ - if ((error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) { + if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, + SUSER_ALLOWJAIL)) != 0) { PROC_UNLOCK(p); crfree(newcred); return (error); @@ -1341,7 +1343,7 @@ switch (args->cmd) { case REBOOT_CAD_ON: case REBOOT_CAD_OFF: - return suser(td); + return (priv_check(td, PRIV_REBOOT)); case REBOOT_HALT: bsd_args.opt = RB_HALT; break; Index: sys/compat/linux/linux_uid16.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/compat/linux/linux_uid16.c,v retrieving revision 1.19 diff -u -r1.19 linux_uid16.c --- sys/compat/linux/linux_uid16.c 19 Mar 2006 11:10:33 -0000 1.19 +++ sys/compat/linux/linux_uid16.c 30 Oct 2006 17:07:54 -0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -123,7 +124,8 @@ * Keep cr_groups[0] unchanged to prevent that. */ - if ((error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) { + if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, + SUSER_ALLOWJAIL)) != 0) { PROC_UNLOCK(p); crfree(newcred); return (error); Index: sys/compat/svr4/svr4_fcntl.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/compat/svr4/svr4_fcntl.c,v retrieving revision 1.38 diff -u -r1.38 svr4_fcntl.c --- sys/compat/svr4/svr4_fcntl.c 22 Oct 2006 11:52:11 -0000 1.38 +++ sys/compat/svr4/svr4_fcntl.c 30 Oct 2006 17:07:54 -0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -280,7 +281,8 @@ goto out; if (td->td_ucred->cr_uid != vattr.va_uid && - (error = suser(td)) != 0) + (error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN, + SUSER_ALLOWJAIL)) != 0) goto out; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) Index: sys/compat/svr4/svr4_misc.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/compat/svr4/svr4_misc.c,v retrieving revision 1.90 diff -u -r1.90 svr4_misc.c --- sys/compat/svr4/svr4_misc.c 22 Oct 2006 11:52:11 -0000 1.90 +++ sys/compat/svr4/svr4_misc.c 30 Oct 2006 17:07:54 -0000 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -611,7 +612,8 @@ struct file *fp; int error, vfslocked; - if ((error = suser(td)) != 0) + if ((error = priv_check_cred(td->td_ucred, PRIV_VFS_FCHROOT, + SUSER_ALLOWJAIL)) != 0) return error; if ((error = getvnode(fdp, uap->fd, &fp)) != 0) return error; Index: sys/conf/files =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/conf/files,v retrieving revision 1.1156 diff -u -r1.1156 files --- sys/conf/files 30 Oct 2006 05:51:53 -0000 1.1156 +++ sys/conf/files 30 Oct 2006 21:24:56 -0000 @@ -1347,6 +1347,7 @@ kern/kern_physio.c standard kern/kern_pmc.c standard kern/kern_poll.c optional device_polling +kern/kern_priv.c standard kern/kern_proc.c standard kern/kern_prot.c standard kern/kern_resource.c standard @@ -1920,6 +1921,7 @@ security/mac/mac_net.c optional mac security/mac/mac_pipe.c optional mac security/mac/mac_posix_sem.c optional mac +security/mac/mac_priv.c optional mac security/mac/mac_process.c optional mac security/mac/mac_socket.c optional mac security/mac/mac_system.c optional mac Index: sys/contrib/altq/altq/altq_cbq.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_cbq.c,v retrieving revision 1.3 diff -u -r1.3 altq_cbq.c --- sys/contrib/altq/altq/altq_cbq.c 9 Aug 2005 10:19:41 -0000 1.3 +++ sys/contrib/altq/altq/altq_cbq.c 30 Oct 2006 17:07:54 -0000 @@ -1062,7 +1062,9 @@ /* currently only command that an ordinary user can call */ break; default: -#if (__FreeBSD_version > 400000) +#if (__FreeBSD_version > 700000) + error = priv_check(p, PRIV_ALTQ_MANAGE); +#elsif (__FreeBSD_version > 400000) error = suser(p); #else error = suser(p->p_ucred, &p->p_acflag); Index: sys/contrib/altq/altq/altq_cdnr.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_cdnr.c,v retrieving revision 1.2 diff -u -r1.2 altq_cdnr.c --- sys/contrib/altq/altq/altq_cdnr.c 12 Jun 2004 00:57:20 -0000 1.2 +++ sys/contrib/altq/altq/altq_cdnr.c 30 Oct 2006 17:07:54 -0000 @@ -1262,7 +1262,9 @@ case CDNR_GETSTATS: break; default: -#if (__FreeBSD_version > 400000) +#if (__FreeBSD_versoin > 700000) + if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0) +#elsif (__FreeBSD_version > 400000) if ((error = suser(p)) != 0) #else if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) Index: sys/contrib/altq/altq/altq_hfsc.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_hfsc.c,v retrieving revision 1.2 diff -u -r1.2 altq_hfsc.c --- sys/contrib/altq/altq/altq_hfsc.c 12 Jun 2004 00:57:20 -0000 1.2 +++ sys/contrib/altq/altq/altq_hfsc.c 30 Oct 2006 17:07:54 -0000 @@ -1975,7 +1975,10 @@ case HFSC_GETSTATS: break; default: -#if (__FreeBSD_version > 400000) +#if (__FreeBSD_version > 700000) + if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0) + return (error); +#elsif (__FreeBSD_version > 400000) if ((error = suser(p)) != 0) return (error); #else Index: sys/contrib/altq/altq/altq_priq.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_priq.c,v retrieving revision 1.2 diff -u -r1.2 altq_priq.c --- sys/contrib/altq/altq/altq_priq.c 12 Jun 2004 00:57:20 -0000 1.2 +++ sys/contrib/altq/altq/altq_priq.c 30 Oct 2006 17:07:54 -0000 @@ -772,7 +772,10 @@ case PRIQ_GETSTATS: break; default: -#if (__FreeBSD_version > 400000) +#if (__FreeBSD_version > 700000) + if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0) + return (error); +#elsif (__FreeBSD_version > 400000) if ((error = suser(p)) != 0) return (error); #else Index: sys/contrib/altq/altq/altq_red.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_red.c,v retrieving revision 1.2 diff -u -r1.2 altq_red.c --- sys/contrib/altq/altq/altq_red.c 12 Jun 2004 00:57:20 -0000 1.2 +++ sys/contrib/altq/altq/altq_red.c 30 Oct 2006 17:07:54 -0000 @@ -781,7 +781,9 @@ case RED_GETSTATS: break; default: -#if (__FreeBSD_version > 400000) +#if (__FreeBSD_version > 700000) + if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0) +#elsif (__FreeBSD_version > 400000) if ((error = suser(p)) != 0) #else if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) Index: sys/contrib/altq/altq/altq_rio.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/altq/altq/altq_rio.c,v retrieving revision 1.3 diff -u -r1.3 altq_rio.c --- sys/contrib/altq/altq/altq_rio.c 10 Jun 2005 16:49:03 -0000 1.3 +++ sys/contrib/altq/altq/altq_rio.c 30 Oct 2006 17:07:54 -0000 @@ -531,7 +531,10 @@ case RIO_GETSTATS: break; default: -#if (__FreeBSD_version > 400000) +#if (__FreeBSD_versoin > 700000) + if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0) + return (error); +#elsif (__FreeBSD_version > 400000) if ((error = suser(p)) != 0) return (error); #else Index: sys/contrib/pf/net/if_pfsync.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/contrib/pf/net/if_pfsync.c,v retrieving revision 1.30 diff -u -r1.30 if_pfsync.c --- sys/contrib/pf/net/if_pfsync.c 9 Jul 2006 06:04:01 -0000 1.30 +++ sys/contrib/pf/net/if_pfsync.c 30 Oct 2006 17:07:54 -0000 @@ -54,6 +54,9 @@ #endif #include +#ifdef __FreeBSD__ +#include +#endif #include #include #include @@ -1057,7 +1060,7 @@ break; case SIOCSETPFSYNC: #ifdef __FreeBSD__ - if ((error = suser(curthread)) != 0) + if ((error = priv_check(curthread, PRIV_NETINET_PF)) != 0) #else if ((error = suser(p, p->p_acflag)) != 0) #endif Index: sys/dev/an/if_an.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/an/if_an.c,v retrieving revision 1.79 diff -u -r1.79 if_an.c --- sys/dev/an/if_an.c 16 May 2006 14:36:22 -0000 1.79 +++ sys/dev/an/if_an.c 30 Oct 2006 17:07:54 -0000 @@ -92,6 +92,7 @@ #include #include #include +#include #include #include #include @@ -1920,7 +1921,7 @@ break; #ifdef ANCACHE if (sc->areq.an_type == AN_RID_ZERO_CACHE) { - error = suser(td); + error = priv_check(td, PRIV_DRIVER); if (error) break; sc->an_sigitems = sc->an_nextitem = 0; @@ -1944,7 +1945,7 @@ error = copyout(&sc->areq, ifr->ifr_data, sizeof(sc->areq)); break; case SIOCSAIRONET: - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_DRIVER))) goto out; error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); if (error != 0) @@ -1952,7 +1953,7 @@ an_setdef(sc, &sc->areq); break; case SIOCGPRIVATE_0: /* used by Cisco client utility */ - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_DRIVER))) goto out; error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); if (error) @@ -1974,7 +1975,7 @@ } break; case SIOCGPRIVATE_1: /* used by Cisco client utility */ - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_DRIVER))) goto out; error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); if (error) @@ -2226,7 +2227,7 @@ } break; case SIOCS80211: - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_NET80211_MANAGE))) goto out; sc->areq.an_len = sizeof(sc->areq); /* Index: sys/dev/arl/if_arl.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/arl/if_arl.c,v retrieving revision 1.13 diff -u -r1.13 if_arl.c --- sys/dev/arl/if_arl.c 16 May 2006 14:36:23 -0000 1.13 +++ sys/dev/arl/if_arl.c 30 Oct 2006 17:07:54 -0000 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -504,7 +505,7 @@ break; case SIOCS80211: - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_NET80211_MANAGE))) break; switch (ireq->i_type) { case IEEE80211_IOC_SSID: @@ -577,7 +578,7 @@ } case SIOCGARLALL: bzero(&arlan_io, sizeof(arlan_io)); - if (!suser(td)) { + if (!priv_check(td, PRIV_DRIVER)) { bcopy(ar->systemId, arlan_io.cfg.sid, 4); } @@ -616,7 +617,7 @@ } while (0) case SIOCSARLALL: - if (suser(td)) + if (priv_check(td, PRIV_DRIVER)) break; user = (void *)ifr->ifr_data; Index: sys/dev/asr/asr.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/asr/asr.c,v retrieving revision 1.79 diff -u -r1.79 asr.c --- sys/dev/asr/asr.c 31 Oct 2006 05:53:26 -0000 1.79 +++ sys/dev/asr/asr.c 31 Oct 2006 08:40:40 -0000 @@ -117,6 +117,7 @@ #include #include #include +#include #include #include #include @@ -3145,7 +3146,7 @@ s = splcam (); if (ASR_ctlr_held) { error = EBUSY; - } else if ((error = suser(td)) == 0) { + } else if ((error = priv_check(td, PRIV_DRIVER)) == 0) { ++ASR_ctlr_held; } splx(s); Index: sys/dev/ata/atapi-cd.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/ata/atapi-cd.c,v retrieving revision 1.189 diff -u -r1.189 atapi-cd.c --- sys/dev/ata/atapi-cd.c 28 Jun 2006 15:04:10 -0000 1.189 +++ sys/dev/ata/atapi-cd.c 30 Oct 2006 17:07:54 -0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -257,8 +258,11 @@ cdp->flags |= F_LOCKED; break; + /* + * XXXRW: Why does this require privilege? + */ case CDIOCRESET: - error = suser(td); + error = priv_check(td, PRIV_DRIVER); if (error) break; error = acd_test_ready(dev); Index: sys/dev/ce/if_ce.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/ce/if_ce.c,v retrieving revision 1.3 diff -u -r1.3 if_ce.c --- sys/dev/ce/if_ce.c 3 Feb 2006 20:55:30 -0000 1.3 +++ sys/dev/ce/if_ce.c 30 Oct 2006 17:07:54 -0000 @@ -29,6 +29,7 @@ #if NPCI > 0 #include +#include #include #include #include @@ -1341,9 +1342,11 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else /* __FreeBSD_version >= 500000 */ +#elsif __FreeBSD_version < 700000 error = suser (td); -#endif /* __FreeBSD_version >= 500000 */ +#else + error = priv_check (td, PRIV_DRIVER); +#endif if (error) return error; #if __FreeBSD_version >= 600034 @@ -1380,8 +1383,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1408,8 +1413,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1426,8 +1433,10 @@ CE_DEBUG2 (d, ("ioctl: setcfg\n")); #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1526,8 +1535,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1560,8 +1571,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1586,8 +1599,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1608,8 +1623,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1634,8 +1651,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1658,8 +1677,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1686,8 +1707,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1708,8 +1731,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1734,8 +1759,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1758,8 +1785,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1784,8 +1813,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1810,8 +1841,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1836,8 +1869,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1867,8 +1902,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1892,8 +1929,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1909,8 +1948,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; @@ -1945,8 +1986,10 @@ /* Only for superuser! */ #if __FreeBSD_version < 500000 error = suser (p); -#else +#elsif __FreeBSD_version < 700000 error = suser (td); +#else + error = priv_check (td, PRIV_DRIVER); #endif if (error) return error; Index: sys/dev/cnw/if_cnw.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/cnw/if_cnw.c,v retrieving revision 1.23 diff -u -r1.23 if_cnw.c --- sys/dev/cnw/if_cnw.c 16 May 2006 14:36:23 -0000 1.23 +++ sys/dev/cnw/if_cnw.c 30 Oct 2006 17:07:54 -0000 @@ -236,6 +236,7 @@ #include #include #include +#include #include #include #include @@ -1339,7 +1340,7 @@ #if !defined(__FreeBSD__) error = suser(p->p_ucred, &p->p_acflag); #else - error = suser(td); + error = priv_check(td, PRIV_DRIVER); #endif if (error) break; @@ -1350,7 +1351,7 @@ #if !defined(__FreeBSD__) error = suser(p->p_ucred, &p->p_acflag); #else - error = suser(td); + error = priv_check(td, PRIV_DRIVER); #endif if (error) break; @@ -1361,7 +1362,7 @@ #if !defined(__FreeBSD__) error = suser(p->p_ucred, &p->p_acflag); #else - error = suser(td); + error = priv_check(td, PRIV_DRIVER); #endif if (error) break; Index: sys/dev/cp/if_cp.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/cp/if_cp.c,v retrieving revision 1.29 diff -u -r1.29 if_cp.c --- sys/dev/cp/if_cp.c 27 Sep 2005 16:57:44 -0000 1.29 +++ sys/dev/cp/if_cp.c 30 Oct 2006 17:07:54 -0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -1071,7 +1072,7 @@ case SERIAL_SETPROTO: CP_DEBUG2 (d, ("ioctl: setproto\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (d->ifp->if_drv_flags & IFF_DRV_RUNNING) @@ -1102,7 +1103,7 @@ case SERIAL_SETKEEPALIVE: CP_DEBUG2 (d, ("ioctl: setkeepalive\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if ((IFP2SP(d->ifp)->pp_flags & PP_FR) || @@ -1126,7 +1127,7 @@ case SERIAL_SETMODE: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (*(int*)data != SERIAL_HDLC) @@ -1142,7 +1143,7 @@ case SERIAL_SETCFG: CP_DEBUG2 (d, ("ioctl: setcfg\n")); - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_E1) @@ -1239,7 +1240,7 @@ case SERIAL_CLRSTAT: CP_DEBUG2 (d, ("ioctl: clrstat\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; c->rintr = 0; @@ -1268,7 +1269,7 @@ case SERIAL_SETBAUD: CP_DEBUG2 (d, ("ioctl: setbaud\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1286,7 +1287,7 @@ case SERIAL_SETLOOP: CP_DEBUG2 (d, ("ioctl: setloop\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1306,7 +1307,7 @@ case SERIAL_SETDPLL: CP_DEBUG2 (d, ("ioctl: setdpll\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_SERIAL) @@ -1328,7 +1329,7 @@ case SERIAL_SETNRZI: CP_DEBUG2 (d, ("ioctl: setnrzi\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_SERIAL) @@ -1348,7 +1349,7 @@ case SERIAL_SETDEBUG: CP_DEBUG2 (d, ("ioctl: setdebug\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; d->chan->debug = *(int*)data; @@ -1370,7 +1371,7 @@ case SERIAL_SETHIGAIN: CP_DEBUG2 (d, ("ioctl: sethigain\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_E1) @@ -1392,7 +1393,7 @@ case SERIAL_SETPHONY: CP_DEBUG2 (d, ("ioctl: setphony\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_E1) @@ -1414,7 +1415,7 @@ case SERIAL_SETUNFRAM: CP_DEBUG2 (d, ("ioctl: setunfram\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_E1) @@ -1436,7 +1437,7 @@ case SERIAL_SETSCRAMBLER: CP_DEBUG2 (d, ("ioctl: setscrambler\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_G703 && !c->unfram) @@ -1461,7 +1462,7 @@ case SERIAL_SETMONITOR: CP_DEBUG2 (d, ("ioctl: setmonitor\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_E1) @@ -1483,7 +1484,7 @@ case SERIAL_SETUSE16: CP_DEBUG2 (d, ("ioctl: setuse16\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_E1) @@ -1505,7 +1506,7 @@ case SERIAL_SETCRC4: CP_DEBUG2 (d, ("ioctl: setcrc4\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_E1) @@ -1538,7 +1539,7 @@ case SERIAL_SETCLK: CP_DEBUG2 (d, ("ioctl: setclk\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_E1 && @@ -1571,7 +1572,7 @@ case SERIAL_SETTIMESLOTS: CP_DEBUG2 (d, ("ioctl: settimeslots\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if ((c->type != T_E1 || c->unfram) && c->type != T_DATA) @@ -1597,7 +1598,7 @@ case SERIAL_SETINVCLK: CP_DEBUG2 (d, ("ioctl: setinvclk\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_SERIAL) @@ -1620,7 +1621,7 @@ case SERIAL_SETINVTCLK: CP_DEBUG2 (d, ("ioctl: setinvtclk\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_SERIAL) @@ -1642,7 +1643,7 @@ case SERIAL_SETINVRCLK: CP_DEBUG2 (d, ("ioctl: setinvrclk\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->type != T_SERIAL) @@ -1669,7 +1670,7 @@ case SERIAL_RESET: CP_DEBUG2 (d, ("ioctl: reset\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1682,7 +1683,7 @@ case SERIAL_HARDRESET: CP_DEBUG2 (d, ("ioctl: hardreset\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1714,7 +1715,7 @@ case SERIAL_SETDIR: CP_DEBUG2 (d, ("ioctl: setdir\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1739,7 +1740,7 @@ if (c->type != T_E3 && c->type != T_T3 && c->type != T_STS1) return EINVAL; /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1761,7 +1762,7 @@ if (c->type != T_T3 && c->type != T_STS1) return EINVAL; /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); Index: sys/dev/ctau/if_ct.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/ctau/if_ct.c,v retrieving revision 1.29 diff -u -r1.29 if_ct.c --- sys/dev/ctau/if_ct.c 16 May 2006 14:36:24 -0000 1.29 +++ sys/dev/ctau/if_ct.c 30 Oct 2006 17:07:54 -0000 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1300,7 +1301,7 @@ case SERIAL_SETPROTO: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (d->ifp->if_drv_flags & IFF_DRV_RUNNING) @@ -1328,7 +1329,7 @@ case SERIAL_SETKEEPALIVE: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if ((IFP2SP(d->ifp)->pp_flags & PP_FR) || @@ -1357,7 +1358,7 @@ case SERIAL_SETCFG: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->mode == M_HDLC) @@ -1435,7 +1436,7 @@ case SERIAL_CLRSTAT: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; c->rintr = 0; @@ -1458,7 +1459,7 @@ case SERIAL_SETBAUD: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1474,7 +1475,7 @@ case SERIAL_SETLOOP: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1492,7 +1493,7 @@ case SERIAL_SETDPLL: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->mode == M_E1 || c->mode == M_G703) @@ -1512,7 +1513,7 @@ case SERIAL_SETNRZI: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->mode == M_E1 || c->mode == M_G703) @@ -1530,7 +1531,7 @@ case SERIAL_SETDEBUG: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; c->debug = *(int*)data; @@ -1550,7 +1551,7 @@ case SERIAL_SETHIGAIN: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1572,7 +1573,7 @@ if (c->mode != M_E1) return EINVAL; /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1595,7 +1596,7 @@ case SERIAL_SETCLK: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1619,7 +1620,7 @@ case SERIAL_SETTIMESLOTS: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1637,7 +1638,7 @@ case SERIAL_SETSUBCHAN: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splimp (); @@ -1663,7 +1664,7 @@ case SERIAL_SETINVCLK: case SERIAL_SETINVTCLK: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->mode == M_E1 || c->mode == M_G703) @@ -1677,7 +1678,7 @@ case SERIAL_SETINVRCLK: /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->mode == M_E1 || c->mode == M_G703) Index: sys/dev/cx/if_cx.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/cx/if_cx.c,v retrieving revision 1.52 diff -u -r1.52 if_cx.c --- sys/dev/cx/if_cx.c 16 May 2006 14:36:24 -0000 1.52 +++ sys/dev/cx/if_cx.c 30 Oct 2006 17:07:54 -0000 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1632,7 +1633,7 @@ case SERIAL_SETPORT: CX_DEBUG2 (d, ("ioctl: setproto\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; @@ -1658,7 +1659,7 @@ case SERIAL_SETPROTO: CX_DEBUG2 (d, ("ioctl: setproto\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->mode == M_ASYNC) @@ -1695,7 +1696,7 @@ case SERIAL_SETKEEPALIVE: CX_DEBUG2 (d, ("ioctl: setkeepalive\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if ((IFP2SP(d->ifp)->pp_flags & PP_FR) || @@ -1725,7 +1726,7 @@ case SERIAL_SETMODE: CX_DEBUG2 (d, ("ioctl: setmode\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; @@ -1778,7 +1779,7 @@ case SERIAL_CLRSTAT: CX_DEBUG2 (d, ("ioctl: clrstat\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splhigh (); @@ -1810,7 +1811,7 @@ case SERIAL_SETBAUD: CX_DEBUG2 (d, ("ioctl: setbaud\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->mode == M_ASYNC) @@ -1836,7 +1837,7 @@ case SERIAL_SETLOOP: CX_DEBUG2 (d, ("ioctl: setloop\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->mode == M_ASYNC) @@ -1862,7 +1863,7 @@ case SERIAL_SETDPLL: CX_DEBUG2 (d, ("ioctl: setdpll\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->mode == M_ASYNC) @@ -1888,7 +1889,7 @@ case SERIAL_SETNRZI: CX_DEBUG2 (d, ("ioctl: setnrzi\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; if (c->mode == M_ASYNC) @@ -1912,7 +1913,7 @@ case SERIAL_SETDEBUG: CX_DEBUG2 (d, ("ioctl: setdebug\n")); /* Only for superuser! */ - error = suser (td); + error = priv_check (td, PRIV_DRIVER); if (error) return error; s = splhigh (); Index: sys/dev/dcons/dcons_os.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/dcons/dcons_os.c,v retrieving revision 1.11 diff -u -r1.11 dcons_os.c --- sys/dev/dcons/dcons_os.c 26 May 2006 13:51:38 -0000 1.11 +++ sys/dev/dcons/dcons_os.c 30 Oct 2006 17:07:54 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -293,7 +294,8 @@ if ((tp->t_state & TS_ISOPEN) == 0) { tp->t_state |= TS_CARR_ON; ttyconsolemode(tp, 0); - } else if ((tp->t_state & TS_XCLUDE) && suser(td)) { + } else if ((tp->t_state & TS_XCLUDE) && + priv_check(td, PRIV_TTY_EXCLUSIVE)) { splx(s); return (EBUSY); } Index: sys/dev/drm/drmP.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/drm/drmP.h,v retrieving revision 1.17 diff -u -r1.17 drmP.h --- sys/dev/drm/drmP.h 7 Sep 2006 23:04:47 -0000 1.17 +++ sys/dev/drm/drmP.h 30 Oct 2006 17:07:54 -0000 @@ -50,6 +50,9 @@ #include #include #include +#if __FreeBSD_version >= 700000 +#include +#endif #include #include #include @@ -233,7 +236,11 @@ #define PAGE_ALIGN(addr) round_page(addr) /* DRM_SUSER returns true if the user is superuser */ +#if __FreeBSD_version >= 700000 +#define DRM_SUSER(p) (priv_check(p, PRIV_DRIVER) == 0) +#else #define DRM_SUSER(p) (suser(p) == 0) +#endif #define DRM_AGP_FIND_DEVICE() agp_find_device() #define DRM_MTRR_WC MDF_WRITECOMBINE #define jiffies ticks Index: sys/dev/fdc/fdc.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/fdc/fdc.c,v retrieving revision 1.313 diff -u -r1.313 fdc.c --- sys/dev/fdc/fdc.c 8 Sep 2006 21:46:00 -0000 1.313 +++ sys/dev/fdc/fdc.c 30 Oct 2006 17:07:54 -0000 @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -1489,8 +1490,9 @@ return (0); case FD_CLRERR: - if (suser(td) != 0) - return (EPERM); + error = priv_check(td, PRIV_DRIVER); + if (error) + return (error); fd->fdc->fdc_errs = 0; return (0); Index: sys/dev/hwpmc/hwpmc_mod.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/hwpmc/hwpmc_mod.c,v retrieving revision 1.25 diff -u -r1.25 hwpmc_mod.c --- sys/dev/hwpmc/hwpmc_mod.c 17 Sep 2006 20:00:35 -0000 1.25 +++ sys/dev/hwpmc/hwpmc_mod.c 30 Oct 2006 17:07:54 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -2782,10 +2783,9 @@ KASSERT(td == curthread, ("[pmc,%d] td != curthread", __LINE__)); - if (suser(td) || jailed(td->td_ucred)) { - error = EPERM; + error = priv_check(td, PRIV_PMC_MANAGE); + if (error) break; - } if ((error = copyin(arg, &pma, sizeof(pma))) != 0) break; @@ -2918,11 +2918,16 @@ */ if (PMC_IS_SYSTEM_MODE(mode)) { - if (jailed(curthread->td_ucred)) - error = EPERM; - else if (suser(curthread) && - (pmc_unprivileged_syspmcs == 0)) + if (jailed(curthread->td_ucred)) { error = EPERM; + break; + } + if (!pmc_unprivileged_syspmcs) { + error = priv_check(curthread, + PRIV_PMC_SYSTEM); + if (error) + break; + } } if (error) Index: sys/dev/if_ndis/if_ndis.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/if_ndis/if_ndis.c,v retrieving revision 1.117 diff -u -r1.117 if_ndis.c --- sys/dev/if_ndis/if_ndis.c 4 Feb 2006 19:42:49 -0000 1.117 +++ sys/dev/if_ndis/if_ndis.c 30 Oct 2006 17:07:54 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -2836,7 +2837,7 @@ error = ENOTTY; break; case SIOCGDRVSPEC: - if ((error = suser(curthread))) + if ((error = priv_check(curthread, PRIV_DRIVER))) break; error = copyin(ifr->ifr_data, &oid, sizeof(oid)); if (error) @@ -2865,7 +2866,7 @@ free(oidbuf, M_TEMP); break; case SIOCSDRVSPEC: - if ((error = suser(curthread))) + if ((error = priv_check(curthread, PRIV_DRIVER))) break; error = copyin(ifr->ifr_data, &oid, sizeof(oid)); if (error) @@ -2894,7 +2895,7 @@ free(oidbuf, M_TEMP); break; case SIOCGPRIVATE_0: - if ((error = suser(curthread))) + if ((error = priv_check(curthread, PRIV_DRIVER))) break; NDIS_LOCK(sc); if (sc->ndis_evt[sc->ndis_evtcidx].ne_sts == 0) { @@ -3062,7 +3063,7 @@ uint32_t foo; int error, len; - error = suser(curthread); + error = priv_check(curthread, PRIV_DRIVER); if (error) return (error); @@ -3370,7 +3371,7 @@ break; #endif case IEEE80211_IOC_STATIONNAME: - error = suser(curthread); + error = priv_check(curthread, PRIV_NET80211_MANAGE); if (error) break; if (ireq->i_val != 0 || Index: sys/dev/kbd/kbd.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/kbd/kbd.c,v retrieving revision 1.45 diff -u -r1.45 kbd.c --- sys/dev/kbd/kbd.c 28 Feb 2006 23:46:23 -0000 1.45 +++ sys/dev/kbd/kbd.c 30 Oct 2006 17:07:54 -0000 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -972,11 +973,11 @@ if (keymap_restrict_change >= 2) { for (i = 0; i < NUM_STATES; i++) if (oldkey->map[i] != newkey->map[i]) - return suser(td); + return priv_check(td, PRIV_KEYBOARD); if (oldkey->spcl != newkey->spcl) - return suser(td); + return priv_check(td, PRIV_KEYBOARD); if (oldkey->flgs != newkey->flgs) - return suser(td); + return priv_check(td, PRIV_KEYBOARD); return (0); } @@ -991,7 +992,7 @@ if ((oldkey->spcl & (0x80 >> i)) == (newkey->spcl & (0x80 >> i)) && oldkey->map[i] == newkey->map[i]) continue; - return suser(td); + return priv_check(td, PRIV_KEYBOARD); } return (0); @@ -1020,20 +1021,20 @@ return (0); if (oldmap->n_accs != newmap->n_accs) - return suser(td); + return priv_check(td, PRIV_KEYBOARD); for (accent = 0; accent < oldmap->n_accs; accent++) { oldacc = &oldmap->acc[accent]; newacc = &newmap->acc[accent]; if (oldacc->accchar != newacc->accchar) - return suser(td); + return priv_check(td, PRIV_KEYBOARD); for (i = 0; i < NUM_ACCENTCHARS; ++i) { if (oldacc->map[i][0] != newacc->map[i][0]) - return suser(td); + return priv_check(td, PRIV_KEYBOARD); if (oldacc->map[i][0] == 0) /* end of table */ break; if (oldacc->map[i][1] != newacc->map[i][1]) - return suser(td); + return priv_check(td, PRIV_KEYBOARD); } } @@ -1048,7 +1049,7 @@ if (oldkey->len != newkey->flen || bcmp(oldkey->str, newkey->keydef, oldkey->len) != 0) - return suser(td); + return priv_check(td, PRIV_KEYBOARD); return (0); } Index: sys/dev/lmc/if_lmc.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/lmc/if_lmc.c,v retrieving revision 1.29 diff -u -r1.29 if_lmc.c --- sys/dev/lmc/if_lmc.c 15 Jul 2006 02:07:38 -0000 1.29 +++ sys/dev/lmc/if_lmc.c 30 Oct 2006 17:07:55 -0000 @@ -113,6 +113,9 @@ # include # include # include +# if (__FreeBSD_version >= 700000) +# include +# endif # if (__FreeBSD_version >= 500000) # include # include Index: sys/dev/lmc/if_lmc.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/lmc/if_lmc.h,v retrieving revision 1.4 diff -u -r1.4 if_lmc.h --- sys/dev/lmc/if_lmc.h 21 Jul 2006 08:45:00 -0000 1.4 +++ sys/dev/lmc/if_lmc.h 30 Oct 2006 17:07:55 -0000 @@ -1223,7 +1223,11 @@ # define TOP_UNLOCK mtx_unlock (&sc->top_mtx) # define BOTTOM_TRYLOCK mtx_trylock(&sc->bottom_mtx) # define BOTTOM_UNLOCK mtx_unlock (&sc->bottom_mtx) -# define CHECK_CAP suser(curthread) +# if (__FreeBSD_version >= 700000) +# define CHECK_CAP priv_check(curthread, PRIV_DRIVER) +# else +# define CHECK_CAP suser(curthread) +# endif # else /* FreeBSD-4 */ # define TOP_TRYLOCK (sc->top_spl = splimp()) # define TOP_UNLOCK splx(sc->top_spl) Index: sys/dev/nmdm/nmdm.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/nmdm/nmdm.c,v retrieving revision 1.37 diff -u -r1.37 nmdm.c --- sys/dev/nmdm/nmdm.c 4 Jan 2006 08:34:23 -0000 1.37 +++ sys/dev/nmdm/nmdm.c 30 Oct 2006 17:07:55 -0000 @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -286,7 +287,8 @@ if ((tp->t_state & TS_ISOPEN) == 0) { ttyinitmode(tp, 0, 0); ttsetwater(tp); /* XXX ? */ - } else if (tp->t_state & TS_XCLUDE && suser(td)) { + } else if (tp->t_state & TS_XCLUDE && + priv_check(td, PRIV_TTY_EXCLUSIVE)) { return (EBUSY); } Index: sys/dev/null/null.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/null/null.c,v retrieving revision 1.31 diff -u -r1.31 null.c --- sys/dev/null/null.c 27 Feb 2005 22:00:45 -0000 1.31 +++ sys/dev/null/null.c 30 Oct 2006 17:07:55 -0000 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,7 @@ if (cmd != DIOCSKERNELDUMP) return (ENOIOCTL); - error = suser(td); + error = priv_check(td, PRIV_SETDUMPER); if (error) return (error); return (set_dumper(NULL)); Index: sys/dev/ofw/ofw_console.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/ofw/ofw_console.c,v retrieving revision 1.34 diff -u -r1.34 ofw_console.c --- sys/dev/ofw/ofw_console.c 30 May 2006 07:56:57 -0000 1.34 +++ sys/dev/ofw/ofw_console.c 30 Oct 2006 17:07:55 -0000 @@ -140,7 +140,8 @@ ttyconsolemode(tp, 0); setuptimeout = 1; - } else if ((tp->t_state & TS_XCLUDE) && suser(td)) { + } else if ((tp->t_state & TS_XCLUDE) && + priv_check(td, PRIV_TTY_EXCLUSIVE)) { return (EBUSY); } Index: sys/dev/random/randomdev.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/random/randomdev.c,v retrieving revision 1.60 diff -u -r1.60 randomdev.c --- sys/dev/random/randomdev.c 20 Dec 2005 21:41:52 -0000 1.60 +++ sys/dev/random/randomdev.c 30 Oct 2006 17:07:55 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -85,7 +86,7 @@ random_close(struct cdev *dev __unused, int flags, int fmt __unused, struct thread *td) { - if ((flags & FWRITE) && (suser(td) == 0) + if ((flags & FWRITE) && (priv_check(td, PRIV_RANDOM_RESEED) == 0) && (securelevel_gt(td->td_ucred, 0) == 0)) { (*random_systat.reseed)(); random_systat.seeded = 1; Index: sys/dev/sbni/if_sbni.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/sbni/if_sbni.c,v retrieving revision 1.22 diff -u -r1.22 if_sbni.c --- sys/dev/sbni/if_sbni.c 11 Nov 2005 16:04:54 -0000 1.22 +++ sys/dev/sbni/if_sbni.c 30 Oct 2006 17:07:55 -0000 @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -1110,7 +1111,7 @@ case SIOCSHWFLAGS: /* set flags */ /* root only */ - error = suser(td); + error = priv_check(td, PRIV_DRIVER); if (error) break; flags = *(struct sbni_flags*)&ifr->ifr_data; @@ -1132,7 +1133,7 @@ break; case SIOCRINSTATS: - if (!(error = suser(td))) /* root only */ + if (!(error = priv_check(td, PRIV_DRIVER))) /* root only */ bzero(&sc->in_stats, sizeof(struct sbni_in_stats)); break; Index: sys/dev/sbsh/if_sbsh.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/sbsh/if_sbsh.c,v retrieving revision 1.16 diff -u -r1.16 if_sbsh.c --- sys/dev/sbsh/if_sbsh.c 16 May 2006 14:36:31 -0000 1.16 +++ sys/dev/sbsh/if_sbsh.c 30 Oct 2006 17:07:55 -0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -424,7 +425,7 @@ switch(cmd) { case SIOCLOADFIRMW: - if ((error = suser(curthread)) != 0) + if ((error = priv_check(curthread, PRIV_DRIVER)) != 0) break; if (ifp->if_flags & IFF_UP) error = EBUSY; @@ -444,7 +445,7 @@ break; case SIOCGETSTATS : - if ((error = suser(curthread)) != 0) + if ((error = priv_check(curthread, PRIV_DRIVER)) != 0) break; t = 0; @@ -478,7 +479,7 @@ break; case SIOCCLRSTATS : - if (!(error = suser(curthread))) { + if (!(error = priv_check(curthread, PRIV_DRIVER))) { bzero(&sc->in_stats, sizeof(struct sbni16_stats)); t = 2; if (issue_cx28975_cmd(sc, _DSL_CLEAR_ERROR_CTRS, &t, 1)) Index: sys/dev/si/si.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/si/si.c,v retrieving revision 1.137 diff -u -r1.137 si.c --- sys/dev/si/si.c 6 Jan 2006 19:56:12 -0000 1.137 +++ sys/dev/si/si.c 30 Oct 2006 17:07:55 -0000 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -650,7 +651,7 @@ ip = (int *)data; -#define SUCHECK if ((error = suser(td))) goto out +#define SUCHECK if ((error = priv_check(td, PRIV_DRIVER))) goto out switch (cmd) { case TCSIPORTS: Index: sys/dev/syscons/syscons.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/syscons/syscons.c,v retrieving revision 1.447 diff -u -r1.447 syscons.c --- sys/dev/syscons/syscons.c 27 Sep 2006 19:56:59 -0000 1.447 +++ sys/dev/syscons/syscons.c 30 Oct 2006 17:07:55 -0000 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -517,7 +518,7 @@ ttyld_modem(tp, 1); } else - if (tp->t_state & TS_XCLUDE && suser(td)) + if (tp->t_state & TS_XCLUDE && priv_check(td, PRIV_TTY_EXCLUSIVE)) return(EBUSY); error = ttyld_open(tp, dev); @@ -1092,7 +1093,7 @@ return 0; case KDENABIO: /* allow io operations */ - error = suser(td); + error = priv_check(td, PRIV_IO); if (error != 0) return error; error = securelevel_gt(td->td_ucred, 0); Index: sys/dev/syscons/sysmouse.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/syscons/sysmouse.c,v retrieving revision 1.28 diff -u -r1.28 sysmouse.c --- sys/dev/syscons/sysmouse.c 4 Dec 2005 02:12:42 -0000 1.28 +++ sys/dev/syscons/sysmouse.c 30 Oct 2006 17:07:55 -0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -83,7 +84,8 @@ ttyinitmode(tp, 0, 0); smparam(tp, &tp->t_termios); ttyld_modem(tp, 1); - } else if (tp->t_state & TS_XCLUDE && suser(td)) { + } else if (tp->t_state & TS_XCLUDE && + priv_check(td, PRIV_TTY_EXCLUSIVE)) { return EBUSY; } Index: sys/dev/wi/if_wi.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/wi/if_wi.c,v retrieving revision 1.199 diff -u -r1.199 if_wi.c --- sys/dev/wi/if_wi.c 5 Aug 2006 04:58:25 -0000 1.199 +++ sys/dev/wi/if_wi.c 30 Oct 2006 17:07:55 -0000 @@ -76,6 +76,7 @@ #endif #include #include +#include #include #include #include @@ -1273,7 +1274,7 @@ WI_UNLOCK(sc); break; case SIOCSIFGENERIC: - error = suser(td); + error = priv_check(td, PRIV_DRIVER); if (error == 0) error = wi_set_cfg(ifp, cmd, data); break; @@ -1291,7 +1292,7 @@ error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); break; case SIOCSPRISM2DEBUG: - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_DRIVER))) return (error); error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); if (error) @@ -1312,7 +1313,7 @@ case SIOCS80211: ireq = (struct ieee80211req *) data; if (ireq->i_type == IEEE80211_IOC_STATIONNAME) { - error = suser(td); + error = priv_check(td, PRIV_NET80211_MANAGE); if (error) break; if (ireq->i_val != 0 || Index: sys/dev/wl/if_wl.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/wl/if_wl.c,v retrieving revision 1.73 diff -u -r1.73 if_wl.c --- sys/dev/wl/if_wl.c 19 Jun 2006 11:30:36 -0000 1.73 +++ sys/dev/wl/if_wl.c 30 Oct 2006 17:07:55 -0000 @@ -197,6 +197,7 @@ #include #include #include +#include #include #include #include @@ -1310,7 +1311,7 @@ /* pointer to buffer in user space */ up = (void *)ifr->ifr_data; /* work out if they're root */ - isroot = (suser(td) == 0); + isroot = (priv_check(td, PRIV_NET80211_GETKEY) == 0); for (i = 0; i < 0x40; i++) { /* don't hand the DES key out to non-root users */ @@ -1327,7 +1328,7 @@ /* copy the PSA in from the caller; we only copy _some_ values */ case SIOCSWLPSA: /* root only */ - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_DRIVER))) break; error = EINVAL; /* assume the worst */ /* pointer to buffer in user space containing data */ @@ -1383,7 +1384,7 @@ */ case SIOCSWLCNWID: /* root only */ - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_DRIVER))) break; if (!(ifp->if_flags & IFF_UP)) { error = EIO; /* only allowed while up */ @@ -1401,7 +1402,7 @@ /* copy the EEPROM in 2.4 Gz WaveMODEM out to the caller */ case SIOCGWLEEPROM: /* root only */ - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_DRIVER))) break; /* pointer to buffer in user space */ up = (void *)ifr->ifr_data; @@ -1428,7 +1429,7 @@ /* zero (Delete) the wl cache */ case SIOCDWLCACHE: /* root only */ - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_DRIVER))) break; wl_cache_zero(sc); break; Index: sys/dev/zs/zs.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/dev/zs/zs.c,v retrieving revision 1.35 diff -u -r1.35 zs.c --- sys/dev/zs/zs.c 26 May 2006 18:25:34 -0000 1.35 +++ sys/dev/zs/zs.c 30 Oct 2006 17:07:55 -0000 @@ -453,7 +453,7 @@ if ((tp->t_state & TS_ISOPEN) != 0 && (tp->t_state & TS_XCLUDE) != 0 && - suser(td) != 0) + priv_check(td, PRIV_TTY_EXCLUSIVE) != 0) return (EBUSY); if ((tp->t_state & TS_ISOPEN) == 0) { Index: sys/fs/devfs/devfs_rule.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/devfs/devfs_rule.c,v retrieving revision 1.22 diff -u -r1.22 devfs_rule.c --- sys/fs/devfs/devfs_rule.c 17 Jul 2006 09:07:01 -0000 1.22 +++ sys/fs/devfs/devfs_rule.c 31 Oct 2006 08:25:32 -0000 @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -164,11 +165,13 @@ sx_assert(&dm->dm_lock, SX_XLOCKED); /* - * XXX: This returns an error regardless of whether we - * actually support the cmd or not. + * XXX: This returns an error regardless of whether we actually + * support the cmd or not. + * + * We could make this privileges finer grained if desired. */ - error = suser(td); - if (error != 0) + error = priv_check(td, PRIV_DEVFS_RULE); + if (error) return (error); sx_xlock(&sx_rules); Index: sys/fs/devfs/devfs_vnops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/devfs/devfs_vnops.c,v retrieving revision 1.139 diff -u -r1.139 devfs_vnops.c --- sys/fs/devfs/devfs_vnops.c 22 Oct 2006 11:52:12 -0000 1.139 +++ sys/fs/devfs/devfs_vnops.c 30 Oct 2006 17:07:55 -0000 @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -1145,19 +1146,25 @@ else gid = vap->va_gid; if (uid != de->de_uid || gid != de->de_gid) { - if (((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid || - (gid != de->de_gid && !groupmember(gid, ap->a_cred))) && - (error = suser_cred(ap->a_td->td_ucred, SUSER_ALLOWJAIL)) != 0) - return (error); + if ((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid || + (gid != de->de_gid && !groupmember(gid, ap->a_cred))) { + error = priv_check_cred(ap->a_td->td_ucred, + PRIV_VFS_CHOWN, SUSER_ALLOWJAIL); + if (error) + return (error); + } de->de_uid = uid; de->de_gid = gid; c = 1; } if (vap->va_mode != (mode_t)VNOVAL) { - if ((ap->a_cred->cr_uid != de->de_uid) && - (error = suser_cred(ap->a_td->td_ucred, SUSER_ALLOWJAIL))) - return (error); + if (ap->a_cred->cr_uid != de->de_uid) { + error = priv_check_cred(ap->a_td->td_ucred, + PRIV_VFS_ADMIN, SUSER_ALLOWJAIL); + if (error) + return (error); + } de->de_mode = vap->va_mode; c = 1; } @@ -1227,7 +1234,8 @@ td = ap->a_cnp->cn_thread; KASSERT(td == curthread, ("devfs_symlink: td != curthread")); - error = suser(td); + + error = priv_check(td, PRIV_DEVFS_SYMLINK); if (error) return(error); dmp = VFSTODEVFS(ap->a_dvp->v_mount); Index: sys/fs/hpfs/hpfs_vnops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/hpfs/hpfs_vnops.c,v retrieving revision 1.68 diff -u -r1.68 hpfs_vnops.c --- sys/fs/hpfs/hpfs_vnops.c 17 Jan 2006 17:29:01 -0000 1.68 +++ sys/fs/hpfs/hpfs_vnops.c 30 Oct 2006 17:07:55 -0000 @@ -501,11 +501,12 @@ if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); - if (cred->cr_uid != hp->h_uid && - (error = suser_cred(cred, SUSER_ALLOWJAIL)) && - ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || - (error = VOP_ACCESS(vp, VWRITE, cred, td)))) - return (error); + if (vap->va_vaflags & VA_UTIMES_NULL) { + error = VOP_ACCESS(vp, VADMIN, cred, td); + if (error) + error = VOP_ACCESS(vp, VWRITE, cred, td); + } else + error = VOP_ACCESS(vp, VADMIN, cred, td); if (vap->va_atime.tv_sec != VNOVAL) hp->h_atime = vap->va_atime.tv_sec; if (vap->va_mtime.tv_sec != VNOVAL) Index: sys/fs/msdosfs/msdosfs_vfsops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/msdosfs/msdosfs_vfsops.c,v retrieving revision 1.153 diff -u -r1.153 msdosfs_vfsops.c --- sys/fs/msdosfs/msdosfs_vfsops.c 26 Sep 2006 04:12:45 -0000 1.153 +++ sys/fs/msdosfs/msdosfs_vfsops.c 30 Oct 2006 17:07:55 -0000 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -293,17 +294,17 @@ * If upgrade to read-write by non-root, then verify * that user has necessary permissions on the device. */ - if (suser(td)) { - devvp = pmp->pm_devvp; - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); - error = VOP_ACCESS(devvp, VREAD | VWRITE, - td->td_ucred, td); - if (error) { - VOP_UNLOCK(devvp, 0, td); - return (error); - } + devvp = pmp->pm_devvp; + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); + error = VOP_ACCESS(devvp, VREAD | VWRITE, + td->td_ucred, td); + if (error) + error = priv_check(td, PRIV_VFS_MOUNT_PERM); + if (error) { VOP_UNLOCK(devvp, 0, td); + return (error); } + VOP_UNLOCK(devvp, 0, td); DROP_GIANT(); g_topology_lock(); error = g_access(pmp->pm_cp, 0, 1, 0); @@ -353,15 +354,15 @@ * If mount by non-root, then verify that user has necessary * permissions on the device. */ - if (suser(td)) { - accessmode = VREAD; - if ((mp->mnt_flag & MNT_RDONLY) == 0) - accessmode |= VWRITE; - error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td); - if (error) { - vput(devvp); - return (error); - } + accessmode = VREAD; + if ((mp->mnt_flag & MNT_RDONLY) == 0) + accessmode |= VWRITE; + error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td); + if (error) + error = priv_check(td, PRIV_VFS_MOUNT_PERM); + if (error) { + vput(devvp); + return (error); } if ((mp->mnt_flag & MNT_UPDATE) == 0) { error = mountmsdosfs(devvp, mp, td); Index: sys/fs/msdosfs/msdosfs_vnops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/msdosfs/msdosfs_vnops.c,v retrieving revision 1.164 diff -u -r1.164 msdosfs_vnops.c --- sys/fs/msdosfs/msdosfs_vnops.c 24 Oct 2006 11:14:05 -0000 1.164 +++ sys/fs/msdosfs/msdosfs_vnops.c 30 Oct 2006 17:07:55 -0000 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -404,9 +405,12 @@ if (vap->va_flags != VNOVAL) { if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); - if (cred->cr_uid != pmp->pm_uid && - (error = suser_cred(cred, SUSER_ALLOWJAIL))) - return (error); + if (cred->cr_uid != pmp->pm_uid) { + error = priv_check_cred(cred, PRIV_VFS_ADMIN, + SUSER_ALLOWJAIL); + if (error) + return (error); + } /* * We are very inconsistent about handling unsupported * attributes. We ignored the access time and the @@ -419,9 +423,11 @@ * set ATTR_ARCHIVE for directories `cp -pr' from a more * sensible filesystem attempts it a lot. */ - if (suser_cred(cred, SUSER_ALLOWJAIL)) { - if (vap->va_flags & SF_SETTABLE) - return EPERM; + if (vap->va_flags & SF_SETTABLE) { + error = priv_check_cred(cred, PRIV_VFS_SYSFLAGS, + SUSER_ALLOWJAIL); + if (error) + return (error); } if (vap->va_flags & ~SF_ARCHIVED) return EOPNOTSUPP; @@ -444,10 +450,13 @@ gid = vap->va_gid; if (gid == (gid_t)VNOVAL) gid = pmp->pm_gid; - if ((cred->cr_uid != pmp->pm_uid || uid != pmp->pm_uid || - (gid != pmp->pm_gid && !groupmember(gid, cred))) && - (error = suser_cred(cred, SUSER_ALLOWJAIL))) - return error; + if (cred->cr_uid != pmp->pm_uid || uid != pmp->pm_uid || + (gid != pmp->pm_gid && !groupmember(gid, cred))) { + error = priv_check_cred(cred, PRIV_VFS_CHOWN, + SUSER_ALLOWJAIL); + if (error) + return (error); + } if (uid != pmp->pm_uid || gid != pmp->pm_gid) return EINVAL; } @@ -477,11 +486,13 @@ if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); - if (cred->cr_uid != pmp->pm_uid && - (error = suser_cred(cred, SUSER_ALLOWJAIL)) && - ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || - (error = VOP_ACCESS(ap->a_vp, VWRITE, cred, ap->a_td)))) - return (error); + if (vap->va_vaflags & VA_UTIMES_NULL) { + error = VOP_ACCESS(vp, VADMIN, cred, ap->a_td); + if (error) + error = VOP_ACCESS(vp, VWRITE, cred, + ap->a_td); + } else + error = VOP_ACCESS(vp, VADMIN, cred, ap->a_td); if (vp->v_type != VDIR) { if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 && vap->va_atime.tv_sec != VNOVAL) { @@ -506,9 +517,12 @@ if (vap->va_mode != (mode_t)VNOVAL) { if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); - if (cred->cr_uid != pmp->pm_uid && - (error = suser_cred(cred, SUSER_ALLOWJAIL))) - return (error); + if (cred->cr_uid != pmp->pm_uid) { + error = priv_check_cred(cred, PRIV_VFS_ADMIN, + SUSER_ALLOWJAIL); + if (error) + return (error); + } if (vp->v_type != VDIR) { /* We ignore the read and execute bits. */ if (vap->va_mode & VWRITE) Index: sys/fs/procfs/procfs_ioctl.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/procfs/procfs_ioctl.c,v retrieving revision 1.13 diff -u -r1.13 procfs_ioctl.c --- sys/fs/procfs/procfs_ioctl.c 27 Sep 2006 19:57:00 -0000 1.13 +++ sys/fs/procfs/procfs_ioctl.c 30 Oct 2006 17:07:55 -0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -104,8 +105,19 @@ #endif case PIOCSFL: flags = *(unsigned int *)data; - if (flags & PF_ISUGID && (error = suser(td)) != 0) - break; + if (flags & PF_ISUGID) { + /* + * XXXRW: Is this specific check required here, as + * p_candebug() should implement it, or other checks + * are missing. + * + * XXXRW: Other debugging privileges are granted in + * jail, why isn't this? + */ + error = priv_check(td, PRIV_DEBUG_SUGID); + if (error) + break; + } p->p_pfsflags = flags; break; case PIOCGFL: Index: sys/fs/smbfs/smbfs_vnops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/smbfs/smbfs_vnops.c,v retrieving revision 1.62 diff -u -r1.62 smbfs_vnops.c --- sys/fs/smbfs/smbfs_vnops.c 31 May 2006 22:31:08 -0000 1.62 +++ sys/fs/smbfs/smbfs_vnops.c 30 Oct 2006 17:07:55 -0000 @@ -352,11 +352,13 @@ if (vap->va_atime.tv_sec != VNOVAL) atime = &vap->va_atime; if (mtime != atime) { - if (ap->a_cred->cr_uid != VTOSMBFS(vp)->sm_uid && - (error = suser_cred(ap->a_cred, SUSER_ALLOWJAIL)) && - ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || - (error = VOP_ACCESS(vp, VWRITE, ap->a_cred, ap->a_td)))) - return (error); + if (vap->va_vaflags & VA_UTIMES_NULL) { + error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td); + if (error) + error = VOP_ACCESS(vp, VWRITE, ap->a_cred, + ap->a_td); + } else + error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td); #if 0 if (mtime == NULL) mtime = &np->n_mtime; Index: sys/fs/udf/udf_vfsops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/udf/udf_vfsops.c,v retrieving revision 1.44 diff -u -r1.44 udf_vfsops.c --- sys/fs/udf/udf_vfsops.c 26 Sep 2006 04:12:46 -0000 1.44 +++ sys/fs/udf/udf_vfsops.c 30 Oct 2006 17:07:55 -0000 @@ -84,6 +84,7 @@ #include #include #include +#include #include #include #include @@ -238,7 +239,7 @@ /* Check the access rights on the mount device */ error = VOP_ACCESS(devvp, VREAD, td->td_ucred, td); if (error) - error = suser(td); + error = priv_check(td, PRIV_VFS_MOUNT_PERM); if (error) { vput(devvp); return (error); Index: sys/fs/umapfs/umap_vfsops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/umapfs/umap_vfsops.c,v retrieving revision 1.65 diff -u -r1.65 umap_vfsops.c --- sys/fs/umapfs/umap_vfsops.c 26 Sep 2006 04:12:46 -0000 1.65 +++ sys/fs/umapfs/umap_vfsops.c 30 Oct 2006 17:07:55 -0000 @@ -88,8 +88,9 @@ /* * Only for root */ - if ((error = suser(td)) != 0) - return (error); + error = priv_check(td, PRIV_VFS_MOUNT); + if (error) + return (ERROR); #ifdef DEBUG printf("umapfs_mount(mp = %p)\n", (void *)mp); Index: sys/gnu/fs/ext2fs/ext2_vfsops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/gnu/fs/ext2fs/ext2_vfsops.c,v retrieving revision 1.158 diff -u -r1.158 ext2_vfsops.c --- sys/gnu/fs/ext2fs/ext2_vfsops.c 26 Sep 2006 04:12:47 -0000 1.158 +++ sys/gnu/fs/ext2fs/ext2_vfsops.c 30 Oct 2006 17:07:55 -0000 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -197,15 +198,16 @@ * If upgrade to read-write by non-root, then verify * that user has necessary permissions on the device. */ - if (suser(td)) { - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); - if ((error = VOP_ACCESS(devvp, VREAD | VWRITE, - td->td_ucred, td)) != 0) { - VOP_UNLOCK(devvp, 0, td); - return (error); - } + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); + error = VOP_ACCESS(devvp, VREAD | VWRITE, + td->td_ucred, td); + if (error) + error = priv_check(td, PRIV_VFS_MOUNT_PERM); + if (error) { VOP_UNLOCK(devvp, 0, td); + return (error); } + VOP_UNLOCK(devvp, 0, td); DROP_GIANT(); g_topology_lock(); error = g_access(ump->um_cp, 0, 1, 0); @@ -259,15 +261,18 @@ /* * If mount by non-root, then verify that user has necessary * permissions on the device. + * + * XXXRW: VOP_ACCESS() enough? */ - if (suser(td)) { - accessmode = VREAD; - if ((mp->mnt_flag & MNT_RDONLY) == 0) - accessmode |= VWRITE; - if ((error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td)) != 0) { - vput(devvp); - return (error); - } + accessmode = VREAD; + if ((mp->mnt_flag & MNT_RDONLY) == 0) + accessmode |= VWRITE; + error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td); + if (error) + error = priv_check(td, PRIV_VFS_MOUNT_PERM); + if (error) { + vput(devvp); + return (error); } if ((mp->mnt_flag & MNT_UPDATE) == 0) { Index: sys/gnu/fs/ext2fs/ext2_vnops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/gnu/fs/ext2fs/ext2_vnops.c,v retrieving revision 1.105 diff -u -r1.105 ext2_vnops.c --- sys/gnu/fs/ext2fs/ext2_vnops.c 29 Dec 2005 21:34:49 -0000 1.105 +++ sys/gnu/fs/ext2fs/ext2_vnops.c 30 Oct 2006 17:07:55 -0000 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -411,7 +412,8 @@ * Privileged non-jail processes may not modify system flags * if securelevel > 0 and any existing system flags are set. */ - if (!suser_cred(cred, SUSER_ALLOWJAIL)) { + if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS, + SUSER_ALLOWJAIL)) { if (ip->i_flags & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) { error = securelevel_gt(cred, 0); @@ -529,11 +531,17 @@ * as well as set the setgid bit on a file with a group that the * process is not a member of. */ - if (suser_cred(cred, SUSER_ALLOWJAIL)) { - if (vp->v_type != VDIR && (mode & S_ISTXT)) + if (vp->v_type != VDIR && (mode & S_ISTXT)) { + error = priv_check_cred(cred, PRIV_VFS_STICKYFILE, + SUSER_ALLOWJAIL); + if (error) return (EFTYPE); - if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) - return (EPERM); + } + if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) { + error = priv_check_cred(cred, PRIV_VFS_SETGID, + SUSER_ALLOWJAIL); + if (error) + return (error); } ip->i_mode &= ~ALLPERMS; ip->i_mode |= (mode & ALLPERMS); @@ -573,17 +581,23 @@ * to a group of which we are not a member, the caller must * have privilege. */ - if ((uid != ip->i_uid || - (gid != ip->i_gid && !groupmember(gid, cred))) && - (error = suser_cred(cred, SUSER_ALLOWJAIL))) - return (error); + if (uid != ip->i_uid || (gid != ip->i_gid && + !groupmember(gid, cred))) { + error = priv_check_cred(cred, PRIV_VFS_CHOWN, + SUSER_ALLOWJAIL); + if (error) + return (error); + } ogid = ip->i_gid; ouid = ip->i_uid; ip->i_gid = gid; ip->i_uid = uid; ip->i_flag |= IN_CHANGE; - if (suser_cred(cred, SUSER_ALLOWJAIL) && (ouid != uid || ogid != gid)) - ip->i_mode &= ~(ISUID | ISGID); + if (ouid != uid || ogid != gid) { + if (priv_check_cred(cred, PRIV_VFS_CLEARSUGID, + SUSER_ALLOWJAIL) != 0) + ip->i_mode &= ~(ISUID | ISGID); + } return (0); } @@ -1608,9 +1622,11 @@ ip->i_mode = mode; tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ ip->i_nlink = 1; - if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) && - suser_cred(cnp->cn_cred, SUSER_ALLOWJAIL)) - ip->i_mode &= ~ISGID; + if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred)) { + if (priv_check_cred(cnp->cn_cred, PRIV_VFS_CLEARSUGID, + SUSER_ALLOWJAIL)) + ip->i_mode &= ~ISGID; + } if (cnp->cn_flags & ISWHITEOUT) ip->i_flags |= UF_OPAQUE; Index: sys/gnu/fs/reiserfs/reiserfs_fs.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/gnu/fs/reiserfs/reiserfs_fs.h,v retrieving revision 1.4 diff -u -r1.4 reiserfs_fs.h --- sys/gnu/fs/reiserfs/reiserfs_fs.h 4 Dec 2005 09:57:09 -0000 1.4 +++ sys/gnu/fs/reiserfs/reiserfs_fs.h 30 Oct 2006 17:07:55 -0000 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include Index: sys/gnu/fs/reiserfs/reiserfs_vfsops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/gnu/fs/reiserfs/reiserfs_vfsops.c,v retrieving revision 1.6 diff -u -r1.6 reiserfs_vfsops.c --- sys/gnu/fs/reiserfs/reiserfs_vfsops.c 26 Sep 2006 04:12:47 -0000 1.6 +++ sys/gnu/fs/reiserfs/reiserfs_vfsops.c 30 Oct 2006 17:07:55 -0000 @@ -125,15 +125,15 @@ /* If mount by non-root, then verify that user has necessary * permissions on the device. */ - if (suser(td)) { - accessmode = VREAD; - if ((mp->mnt_flag & MNT_RDONLY) == 0) - accessmode |= VWRITE; - if ((error = VOP_ACCESS(devvp, - accessmode, td->td_ucred, td)) != 0) { - vput(devvp); - return (error); - } + accessmode = VREAD; + if ((mp->mnt_flag & MNT_RDONLY) == 0) + accessmode |= VWRITE; + error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td); + if (error) + error = priv_check(td, PRIV_VFS_MOUNT_PERM); + if (error) { + vput(devvp); + return (error); } if ((mp->mnt_flag & MNT_UPDATE) == 0) { Index: sys/gnu/fs/xfs/FreeBSD/xfs_super.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/gnu/fs/xfs/FreeBSD/xfs_super.c,v retrieving revision 1.4 diff -u -r1.4 xfs_super.c --- sys/gnu/fs/xfs/FreeBSD/xfs_super.c 10 Jun 2006 19:02:13 -0000 1.4 +++ sys/gnu/fs/xfs/FreeBSD/xfs_super.c 30 Oct 2006 17:07:55 -0000 @@ -53,6 +53,8 @@ #include "xfs_version.h" #include "xfs_buf.h" +#include + #include #include @@ -149,14 +151,15 @@ vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); ronly = ((XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) != 0); - if (suser(td)) { - accessmode = VREAD; - if (!ronly) - accessmode |= VWRITE; - if ((error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td))!= 0){ - vput(devvp); - return (error); - } + accessmode = VREAD; + if (!ronly) + accessmode |= VWRITE; + error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td); + if (error) + error = priv_check(td, PRIV_VFS_MOUNT_PERM); + if (error) { + vput(devvp); + return (error); } DROP_GIANT(); Index: sys/i386/i386/io.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/i386/io.c,v retrieving revision 1.1 diff -u -r1.1 io.c --- sys/i386/i386/io.c 1 Aug 2004 11:40:52 -0000 1.1 +++ sys/i386/i386/io.c 30 Oct 2006 17:07:55 -0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +55,7 @@ { int error; - error = suser(td); + error = priv_check(td, PRIV_IO); if (error != 0) return (error); error = securelevel_gt(td->td_ucred, 0); Index: sys/i386/i386/sys_machdep.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/i386/sys_machdep.c,v retrieving revision 1.106 diff -u -r1.106 sys_machdep.c --- sys/i386/i386/sys_machdep.c 22 Oct 2006 11:52:12 -0000 1.106 +++ sys/i386/i386/sys_machdep.c 30 Oct 2006 17:07:55 -0000 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -292,7 +293,7 @@ if ((error = mac_check_sysarch_ioperm(td->td_ucred)) != 0) return (error); #endif - if ((error = suser(td)) != 0) + if ((error = priv_check(td, PRIV_IO)) != 0) return (error); if ((error = securelevel_gt(td->td_ucred, 0)) != 0) return (error); Index: sys/i386/i386/vm86.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/i386/vm86.c,v retrieving revision 1.59 diff -u -r1.59 vm86.c --- sys/i386/i386/vm86.c 28 Sep 2005 07:03:03 -0000 1.59 +++ sys/i386/i386/vm86.c 30 Oct 2006 17:07:55 -0000 @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -724,7 +725,7 @@ case VM86_INTCALL: { struct vm86_intcall_args sa; - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_VM86_INTCALL))) return (error); if ((error = copyin(ua.sub_args, &sa, sizeof(sa)))) return (error); Index: sys/i386/ibcs2/ibcs2_misc.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/ibcs2/ibcs2_misc.c,v retrieving revision 1.65 diff -u -r1.65 ibcs2_misc.c --- sys/i386/ibcs2/ibcs2_misc.c 22 Oct 2006 11:52:12 -0000 1.65 +++ sys/i386/ibcs2/ibcs2_misc.c 30 Oct 2006 17:07:55 -0000 @@ -68,6 +68,7 @@ #include #include /* Must come after sys/malloc.h */ #include +#include #include #include #include @@ -1008,14 +1009,22 @@ #define IBCS2_DATALOCK 4 - if ((error = suser(td)) != 0) - return EPERM; switch(uap->cmd) { case IBCS2_UNLOCK: + error = priv_check(td, PRIV_VM_MUNLOCK); + if (error) + return (error); + /* XXX - TODO */ + return (0); + case IBCS2_PROCLOCK: case IBCS2_TEXTLOCK: case IBCS2_DATALOCK: - return 0; /* XXX - TODO */ + error = priv_check(td, PRIV_VM_MLOCK); + if (error) + return (error); + /* XXX - TODO */ + return 0; } return EINVAL; } @@ -1043,9 +1052,6 @@ #define SCO_AD_GETBMAJ 0 #define SCO_AD_GETCMAJ 1 - if (suser(td)) - return EPERM; - switch(uap->cmd) { case SCO_A_REBOOT: case SCO_A_SHUTDOWN: @@ -1055,11 +1061,11 @@ case SCO_AD_PWRDOWN: case SCO_AD_PWRNAP: r.opt = RB_HALT; - reboot(td, &r); + return (reboot(td, &r)); case SCO_AD_BOOT: case SCO_AD_IBOOT: r.opt = RB_AUTOBOOT; - reboot(td, &r); + return (reboot(td, &r)); } return EINVAL; case SCO_A_REMOUNT: Index: sys/i386/ibcs2/ibcs2_socksys.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/ibcs2/ibcs2_socksys.c,v retrieving revision 1.21 diff -u -r1.21 ibcs2_socksys.c --- sys/i386/ibcs2/ibcs2_socksys.c 6 Jan 2005 23:22:04 -0000 1.21 +++ sys/i386/ibcs2/ibcs2_socksys.c 30 Oct 2006 17:07:55 -0000 @@ -174,9 +174,6 @@ char hname[MAXHOSTNAMELEN], *ptr; int error, sctl[2], hlen; - if ((error = suser(td))) - return (error); - /* W/out a hostname a domain-name is nonsense */ if ( strlen(hostname) == 0 ) return EINVAL; Index: sys/i386/ibcs2/ibcs2_sysi86.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/ibcs2/ibcs2_sysi86.c,v retrieving revision 1.22 diff -u -r1.22 ibcs2_sysi86.c --- sys/i386/ibcs2/ibcs2_sysi86.c 7 Jul 2005 19:30:30 -0000 1.22 +++ sys/i386/ibcs2/ibcs2_sysi86.c 30 Oct 2006 17:07:55 -0000 @@ -76,8 +76,6 @@ int name[2]; int error; - if ((error = suser(td))) - return (error); name[0] = CTL_KERN; name[1] = KERN_HOSTNAME; mtx_lock(&Giant); Index: sys/i386/linux/linux_machdep.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i386/linux/linux_machdep.c,v retrieving revision 1.63 diff -u -r1.63 linux_machdep.c --- sys/i386/linux/linux_machdep.c 20 Oct 2006 10:09:40 -0000 1.63 +++ sys/i386/linux/linux_machdep.c 30 Oct 2006 17:07:55 -0000 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -812,7 +813,7 @@ if (args->level < 0 || args->level > 3) return (EINVAL); - if ((error = suser(td)) != 0) + if ((error = priv_check(td, PRIV_IO)) != 0) return (error); if ((error = securelevel_gt(td->td_ucred, 0)) != 0) return (error); Index: sys/i4b/driver/i4b_ipr.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/i4b/driver/i4b_ipr.c,v retrieving revision 1.35 diff -u -r1.35 i4b_ipr.c --- sys/i4b/driver/i4b_ipr.c 9 Aug 2005 10:19:57 -0000 1.35 +++ sys/i4b/driver/i4b_ipr.c 30 Oct 2006 17:07:55 -0000 @@ -490,7 +490,7 @@ { struct thread *td = curthread; /* XXX */ - if((error = suser(td))) + if((error = priv_check(td, PRIV_DRIVER))) return (error); sl_compress_setup(sc->sc_compr, *(int *)data); } Index: sys/ia64/ia64/ssc.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ia64/ia64/ssc.c,v retrieving revision 1.28 diff -u -r1.28 ssc.c --- sys/ia64/ia64/ssc.c 27 May 2006 17:52:08 -0000 1.28 +++ sys/ia64/ia64/ssc.c 30 Oct 2006 17:07:55 -0000 @@ -147,7 +147,8 @@ ttyconsolemode(tp, 0); setuptimeout = 1; - } else if ((tp->t_state & TS_XCLUDE) && suser(td)) { + } else if ((tp->t_state & TS_XCLUDE) && + priv_check(td, PRIV_TTY_EXCLUSIVE)) { splx(s); return EBUSY; } Index: sys/isofs/cd9660/cd9660_vfsops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/isofs/cd9660/cd9660_vfsops.c,v retrieving revision 1.146 diff -u -r1.146 cd9660_vfsops.c --- sys/isofs/cd9660/cd9660_vfsops.c 26 Sep 2006 04:12:47 -0000 1.146 +++ sys/isofs/cd9660/cd9660_vfsops.c 30 Oct 2006 17:07:55 -0000 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -174,7 +175,7 @@ vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td); if (error) - error = suser(td); + error = priv_check(td, PRIV_VFS_MOUNT_PERM); if (error) { vput(devvp); return (error); Index: sys/kern/kern_acct.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_acct.c,v retrieving revision 1.84 diff -u -r1.84 kern_acct.c --- sys/kern/kern_acct.c 22 Oct 2006 11:52:12 -0000 1.84 +++ sys/kern/kern_acct.c 30 Oct 2006 17:07:55 -0000 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -166,8 +167,7 @@ struct nameidata nd; int error, flags, vfslocked; - /* Make sure that the caller is root. */ - error = suser(td); + error = priv_check(td, PRIV_ACCT); if (error) return (error); Index: sys/kern/kern_descrip.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_descrip.c,v retrieving revision 1.298 diff -u -r1.298 kern_descrip.c --- sys/kern/kern_descrip.c 24 Sep 2006 02:29:53 -0000 1.298 +++ sys/kern/kern_descrip.c 30 Oct 2006 17:07:55 -0000 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -1351,8 +1352,8 @@ sx_xlock(&filelist_lock); if ((openfiles >= maxuserfiles && - suser_cred(td->td_ucred, SUSER_RUID) != 0) || - openfiles >= maxfiles) { + priv_check_cred(td->td_ucred, PRIV_MAXFILES, SUSER_RUID) != 0) + || openfiles >= maxfiles) { if (ppsratecheck(&lastfail, &curfail, 1)) { printf("kern.maxfiles limit exceeded by uid %i, please see tuning(7).\n", td->td_ucred->cr_ruid); Index: sys/kern/kern_environment.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_environment.c,v retrieving revision 1.45 diff -u -r1.45 kern_environment.c --- sys/kern/kern_environment.c 22 Oct 2006 11:52:12 -0000 1.45 +++ sys/kern/kern_environment.c 30 Oct 2006 17:07:55 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -125,11 +126,18 @@ return (error); } - if ((uap->what == KENV_SET) || - (uap->what == KENV_UNSET)) { - error = suser(td); + switch (uap->what) { + case KENV_SET: + error = priv_check(td, PRIV_KENV_SET); + if (error) + return (error); + break; + + case KENV_UNSET: + error = priv_check(td, PRIV_KENV_UNSET); if (error) return (error); + break; } name = malloc(KENV_MNAMELEN, M_TEMP, M_WAITOK); Index: sys/kern/kern_exec.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_exec.c,v retrieving revision 1.298 diff -u -r1.298 kern_exec.c --- sys/kern/kern_exec.c 22 Oct 2006 21:18:47 -0000 1.298 +++ sys/kern/kern_exec.c 31 Oct 2006 08:28:07 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -571,8 +572,11 @@ * we do not regain any tracing during a possible block. */ setsugid(p); + #ifdef KTRACE - if (p->p_tracevp != NULL && suser_cred(oldcred, SUSER_ALLOWJAIL)) { + if (p->p_tracevp != NULL && + priv_check_cred(oldcred, PRIV_DEBUG_DIFFCRED, + SUSER_ALLOWJAIL)) { mtx_lock(&ktrace_mtx); p->p_traceflag = 0; tracevp = p->p_tracevp; Index: sys/kern/kern_fork.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_fork.c,v retrieving revision 1.263 diff -u -r1.263 kern_fork.c --- sys/kern/kern_fork.c 26 Oct 2006 21:42:19 -0000 1.263 +++ sys/kern/kern_fork.c 30 Oct 2006 17:07:55 -0000 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -310,7 +311,7 @@ */ sx_xlock(&allproc_lock); if ((nprocs >= maxproc - 10 && - suser_cred(td->td_ucred, SUSER_RUID) != 0) || + priv_check_cred(td->td_ucred, PRIV_MAXPROC, SUSER_RUID) != 0) || nprocs >= maxproc) { error = EAGAIN; goto fail; @@ -319,8 +320,11 @@ /* * Increment the count of procs running with this uid. Don't allow * a nonprivileged user to exceed their current limit. + * + * XXXRW: Can we avoid privilege here if it's not needed? */ - error = suser_cred(td->td_ucred, SUSER_RUID | SUSER_ALLOWJAIL); + error = priv_check_cred(td->td_ucred, PRIV_PROC_LIMIT, SUSER_RUID | + SUSER_ALLOWJAIL); if (error == 0) ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, 0); else { Index: sys/kern/kern_jail.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_jail.c,v retrieving revision 1.53 diff -u -r1.53 kern_jail.c --- sys/kern/kern_jail.c 22 Oct 2006 11:52:13 -0000 1.53 +++ sys/kern/kern_jail.c 30 Oct 2006 17:07:55 -0000 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -205,7 +206,7 @@ * a process root from one prison, but attached to the jail * of another. */ - error = suser(td); + error = priv_check(td, PRIV_JAIL_ATTACH); if (error) return (error); @@ -523,6 +524,172 @@ } } +/* + * Check with permission for a specific privilege is granted within jail. We + * have a specific list of accepted privileges; the rest are denied. + */ +int +prison_priv_check(struct ucred *cred, int priv) +{ + + if (!(jailed(cred))) + return (0); + + switch (priv) { + + /* + * Allow ktrace privileges for root in jail. + */ + case PRIV_KTRACE: + + /* + * Allow jailed processes to configure audit identity and + * submit audit records (login, etc). In the future we may + * want to further refine the relationship between audit and + * jail. + */ + case PRIV_AUDIT_GETAUDIT: + case PRIV_AUDIT_SETAUDIT: + case PRIV_AUDIT_SUBMIT: + + /* + * Allow jailed processes to manipulate process UNIX + * credentials in any way they see fit. + */ + case PRIV_CRED_SETUID: + case PRIV_CRED_SETEUID: + case PRIV_CRED_SETGID: + case PRIV_CRED_SETEGID: + case PRIV_CRED_SETGROUPS: + case PRIV_CRED_SETREUID: + case PRIV_CRED_SETREGID: + case PRIV_CRED_SETRESUID: + case PRIV_CRED_SETRESGID: + + /* + * Jail implements visibility constraints already, so allow + * jailed root to override uid/gid-based constraints. + */ + case PRIV_SEEOTHERGIDS: + case PRIV_SEEOTHERUIDS: + + /* + * Jail implements inter-process debugging limits already, so + * allow jailed root various debugging privileges. + */ + case PRIV_DEBUG_DIFFCRED: + case PRIV_DEBUG_SUGID: + case PRIV_DEBUG_UNPRIV: + + /* + * Allow jail to set various resource limits and login + * properties, and for now, exceed process resource limits. + */ + case PRIV_PROC_LIMIT: + case PRIV_PROC_SETLOGIN: + case PRIV_PROC_SETRLIMIT: + + /* + * System V and POSIX IPC privileges are granted in jail. + */ + case PRIV_IPC_READ: + case PRIV_IPC_WRITE: + case PRIV_IPC_EXEC: + case PRIV_IPC_ADMIN: + case PRIV_IPC_MSGSIZE: + case PRIV_MQ_ADMIN: + + /* + * Jail implements its own inter-process limits, so allow + * root processes in jail to change scheduling on other + * processes in the same jail. Likewise for signalling. + */ + case PRIV_SCHED_DIFFCRED: + case PRIV_SIGNAL_DIFFCRED: + case PRIV_SIGNAL_SUGID: + + /* + * Allow jailed processes to write to sysctls marked as jail + * writable. + */ + case PRIV_SYSCTL_WRITEJAIL: + + /* + * Allow root in jail to manage a variety of quota + * properties. Some are a bit surprising and should be + * reconsidered. + */ + case PRIV_UFS_GETQUOTA: + case PRIV_UFS_QUOTAOFF: /* XXXRW: Slightly surprising. */ + case PRIV_UFS_QUOTAON: /* XXXRW: Slightly surprising. */ + case PRIV_UFS_SETQUOTA: + case PRIV_UFS_SETUSE: /* XXXRW: Slightly surprising. */ + + /* + * Since Jail relies on chroot() to implement file system + * protections, grant many VFS privileges to root in jail. + * Be careful to exclude mount-related and NFS-related + * privileges. + */ + case PRIV_VFS_READ: + case PRIV_VFS_WRITE: + case PRIV_VFS_ADMIN: + case PRIV_VFS_EXEC: + case PRIV_VFS_LOOKUP: + case PRIV_VFS_BLOCKRESERVE: /* XXXRW: Slightly surprising. */ + case PRIV_VFS_CHFLAGS_DEV: + case PRIV_VFS_CHOWN: + case PRIV_VFS_CHROOT: + case PRIV_VFS_CLEARSUGID: + case PRIV_VFS_FCHROOT: + case PRIV_VFS_LINK: + case PRIV_VFS_SETGID: + case PRIV_VFS_STICKYFILE: + return (0); + + /* + * Depending on the global setting, allow privilege of + * setting system flags. + */ + case PRIV_VFS_SYSFLAGS: + if (jail_chflags_allowed) + return (0); + else + return (EPERM); + + /* + * Allow jailed root to bind reserved ports. + */ + case PRIV_NETINET_RESERVEDPORT: + return (0); + + /* + * Conditionally allow creating raw sockets in jail. + */ + case PRIV_NETINET_RAW: + if (jail_allow_raw_sockets) + return (0); + else + return (EPERM); + + /* + * Since jail implements its own visibility limits on netstat + * sysctls, allow getcred. This allows identd to work in + * jail. + */ + case PRIV_NETINET_GETCRED: + return (0); + + default: + /* + * In all remaining cases, deny the privilege request. This + * includes almost all network privileges, many system + * configuration privileges. + */ + return (EPERM); + } +} + static int sysctl_jail_list(SYSCTL_HANDLER_ARGS) { Index: sys/kern/kern_ktrace.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_ktrace.c,v retrieving revision 1.111 diff -u -r1.111 kern_ktrace.c --- sys/kern/kern_ktrace.c 22 Oct 2006 11:52:13 -0000 1.111 +++ sys/kern/kern_ktrace.c 30 Oct 2006 17:07:55 -0000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -807,7 +808,8 @@ p->p_tracecred = crhold(td->td_ucred); } p->p_traceflag |= facs; - if (suser_cred(td->td_ucred, SUSER_ALLOWJAIL) == 0) + if (priv_check_cred(td->td_ucred, PRIV_KTRACE, + SUSER_ALLOWJAIL) == 0) p->p_traceflag |= KTRFAC_ROOT; } else { /* KTROP_CLEAR */ @@ -1013,7 +1015,7 @@ PROC_LOCK_ASSERT(targetp, MA_OWNED); if (targetp->p_traceflag & KTRFAC_ROOT && - suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) + priv_check_cred(td->td_ucred, PRIV_KTRACE, SUSER_ALLOWJAIL)) return (0); if (p_candebug(td, targetp) != 0) Index: sys/kern/kern_linker.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_linker.c,v retrieving revision 1.143 diff -u -r1.143 kern_linker.c --- sys/kern/kern_linker.c 22 Oct 2006 11:52:13 -0000 1.143 +++ sys/kern/kern_linker.c 30 Oct 2006 17:07:55 -0000 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -854,7 +855,7 @@ if ((error = securelevel_gt(td->td_ucred, 0)) != 0) return (error); - if ((error = suser(td)) != 0) + if ((error = priv_check(td, PRIV_KLD_LOAD)) != 0) return (error); /* @@ -921,7 +922,7 @@ if ((error = securelevel_gt(td->td_ucred, 0)) != 0) return (error); - if ((error = suser(td)) != 0) + if ((error = priv_check(td, PRIV_KLD_UNLOAD)) != 0) return (error); KLD_LOCK(); Index: sys/kern/kern_ntptime.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_ntptime.c,v retrieving revision 1.59 diff -u -r1.59 kern_ntptime.c --- sys/kern/kern_ntptime.c 28 May 2005 14:34:41 -0000 1.59 +++ sys/kern/kern_ntptime.c 30 Oct 2006 17:07:55 -0000 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -333,7 +334,7 @@ mtx_lock(&Giant); modes = ntv.modes; if (modes) - error = suser(td); + error = priv_check(td, PRIV_NTP_ADJTIME); if (error) goto done2; s = splclock(); @@ -954,7 +955,7 @@ struct timeval atv; int error; - if ((error = suser(td))) + if ((error = priv_check(td, PRIV_ADJTIME))) return (error); mtx_lock(&Giant); Index: sys/kern/kern_priv.c =================================================================== RCS file: sys/kern/kern_priv.c diff -N sys/kern/kern_priv.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/kern/kern_priv.c 31 Oct 2006 08:22:47 -0000 @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 2006 nCircle Network Security, Inc. + * All rights reserved. + * + * This software was developed by Robert N. M. Watson for the TrustedBSD + * Project under contract to nCircle Network Security, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY, + * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include "opt_mac.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * `suser_enabled' (which can be set by the security.bsd.suser_enabled + * sysctl) determines whether the system 'super-user' policy is in effect. If + * it is nonzero, an effective uid of 0 connotes special privilege, + * overriding many mandatory and discretionary protections. If it is zero, + * uid 0 is offered no special privilege in the kernel security policy. + * Setting it to zero may seriously impact the functionality of many existing + * userland programs, and should not be done without careful consideration of + * the consequences. + */ +int suser_enabled = 1; +SYSCTL_INT(_security_bsd, OID_AUTO, suser_enabled, CTLFLAG_RW, + &suser_enabled, 0, "processes with uid 0 have privilege"); +TUNABLE_INT("security.bsd.suser_enabled", &suser_enabled); + +/* + * Check a credential for privilege. Lots of good reasons to deny privilege; + * only a few to grant it. + */ +int +priv_check_cred(struct ucred *cred, int priv, int flags) +{ + int error; + + KASSERT(PRIV_VALID(priv), ("priv_check_cred: invalid privilege %d", + priv)); + +#ifdef MAC + error = mac_priv_check(cred, priv); + if (error) + return (error); +#endif + + /* + * Jail policy will restrict certain privileges that may otherwise be + * be granted. + * + * While debugging the transition from SUSER_ALLOWJAIL to Jail being + * aware of specific privileges, perform run-time checking that the + * two versions of the policy align. This assertion will go away + * once the SUSER_ALLOWJAIL flag has gone away. + */ + error = prison_priv_check(cred, priv); +#ifdef NOTYET + KASSERT(!jailed(cred) || error == ((flags & SUSER_ALLOWJAIL) ? 0 : + EPERM), ("priv_check_cred: prison_priv_check %d but flags %s", + error, flags & SUSER_ALLOWJAIL ? "allowjail" : "!allowjail")); +#endif + if (error) + return (error); + + /* + * Having determined if privilege is restricted by various policies, + * now determine if privilege is granted. For now, we allow + * short-circuit boolean evaluation, so may not call all policies. + * Perhaps we should. + * + * Superuser policy grants privilege based on the effective (or in + * certain edge cases, real) uid being 0. We allow the policy to be + * globally disabled, although this is currently of limited utility. + */ + if (suser_enabled) { + if (flags & SUSER_RUID) { + if (cred->cr_ruid == 0) + return (0); + } else { + if (cred->cr_uid == 0) + return (0); + } + } + + /* + * Now check with MAC, if enabled, to see if a policy module grants + * privilege. + */ +#ifdef MAC + if (mac_priv_grant(cred, priv) == 0) + return (0); +#endif + return (EPERM); +} + +int +priv_check(struct thread *td, int priv) +{ + + KASSERT(td == curthread, ("priv_check: td != curthread")); + + return (priv_check_cred(td->td_ucred, priv, 0)); +} + +/* + * Historical suser() wrapper functions, which now simply request PRIV_ROOT. + * These will be removed in the near future, and exist solely because + * the kernel and modules are not yet fully adapted to the new model. + */ +int +suser_cred(struct ucred *cred, int flags) +{ + + return (priv_check_cred(cred, PRIV_ROOT, flags)); +} + +int +suser(struct thread *td) +{ + + KASSERT(td == curthread, ("suser: td != curthread")); + + return (suser_cred(td->td_ucred, 0)); +} Index: sys/kern/kern_prot.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_prot.c,v retrieving revision 1.205 diff -u -r1.205 kern_prot.c --- sys/kern/kern_prot.c 22 Oct 2006 11:52:13 -0000 1.205 +++ sys/kern/kern_prot.c 30 Oct 2006 17:07:55 -0000 @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -547,7 +548,8 @@ #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ #endif - (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) + (error = priv_check_cred(oldcred, PRIV_CRED_SETUID, + SUSER_ALLOWJAIL)) != 0) goto fail; /* @@ -563,7 +565,8 @@ #ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ uid == oldcred->cr_uid || #endif - suser_cred(oldcred, SUSER_ALLOWJAIL) == 0) /* we are using privs */ + /* We are using privs. */ + priv_check_cred(oldcred, PRIV_CRED_SETUID, SUSER_ALLOWJAIL) == 0) #endif { /* @@ -639,7 +642,8 @@ if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ - (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) + (error = priv_check_cred(oldcred, PRIV_CRED_SETEUID, + SUSER_ALLOWJAIL)) != 0) goto fail; /* @@ -711,7 +715,8 @@ #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ #endif - (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) + (error = priv_check_cred(oldcred, PRIV_CRED_SETGID, + SUSER_ALLOWJAIL)) != 0) goto fail; crcopy(newcred, oldcred); @@ -724,7 +729,8 @@ #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ gid == oldcred->cr_groups[0] || #endif - suser_cred(oldcred, SUSER_ALLOWJAIL) == 0) /* we are using privs */ + /* We are using privs. */ + priv_check_cred(oldcred, PRIV_CRED_SETGID, SUSER_ALLOWJAIL) == 0) #endif { /* @@ -796,7 +802,8 @@ if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ - (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) + (error = priv_check_cred(oldcred, PRIV_CRED_SETEGID, + SUSER_ALLOWJAIL)) != 0) goto fail; crcopy(newcred, oldcred); @@ -859,7 +866,8 @@ goto fail; #endif - error = suser_cred(oldcred, SUSER_ALLOWJAIL); + error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, + SUSER_ALLOWJAIL); if (error) goto fail; @@ -931,7 +939,8 @@ ruid != oldcred->cr_svuid) || (euid != (uid_t)-1 && euid != oldcred->cr_uid && euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && - (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) + (error = priv_check_cred(oldcred, PRIV_CRED_SETREUID, + SUSER_ALLOWJAIL)) != 0) goto fail; crcopy(newcred, oldcred); @@ -999,7 +1008,8 @@ rgid != oldcred->cr_svgid) || (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && - (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) + (error = priv_check_cred(oldcred, PRIV_CRED_SETREGID, + SUSER_ALLOWJAIL)) != 0) goto fail; crcopy(newcred, oldcred); @@ -1079,7 +1089,8 @@ (suid != (uid_t)-1 && suid != oldcred->cr_ruid && suid != oldcred->cr_svuid && suid != oldcred->cr_uid)) && - (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) + (error = priv_check_cred(oldcred, PRIV_CRED_SETRESUID, + SUSER_ALLOWJAIL)) != 0) goto fail; crcopy(newcred, oldcred); @@ -1160,7 +1171,8 @@ (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid && sgid != oldcred->cr_svgid && sgid != oldcred->cr_groups[0])) && - (error = suser_cred(oldcred, SUSER_ALLOWJAIL)) != 0) + (error = priv_check_cred(oldcred, PRIV_CRED_SETRESGID, + SUSER_ALLOWJAIL)) != 0) goto fail; crcopy(newcred, oldcred); @@ -1324,65 +1336,14 @@ } /* - * `suser_enabled' (which can be set by the security.suser_enabled - * sysctl) determines whether the system 'super-user' policy is in effect. - * If it is nonzero, an effective uid of 0 connotes special privilege, - * overriding many mandatory and discretionary protections. If it is zero, - * uid 0 is offered no special privilege in the kernel security policy. - * Setting it to zero may seriously impact the functionality of many - * existing userland programs, and should not be done without careful - * consideration of the consequences. - */ -int suser_enabled = 1; -SYSCTL_INT(_security_bsd, OID_AUTO, suser_enabled, CTLFLAG_RW, - &suser_enabled, 0, "processes with uid 0 have privilege"); -TUNABLE_INT("security.bsd.suser_enabled", &suser_enabled); - -/* - * Test whether the specified credentials imply "super-user" privilege. - * Return 0 or EPERM. - */ -int -suser_cred(struct ucred *cred, int flag) -{ - - if (!suser_enabled) - return (EPERM); - if (((flag & SUSER_RUID) ? cred->cr_ruid : cred->cr_uid) != 0) - return (EPERM); - if (jailed(cred) && !(flag & SUSER_ALLOWJAIL)) - return (EPERM); - return (0); -} - -/* - * Shortcut to hide contents of struct td and struct proc from the - * caller, promoting binary compatibility. - */ -int -suser(struct thread *td) -{ - -#ifdef INVARIANTS - if (td != curthread) { - printf("suser: thread %p (%d %s) != curthread %p (%d %s)\n", - td, td->td_proc->p_pid, td->td_proc->p_comm, - curthread, curthread->td_proc->p_pid, - curthread->td_proc->p_comm); -#ifdef KDB - kdb_backtrace(); -#endif - } -#endif - return (suser_cred(td->td_ucred, 0)); -} - -/* * Test the active securelevel against a given level. securelevel_gt() * implements (securelevel > level). securelevel_ge() implements * (securelevel >= level). Note that the logic is inverted -- these * functions return EPERM on "success" and 0 on "failure". * + * XXXRW: Possibly since this has to do with privilege, it should move to + * kern_priv.c. + * * MPSAFE */ int @@ -1435,7 +1396,8 @@ { if (!see_other_uids && u1->cr_ruid != u2->cr_ruid) { - if (suser_cred(u1, SUSER_ALLOWJAIL) != 0) + if (priv_check_cred(u1, PRIV_SEEOTHERUIDS, SUSER_ALLOWJAIL) + != 0) return (ESRCH); } return (0); @@ -1474,7 +1436,8 @@ break; } if (!match) { - if (suser_cred(u1, SUSER_ALLOWJAIL) != 0) + if (priv_check_cred(u1, PRIV_SEEOTHERGIDS, + SUSER_ALLOWJAIL) != 0) return (ESRCH); } } @@ -1591,7 +1554,8 @@ break; default: /* Not permitted without privilege. */ - error = suser_cred(cred, SUSER_ALLOWJAIL); + error = priv_check_cred(cred, PRIV_SIGNAL_SUGID, + SUSER_ALLOWJAIL); if (error) return (error); } @@ -1606,7 +1570,8 @@ cred->cr_uid != proc->p_ucred->cr_ruid && cred->cr_uid != proc->p_ucred->cr_svuid) { /* Not permitted without privilege. */ - error = suser_cred(cred, SUSER_ALLOWJAIL); + error = priv_check_cred(cred, PRIV_SIGNAL_DIFFCRED, + SUSER_ALLOWJAIL); if (error) return (error); } @@ -1614,7 +1579,6 @@ return (0); } - /*- * Determine whether td may deliver the specified signal to p. * Returns: 0 for permitted, an errno value otherwise @@ -1683,19 +1647,14 @@ return (error); if ((error = cr_seeothergids(td->td_ucred, p->p_ucred))) return (error); - if (td->td_ucred->cr_ruid == p->p_ucred->cr_ruid) - return (0); - if (td->td_ucred->cr_uid == p->p_ucred->cr_ruid) - return (0); - if (suser_cred(td->td_ucred, SUSER_ALLOWJAIL) == 0) - return (0); - -#ifdef CAPABILITIES - if (!cap_check(NULL, td, CAP_SYS_NICE, SUSER_ALLOWJAIL)) - return (0); -#endif - - return (EPERM); + if (td->td_ucred->cr_ruid != p->p_ucred->cr_ruid && + td->td_ucred->cr_uid != p->p_ucred->cr_ruid) { + error = priv_check_cred(td->td_ucred, PRIV_SCHED_DIFFCRED, + SUSER_ALLOWJAIL); + if (error) + return (error); + } + return (0); } /* @@ -1730,7 +1689,8 @@ KASSERT(td == curthread, ("%s: td not curthread", __func__)); PROC_LOCK_ASSERT(p, MA_OWNED); if (!unprivileged_proc_debug) { - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(td->td_ucred, PRIV_DEBUG_UNPRIV, + SUSER_ALLOWJAIL); if (error) return (error); } @@ -1778,11 +1738,18 @@ /* * If p's gids aren't a subset, or the uids aren't a subset, * or the credential has changed, require appropriate privilege - * for td to debug p. For POSIX.1e capabilities, this will - * require CAP_SYS_PTRACE. + * for td to debug p. */ - if (!grpsubset || !uidsubset || credentialchanged) { - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + if (!grpsubset || !uidsubset) { + error = priv_check_cred(td->td_ucred, PRIV_DEBUG_DIFFCRED, + SUSER_ALLOWJAIL); + if (error) + return (error); + } + + if (credentialchanged) { + error = priv_check_cred(td->td_ucred, PRIV_DEBUG_SUGID, + SUSER_ALLOWJAIL); if (error) return (error); } @@ -1796,6 +1763,7 @@ /* * Can't trace a process that's currently exec'ing. + * * XXX: Note, this is not a security policy decision, it's a * basic correctness/functionality decision. Therefore, this check * should be moved to the caller's of p_candebug(). @@ -2057,7 +2025,8 @@ int error; char logintmp[MAXLOGNAME]; - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(td->td_ucred, PRIV_PROC_SETLOGIN, + SUSER_ALLOWJAIL); if (error) return (error); error = copyinstr(uap->namebuf, logintmp, sizeof(logintmp), NULL); Index: sys/kern/kern_resource.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_resource.c,v retrieving revision 1.161 diff -u -r1.161 kern_resource.c --- sys/kern/kern_resource.c 26 Oct 2006 21:42:19 -0000 1.161 +++ sys/kern/kern_resource.c 30 Oct 2006 17:07:55 -0000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -264,7 +265,7 @@ n = PRIO_MAX; if (n < PRIO_MIN) n = PRIO_MIN; - if (n < p->p_nice && suser(td) != 0) + if (n < p->p_nice && priv_check(td, PRIV_SCHED_SETPRIORITY) != 0) return (EACCES); mtx_lock_spin(&sched_lock); sched_nice(p, n); @@ -468,7 +469,7 @@ break; /* Disallow setting rtprio in most cases if not superuser. */ - if (suser(td) != 0) { + if (priv_check(td, PRIV_SCHED_RTPRIO) != 0) { /* can't set someone else's */ if (uap->pid) { error = EPERM; @@ -754,7 +755,8 @@ alimp = &oldlim->pl_rlimit[which]; if (limp->rlim_cur > alimp->rlim_max || limp->rlim_max > alimp->rlim_max) - if ((error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL))) { + if ((error = priv_check_cred(td->td_ucred, + PRIV_PROC_SETRLIMIT, SUSER_ALLOWJAIL))) { PROC_UNLOCK(p); lim_free(newlim); return (error); Index: sys/kern/kern_shutdown.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_shutdown.c,v retrieving revision 1.179 diff -u -r1.179 kern_shutdown.c --- sys/kern/kern_shutdown.c 22 Oct 2006 11:52:13 -0000 1.179 +++ sys/kern/kern_shutdown.c 30 Oct 2006 17:07:55 -0000 @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -164,7 +165,7 @@ error = mac_check_system_reboot(td->td_ucred, uap->opt); #endif if (error == 0) - error = suser(td); + error = priv_check(td, PRIV_REBOOT); if (error == 0) { mtx_lock(&Giant); boot(uap->opt); Index: sys/kern/kern_sysctl.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_sysctl.c,v retrieving revision 1.171 diff -u -r1.171 kern_sysctl.c --- sys/kern/kern_sysctl.c 22 Oct 2006 11:52:13 -0000 1.171 +++ sys/kern/kern_sysctl.c 30 Oct 2006 17:07:55 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -512,7 +513,7 @@ { int error; - error = suser(req->td); + error = priv_check(req->td, PRIV_SYSCTL_DEBUG); if (error) return (error); sysctl_sysctl_debug_dump_node(&sysctl__children, 0); @@ -1253,13 +1254,11 @@ /* Is this sysctl writable by only privileged users? */ if (req->newptr && !(oid->oid_kind & CTLFLAG_ANYBODY)) { - int flags; - if (oid->oid_kind & CTLFLAG_PRISON) - flags = SUSER_ALLOWJAIL; + error = priv_check_cred(req->td->td_ucred, + PRIV_SYSCTL_WRITEJAIL, SUSER_ALLOWJAIL); else - flags = 0; - error = suser_cred(req->td->td_ucred, flags); + error = priv_check(req->td, PRIV_SYSCTL_WRITE); if (error) return (error); } Index: sys/kern/kern_thr.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_thr.c,v retrieving revision 1.54 diff -u -r1.54 kern_thr.c --- sys/kern/kern_thr.c 26 Oct 2006 21:42:20 -0000 1.54 +++ sys/kern/kern_thr.c 30 Oct 2006 17:07:55 -0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -164,7 +165,7 @@ case RTP_PRIO_REALTIME: case RTP_PRIO_FIFO: /* Only root can set scheduler policy */ - if (suser(td) != 0) + if (priv_check(td, PRIV_SCHED_SETPOLICY) != 0) return (EPERM); if (rtp->prio > RTP_PRIO_MAX) return (EINVAL); Index: sys/kern/kern_time.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_time.c,v retrieving revision 1.134 diff -u -r1.134 kern_time.c --- sys/kern/kern_time.c 22 Oct 2006 11:52:13 -0000 1.134 +++ sys/kern/kern_time.c 30 Oct 2006 17:07:55 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -286,7 +287,7 @@ if (error) return (error); #endif - if ((error = suser(td)) != 0) + if ((error = priv_check(td, PRIV_CLOCK_SETTIME)) != 0) return (error); if (clock_id != CLOCK_REALTIME) return (EINVAL); @@ -504,7 +505,7 @@ if (error) return (error); #endif - error = suser(td); + error = priv_check(td, PRIV_SETTIMEOFDAY); if (error) return (error); /* Verify all parameters before changing time. */ Index: sys/kern/kern_umtx.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_umtx.c,v retrieving revision 1.53 diff -u -r1.53 kern_umtx.c --- sys/kern/kern_umtx.c 26 Oct 2006 21:42:20 -0000 1.53 +++ sys/kern/kern_umtx.c 30 Oct 2006 17:07:55 -0000 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -1813,7 +1814,7 @@ if ((error = umtx_key_get(m, TYPE_PP_UMUTEX, GET_SHARE(flags), &uq->uq_key)) != 0) return (error); - su = (suser(td) == 0); + su = (priv_check(td, PRIV_SCHED_RTPRIO) == 0); for (;;) { old_inherited_pri = uq->uq_inherited_pri; umtxq_lock(&uq->uq_key); @@ -1934,7 +1935,7 @@ id = td->td_tid; uq = td->td_umtxq; - su = (suser(td) == 0); + su = (priv_check(td, PRIV_SCHED_RTPRIO) == 0); /* * Make sure we own this mtx. Index: sys/kern/kern_xxx.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/kern_xxx.c,v retrieving revision 1.46 diff -u -r1.46 kern_xxx.c --- sys/kern/kern_xxx.c 6 Jan 2005 23:35:39 -0000 1.46 +++ sys/kern/kern_xxx.c 30 Oct 2006 17:07:55 -0000 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -139,7 +140,8 @@ { int error; - if ((error = suser(td))) + error = priv_check(td, PRIV_SETHOSTID); + if (error) return (error); mtx_lock(&Giant); hostid = uap->hostid; @@ -295,9 +297,10 @@ { int error, domainnamelen; + error = priv_check(td, PRIV_SETDOMAINNAME); + if (error) + return (error); mtx_lock(&Giant); - if ((error = suser(td))) - goto done2; if ((u_int)uap->len > sizeof (domainname) - 1) { error = EINVAL; goto done2; @@ -309,4 +312,3 @@ mtx_unlock(&Giant); return (error); } - Index: sys/kern/subr_acl_posix1e.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/subr_acl_posix1e.c,v retrieving revision 1.50 diff -u -r1.50 subr_acl_posix1e.c --- sys/kern/subr_acl_posix1e.c 23 Jul 2006 19:35:10 -0000 1.50 +++ sys/kern/subr_acl_posix1e.c 31 Oct 2006 08:30:24 -0000 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -46,9 +47,9 @@ /* * Implement a version of vaccess() that understands POSIX.1e ACL semantics; - * the access ACL has already been prepared for evaluation by the file - * system and is passed via 'uid', 'gid', and 'acl'. Return 0 on success, - * else an errno value. + * the access ACL has already been prepared for evaluation by the file system + * and is passed via 'uid', 'gid', and 'acl'. Return 0 on success, else an + * errno value. */ int vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid, @@ -56,14 +57,14 @@ { struct acl_entry *acl_other, *acl_mask; mode_t dac_granted; - mode_t cap_granted; + mode_t priv_granted; mode_t acl_mask_granted; int group_matched, i; /* * Look for a normal, non-privileged way to access the file/directory * as requested. If it exists, go with that. Otherwise, attempt to - * use privileges granted via cap_granted. In some cases, which + * use privileges granted via priv_granted. In some cases, which * privileges to use may be ambiguous due to "best match", in which * case fall back on first match for the time being. */ @@ -72,40 +73,34 @@ /* * Determine privileges now, but don't apply until we've found a DAC - * entry that matches but has failed to allow access. POSIX.1e - * capabilities are not implemented, but we document how they would - * behave here if implemented. - */ -#ifndef CAPABILITIES - if (suser_cred(cred, SUSER_ALLOWJAIL) == 0) - cap_granted = VALLPERM; - else - cap_granted = 0; -#else - cap_granted = 0; + * entry that matches but has failed to allow access. + * + * XXXRW: Ideally, we'd determine the privileges required before + * asking for them. + */ + priv_granted = 0; if (type == VDIR) { - if ((acc_mode & VEXEC) && !cap_check(cred, NULL, - CAP_DAC_READ_SEARCH, SUSER_ALLOWJAIL)) - cap_granted |= VEXEC; + if ((acc_mode & VEXEC) && !priv_check_cred(cred, + PRIV_VFS_LOOKUP, SUSER_ALLOWJAIL)) + priv_granted |= VEXEC; } else { - if ((acc_mode & VEXEC) && !cap_check(cred, NULL, - CAP_DAC_EXECUTE, SUSER_ALLOWJAIL)) - cap_granted |= VEXEC; + if ((acc_mode & VEXEC) && !priv_check_cred(cred, + PRIV_VFS_EXEC, SUSER_ALLOWJAIL)) + priv_granted |= VEXEC; } - if ((acc_mode & VREAD) && !cap_check(cred, NULL, CAP_DAC_READ_SEARCH, + if ((acc_mode & VREAD) && !priv_check_cred(cred, PRIV_VFS_READ, SUSER_ALLOWJAIL)) - cap_granted |= VREAD; + priv_granted |= VREAD; if (((acc_mode & VWRITE) || (acc_mode & VAPPEND)) && - !cap_check(cred, NULL, CAP_DAC_WRITE, SUSER_ALLOWJAIL)) - cap_granted |= (VWRITE | VAPPEND); + !priv_check_cred(cred, PRIV_VFS_WRITE, SUSER_ALLOWJAIL)) + priv_granted |= (VWRITE | VAPPEND); - if ((acc_mode & VADMIN) && !cap_check(cred, NULL, CAP_FOWNER, + if ((acc_mode & VADMIN) && !priv_check_cred(cred, PRIV_VFS_ADMIN, SUSER_ALLOWJAIL)) - cap_granted |= VADMIN; -#endif /* CAPABILITIES */ + priv_granted |= VADMIN; /* * The owner matches if the effective uid associated with the @@ -129,7 +124,11 @@ dac_granted |= (VWRITE | VAPPEND); if ((acc_mode & dac_granted) == acc_mode) return (0); - if ((acc_mode & (dac_granted | cap_granted)) == + + /* + * XXXRW: Do privilege lookup here. + */ + if ((acc_mode & (dac_granted | priv_granted)) == acc_mode) { if (privused != NULL) *privused = 1; @@ -183,13 +182,9 @@ acl_mask_granted = VEXEC | VREAD | VWRITE | VAPPEND; /* - * Iterate through user ACL entries. Do checks twice, first without - * privilege, and then if a match is found but failed, a second time - * with privilege. - */ - - /* - * Check ACL_USER ACL entries. + * Check ACL_USER ACL entries. There will either be one or no + * matches; if there is one, we accept or rejected based on the + * match; otherwise, we continue on to groups. */ for (i = 0; i < acl->acl_cnt; i++) { switch (acl->acl_entry[i].ae_tag) { @@ -206,7 +201,10 @@ dac_granted &= acl_mask_granted; if ((acc_mode & dac_granted) == acc_mode) return (0); - if ((acc_mode & (dac_granted | cap_granted)) != + /* + * XXXRW: Do privilege lookup here. + */ + if ((acc_mode & (dac_granted | priv_granted)) != acc_mode) goto error; @@ -286,8 +284,11 @@ dac_granted |= (VWRITE | VAPPEND); dac_granted &= acl_mask_granted; - if ((acc_mode & (dac_granted | cap_granted)) != - acc_mode) + /* + * XXXRW: Do privilege lookup here. + */ + if ((acc_mode & (dac_granted | priv_granted)) + != acc_mode) break; if (privused != NULL) @@ -307,8 +308,11 @@ dac_granted |= (VWRITE | VAPPEND); dac_granted &= acl_mask_granted; - if ((acc_mode & (dac_granted | cap_granted)) != - acc_mode) + /* + * XXXRW: Do privilege lookup here. + */ + if ((acc_mode & (dac_granted | priv_granted)) + != acc_mode) break; if (privused != NULL) @@ -339,7 +343,10 @@ if ((acc_mode & dac_granted) == acc_mode) return (0); - if ((acc_mode & (dac_granted | cap_granted)) == acc_mode) { + /* + * XXXRW: Do privilege lookup here. + */ + if ((acc_mode & (dac_granted | priv_granted)) == acc_mode) { if (privused != NULL) *privused = 1; return (0); Index: sys/kern/subr_firmware.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/subr_firmware.c,v retrieving revision 1.5 diff -u -r1.5 subr_firmware.c --- sys/kern/subr_firmware.c 25 Jun 2006 12:36:21 -0000 1.5 +++ sys/kern/subr_firmware.c 30 Oct 2006 17:07:55 -0000 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -190,7 +191,8 @@ return NULL; } td = curthread; - if (suser(td) != 0 || securelevel_gt(td->td_ucred, 0) != 0) { + if (priv_check(td, PRIV_FIRMWARE_LOAD) != 0 || + securelevel_gt(td->td_ucred, 0) != 0) { printf("%s: insufficient privileges to " "load firmware image %s\n", __func__, imagename); return NULL; Index: sys/kern/subr_prf.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/subr_prf.c,v retrieving revision 1.125 diff -u -r1.125 subr_prf.c --- sys/kern/subr_prf.c 17 Sep 2006 20:00:35 -0000 1.125 +++ sys/kern/subr_prf.c 30 Oct 2006 17:07:55 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -870,7 +871,7 @@ int error, len; if (!unprivileged_read_msgbuf) { - error = suser(req->td); + error = priv_check(req->td, PRIV_MSGBUF); if (error) return (error); } Index: sys/kern/subr_witness.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/subr_witness.c,v retrieving revision 1.218 diff -u -r1.218 subr_witness.c --- sys/kern/subr_witness.c 13 Sep 2006 15:48:15 -0000 1.218 +++ sys/kern/subr_witness.c 30 Oct 2006 17:07:55 -0000 @@ -95,6 +95,7 @@ #include #include #include +#include #include #include #include @@ -533,7 +534,10 @@ error = sysctl_handle_int(oidp, &value, 0, req); if (error != 0 || req->newptr == NULL) return (error); - error = suser(req->td); + /* + * XXXRW: Why a priv check here? + */ + error = priv_check(req->td, PRIV_WITNESS); if (error != 0) return (error); if (value == witness_watch) Index: sys/kern/sysv_ipc.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/sysv_ipc.c,v retrieving revision 1.29 diff -u -r1.29 sysv_ipc.c --- sys/kern/sysv_ipc.c 6 Jan 2005 23:35:39 -0000 1.29 +++ sys/kern/sysv_ipc.c 31 Oct 2006 08:31:20 -0000 @@ -1,8 +1,12 @@ /* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */ /*- * Copyright (c) 1994 Herb Peyerl + * Copyright (c) 2006 nCircle Network Security, Inc. * All rights reserved. * + * This software was developed by Robert N. M. Watson for the TrustedBSD + * Project under contract to nCircle Network Security, Inc. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -39,6 +43,7 @@ #include #include #include +#include #include #include @@ -72,50 +77,73 @@ * Note: The MAC Framework does not require any modifications to the * ipcperm() function, as access control checks are performed throughout the * implementation of each primitive. Those entry point calls complement the - * ipcperm() discertionary checks. + * ipcperm() discertionary checks. Unlike file system discretionary access + * control, the original create of an object is given the same rights as the + * current owner. */ int -ipcperm(td, perm, mode) - struct thread *td; - struct ipc_perm *perm; - int mode; +ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode) { struct ucred *cred = td->td_ucred; - int error; + int error, obj_mode, dac_granted, priv_granted; - if (cred->cr_uid != perm->cuid && cred->cr_uid != perm->uid) { - /* - * For a non-create/owner, we require privilege to - * modify the object protections. Note: some other - * implementations permit IPC_M to be delegated to - * unprivileged non-creator/owner uids/gids. - */ - if (mode & IPC_M) { - error = suser(td); - if (error) - return (error); - } - /* - * Try to match against creator/owner group; if not, fall - * back on other. - */ - mode >>= 3; - if (!groupmember(perm->gid, cred) && - !groupmember(perm->cgid, cred)) - mode >>= 3; + dac_granted = 0; + if (cred->cr_uid == perm->cuid || cred->cr_uid == perm->uid) { + obj_mode = perm->mode; + dac_granted |= IPC_M; + } else if (groupmember(perm->gid, cred) || + groupmember(perm->cgid, cred)) { + obj_mode = perm->mode; + obj_mode <<= 3; } else { - /* - * Always permit the creator/owner to update the object - * protections regardless of whether the object mode - * permits it. - */ - if (mode & IPC_M) - return (0); + obj_mode = perm->mode; + obj_mode <<= 6; + } + + /* + * While the System V IPC permission model allows IPC_M to be + * granted, as part of the mode, our implementation requires + * privilege to adminster the object if not the owner or creator. + */ +#if 0 + if (obj_mode & IPC_M) + dac_granted |= IPC_M; +#endif + if (obj_mode & IPC_R) + dac_granted |= IPC_R; + if (obj_mode & IPC_W) + dac_granted |= IPC_W; + + /* + * Simple case: all required rights are granted by DAC. + */ + if ((dac_granted & acc_mode) == acc_mode) + return (0); + + /* + * Privilege is required to satisfy the request. + */ + priv_granted = 0; + if ((acc_mode & IPC_M) && !(dac_granted & IPC_M)) { + error = priv_check(td, PRIV_IPC_ADMIN); + if (error == 0) + priv_granted |= IPC_M; } - if ((mode & perm->mode) != mode) { - if (suser(td) != 0) - return (EACCES); + if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) { + error = priv_check(td, PRIV_IPC_READ); + if (error == 0) + priv_granted |= IPC_R; } - return (0); + + if ((acc_mode & IPC_W) && !(dac_granted & IPC_W)) { + error = priv_check(td, PRIV_IPC_WRITE); + if (error == 0) + priv_granted |= IPC_W; + } + + if (((dac_granted | priv_granted) & acc_mode) == acc_mode) + return (0); + else + return (EACCES); } Index: sys/kern/sysv_msg.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/sysv_msg.c,v retrieving revision 1.63 diff -u -r1.63 sysv_msg.c --- sys/kern/sysv_msg.c 22 Oct 2006 11:52:13 -0000 1.63 +++ sys/kern/sysv_msg.c 30 Oct 2006 17:07:55 -0000 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -507,7 +508,7 @@ if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_M))) goto done2; if (msqbuf->msg_qbytes > msqkptr->u.msg_qbytes) { - error = suser(td); + error = priv_check(td, PRIV_IPC_MSGSIZE); if (error) goto done2; } Index: sys/kern/tty.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/tty.c,v retrieving revision 1.262 diff -u -r1.262 tty.c --- sys/kern/tty.c 26 Oct 2006 21:42:20 -0000 1.262 +++ sys/kern/tty.c 30 Oct 2006 17:07:55 -0000 @@ -86,6 +86,7 @@ #if defined(COMPAT_43TTY) #include #endif +#include #include #define TTYDEFCHARS #include @@ -1020,7 +1021,7 @@ break; case TIOCMSDTRWAIT: /* must be root since the wait applies to following logins */ - error = suser(td); + error = priv_check(td, PRIV_TTY_DTRWAIT); if (error) return (error); tp->t_dtr_wait = *(int *)data * hz / 100; @@ -1169,9 +1170,9 @@ splx(s); break; case TIOCSTI: /* simulate terminal input */ - if ((flag & FREAD) == 0 && suser(td)) + if ((flag & FREAD) == 0 && priv_check(td, PRIV_TTY_STI)) return (EPERM); - if (!isctty(p, tp) && suser(td)) + if (!isctty(p, tp) && priv_check(td, PRIV_TTY_STI)) return (EACCES); s = spltty(); ttyld_rint(tp, *(u_char *)data); @@ -1244,7 +1245,7 @@ } break; case TIOCSDRAINWAIT: - error = suser(td); + error = priv_check(td, PRIV_TTY_DRAINWAIT); if (error) return (error); tp->t_timeout = *(int *)data * hz; @@ -3114,7 +3115,8 @@ goto out; goto open_top; } - if (tp->t_state & TS_XCLUDE && suser(td)) + if (tp->t_state & TS_XCLUDE && priv_check(td, + PRIV_TTY_EXCLUSIVE)) return (EBUSY); } else { /* @@ -3340,7 +3342,7 @@ ct = dev->si_drv2; switch (cmd) { case TIOCSETA: - error = suser(td); + error = priv_check(td, PRIV_TTY_SETA); if (error != 0) return (error); *ct = *(struct termios *)data; Index: sys/kern/tty_cons.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/tty_cons.c,v retrieving revision 1.135 diff -u -r1.135 tty_cons.c --- sys/kern/tty_cons.c 26 May 2006 11:00:20 -0000 1.135 +++ sys/kern/tty_cons.c 30 Oct 2006 17:07:55 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -506,7 +507,7 @@ * output from the "virtual" console. */ if (cmd == TIOCCONS && constty) { - error = suser(td); + error = priv_check(td, PRIV_TTY_CONSOLE); if (error) return (error); constty = NULL; Index: sys/kern/tty_pts.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/tty_pts.c,v retrieving revision 1.10 diff -u -r1.10 tty_pts.c --- sys/kern/tty_pts.c 29 Sep 2006 09:53:19 -0000 1.10 +++ sys/kern/tty_pts.c 30 Oct 2006 17:07:55 -0000 @@ -56,6 +56,7 @@ #if defined(COMPAT_43TTY) #include #endif +#include #include #include #include @@ -268,9 +269,11 @@ tp = dev->si_tty; if ((tp->t_state & TS_ISOPEN) == 0) ttyinitmode(tp, 1, 0); - else if (tp->t_state & TS_XCLUDE && suser(td)) { + else if (tp->t_state & TS_XCLUDE && priv_check(td, + PRIV_TTY_EXCLUSIVE)) { return (EBUSY); - } else if (pt->pt_prison != td->td_ucred->cr_prison && suser(td)) { + } else if (pt->pt_prison != td->td_ucred->cr_prison && + priv_check(td, PRIV_TTY_PRISON)) { return (EBUSY); } if (tp->t_oproc) /* Ctrlr still around. */ Index: sys/kern/tty_pty.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/tty_pty.c,v retrieving revision 1.150 diff -u -r1.150 tty_pty.c --- sys/kern/tty_pty.c 4 Oct 2006 05:43:39 -0000 1.150 +++ sys/kern/tty_pty.c 30 Oct 2006 17:07:55 -0000 @@ -46,6 +46,7 @@ #if defined(COMPAT_43TTY) #include #endif +#include #include #include #include @@ -207,9 +208,11 @@ if ((tp->t_state & TS_ISOPEN) == 0) { ttyinitmode(tp, 1, 0); - } else if (tp->t_state & TS_XCLUDE && suser(td)) + } else if (tp->t_state & TS_XCLUDE && priv_check(td, + PRIV_TTY_EXCLUSIVE)) return (EBUSY); - else if (pt->pt_prison != td->td_ucred->cr_prison && suser(td)) + else if (pt->pt_prison != td->td_ucred->cr_prison && + priv_check(td, PRIV_TTY_PRISON)) return (EBUSY); if (tp->t_oproc) /* Ctrlr still around. */ (void)ttyld_modem(tp, 1); Index: sys/kern/uipc_mqueue.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/uipc_mqueue.c,v retrieving revision 1.16 diff -u -r1.16 uipc_mqueue.c --- sys/kern/uipc_mqueue.c 26 Sep 2006 04:12:47 -0000 1.16 +++ sys/kern/uipc_mqueue.c 30 Oct 2006 17:07:55 -0000 @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -955,8 +956,12 @@ sx_assert(&pn->mn_info->mi_lock, SX_LOCKED); + /* + * XXXRW: Other instances of the message queue primitive are + * allowed in jail? + */ if (ucred->cr_uid != pn->mn_uid && - (error = suser_cred(ucred, 0)) != 0) + (error = priv_check_cred(ucred, PRIV_MQ_ADMIN, 0)) != 0) error = EACCES; else if (!pn->mn_deleted) { parent = pn->mn_parent; @@ -1207,10 +1212,16 @@ */ if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td))) return (error); + + /* + * XXXRW: Why is there a privilege check here: shouldn't the + * check in VOP_ACCESS() be enough? Also, are the group bits + * below definitely right? + */ if (((ap->a_cred->cr_uid != pn->mn_uid) || uid != pn->mn_uid || (gid != pn->mn_gid && !groupmember(gid, ap->a_cred))) && - (error = suser_cred(ap->a_td->td_ucred, SUSER_ALLOWJAIL)) - != 0) + (error = priv_check_cred(ap->a_td->td_ucred, + PRIV_MQ_ADMIN, SUSER_ALLOWJAIL)) != 0) return (error); pn->mn_uid = uid; pn->mn_gid = gid; @@ -1219,7 +1230,8 @@ if (vap->va_mode != (mode_t)VNOVAL) { if ((ap->a_cred->cr_uid != pn->mn_uid) && - (error = suser_cred(ap->a_td->td_ucred, SUSER_ALLOWJAIL))) + (error = priv_check_cred(ap->a_td->td_ucred, + PRIV_MQ_ADMIN, SUSER_ALLOWJAIL))) return (error); pn->mn_mode = vap->va_mode; c = 1; Index: sys/kern/uipc_sem.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/uipc_sem.c,v retrieving revision 1.25 diff -u -r1.25 uipc_sem.c --- sys/kern/uipc_sem.c 22 Oct 2006 11:52:13 -0000 1.25 +++ sys/kern/uipc_sem.c 30 Oct 2006 17:07:55 -0000 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -419,15 +420,23 @@ { struct ucred *uc; + /* + * XXXRW: This permission routine appears to be incorrect. If the + * user matches, we shouldn't go on to the group if the user + * permissions don't allow the action? Not changed for now. To fix, + * change from a series of if (); if (); to if () else if () else... + */ uc = td->td_ucred; DP(("sem_perm: uc(%d,%d) ks(%d,%d,%o)\n", uc->cr_uid, uc->cr_gid, ks->ks_uid, ks->ks_gid, ks->ks_mode)); - if ((uc->cr_uid == ks->ks_uid && (ks->ks_mode & S_IWUSR) != 0) || - (uc->cr_gid == ks->ks_gid && (ks->ks_mode & S_IWGRP) != 0) || - (ks->ks_mode & S_IWOTH) != 0 || suser(td) == 0) + if ((uc->cr_uid == ks->ks_uid) && (ks->ks_mode & S_IWUSR) != 0) + return (0); + if ((uc->cr_gid == ks->ks_gid) && (ks->ks_mode & S_IWGRP) != 0) + return (0); + if ((ks->ks_mode & S_IWOTH) != 0) return (0); - return (EPERM); + return (priv_check(td, PRIV_SEM_WRITE)); } static void Index: sys/kern/vfs_mount.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/vfs_mount.c,v retrieving revision 1.241 diff -u -r1.241 vfs_mount.c --- sys/kern/vfs_mount.c 22 Oct 2006 11:52:14 -0000 1.241 +++ sys/kern/vfs_mount.c 30 Oct 2006 17:07:55 -0000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -808,23 +809,31 @@ if (jailed(td->td_ucred)) return (EPERM); if (usermount == 0) { - if ((error = suser(td)) != 0) + if ((error = priv_check(td, PRIV_VFS_MOUNT)) != 0) return (error); } /* * Do not allow NFS export or MNT_SUIDDIR by unprivileged users. */ - if (fsflags & (MNT_EXPORTED | MNT_SUIDDIR)) { - if ((error = suser(td)) != 0) + if (fsflags & MNT_EXPORTED) { + error = priv_check(td, PRIV_VFS_MOUNT_EXPORTED); + if (error) return (error); } + if (fsflags & MNT_SUIDDIR) { + error = priv_check(td, PRIV_VFS_MOUNT_SUIDDIR); + if (error) + return (error); + + } /* - * Silently enforce MNT_NOSUID and MNT_USER for - * unprivileged users. + * Silently enforce MNT_NOSUID and MNT_USER for unprivileged users. */ - if (suser(td) != 0) - fsflags |= MNT_NOSUID | MNT_USER; + if ((fsflags & (MNT_NOSUID | MNT_USER)) != (MNT_NOSUID | MNT_USER)) { + if (priv_check(td, PRIV_VFS_MOUNT_NONUSER) != 0) + fsflags |= MNT_NOSUID | MNT_USER; + } /* Load KLDs before we lock the covered vnode to avoid reversals. */ vfsp = NULL; @@ -906,7 +915,9 @@ return (error); } if (va.va_uid != td->td_ucred->cr_uid) { - if ((error = suser(td)) != 0) { + error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN, + SUSER_ALLOWJAIL); + if (error) { vput(vp); return (error); } @@ -1078,7 +1089,8 @@ if (jailed(td->td_ucred)) return (EPERM); if (usermount == 0) { - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_VFS_UNMOUNT); + if (error) return (error); } Index: sys/kern/vfs_subr.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/vfs_subr.c,v retrieving revision 1.686 diff -u -r1.686 vfs_subr.c --- sys/kern/vfs_subr.c 22 Oct 2006 11:52:14 -0000 1.686 +++ sys/kern/vfs_subr.c 30 Oct 2006 17:07:55 -0000 @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -412,7 +413,7 @@ if ((mp->mnt_flag & MNT_USER) == 0 || mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) { - if ((error = suser(td)) != 0) + if ((error = priv_check(td, PRIV_VFS_MOUNT_OWNER)) != 0) return (error); } return (0); @@ -3176,9 +3177,7 @@ mode_t acc_mode, struct ucred *cred, int *privused) { mode_t dac_granted; -#ifdef CAPABILITIES - mode_t cap_granted; -#endif + mode_t priv_granted; /* * Look for a normal, non-privileged way to access the file/directory @@ -3232,59 +3231,46 @@ return (0); privcheck: - if (!suser_cred(cred, SUSER_ALLOWJAIL)) { - /* XXX audit: privilege used */ - if (privused != NULL) - *privused = 1; - return (0); - } - -#ifdef CAPABILITIES /* - * Build a capability mask to determine if the set of capabilities + * Build a privilege mask to determine if the set of privileges * satisfies the requirements when combined with the granted mask - * from above. For each capability, if the capability is required, - * bitwise or the request type onto the cap_granted mask. - * - * Note: This is never actually used, but is here for reference - * purposes. + * from above. For each privilege, if the privilege is required, + * bitwise or the request type onto the priv_granted mask. */ - cap_granted = 0; + priv_granted = 0; if (type == VDIR) { /* - * For directories, use CAP_DAC_READ_SEARCH to satisfy - * VEXEC requests, instead of CAP_DAC_EXECUTE. + * For directories, use PRIV_VFS_LOOKUP to satisfy VEXEC + * requests, instead of PRIV_VFS_EXEC. */ if ((acc_mode & VEXEC) && ((dac_granted & VEXEC) == 0) && - !cap_check(cred, NULL, CAP_DAC_READ_SEARCH, - SUSER_ALLOWJAIL)) - cap_granted |= VEXEC; + !priv_check_cred(cred, PRIV_VFS_LOOKUP, SUSER_ALLOWJAIL)) + priv_granted |= VEXEC; } else { if ((acc_mode & VEXEC) && ((dac_granted & VEXEC) == 0) && - !cap_check(cred, NULL, CAP_DAC_EXECUTE, SUSER_ALLOWJAIL)) - cap_granted |= VEXEC; + !priv_check_cred(cred, PRIV_VFS_EXEC, SUSER_ALLOWJAIL)) + priv_granted |= VEXEC; } if ((acc_mode & VREAD) && ((dac_granted & VREAD) == 0) && - !cap_check(cred, NULL, CAP_DAC_READ_SEARCH, SUSER_ALLOWJAIL)) - cap_granted |= VREAD; + !priv_check_cred(cred, PRIV_VFS_READ, SUSER_ALLOWJAIL)) + priv_granted |= VREAD; if ((acc_mode & VWRITE) && ((dac_granted & VWRITE) == 0) && - !cap_check(cred, NULL, CAP_DAC_WRITE, SUSER_ALLOWJAIL)) - cap_granted |= (VWRITE | VAPPEND); + !priv_check_cred(cred, PRIV_VFS_WRITE, SUSER_ALLOWJAIL)) + priv_granted |= (VWRITE | VAPPEND); if ((acc_mode & VADMIN) && ((dac_granted & VADMIN) == 0) && - !cap_check(cred, NULL, CAP_FOWNER, SUSER_ALLOWJAIL)) - cap_granted |= VADMIN; + !priv_check_cred(cred, PRIV_VFS_ADMIN, SUSER_ALLOWJAIL)) + priv_granted |= VADMIN; - if ((acc_mode & (cap_granted | dac_granted)) == acc_mode) { + if ((acc_mode & (priv_granted | dac_granted)) == acc_mode) { /* XXX audit: privilege used */ if (privused != NULL) *privused = 1; return (0); } -#endif return ((acc_mode & VADMIN) ? EPERM : EACCES); } @@ -3305,16 +3291,13 @@ return (0); /* - * Do not allow privileged processes in jail to directly - * manipulate system attributes. - * - * XXX What capability should apply here? - * Probably CAP_SYS_SETFFLAG. + * Do not allow privileged processes in jail to directly manipulate + * system attributes. */ switch (attrnamespace) { case EXTATTR_NAMESPACE_SYSTEM: /* Potentially should be: return (EPERM); */ - return (suser_cred(cred, 0)); + return (priv_check_cred(cred, PRIV_VFS_EXTATTR_SYSTEM, 0)); case EXTATTR_NAMESPACE_USER: return (VOP_ACCESS(vp, access, cred, td)); default: Index: sys/kern/vfs_syscalls.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.427 diff -u -r1.427 vfs_syscalls.c --- sys/kern/vfs_syscalls.c 26 Oct 2006 13:20:28 -0000 1.427 +++ sys/kern/vfs_syscalls.c 30 Oct 2006 17:07:55 -0000 @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -272,7 +273,7 @@ error = VFS_STATFS(mp, sp, td); if (error) goto out; - if (suser(td)) { + if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; prison_enforce_statfs(td->td_ucred, mp, &sb); @@ -357,7 +358,7 @@ error = VFS_STATFS(mp, sp, td); if (error) goto out; - if (suser(td)) { + if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; prison_enforce_statfs(td->td_ucred, mp, &sb); @@ -468,7 +469,7 @@ vfs_unbusy(mp, td); continue; } - if (suser(td)) { + if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; prison_enforce_statfs(td->td_ucred, mp, &sb); @@ -842,7 +843,8 @@ struct nameidata nd; int vfslocked; - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(td->td_ucred, PRIV_VFS_CHROOT, + SUSER_ALLOWJAIL); if (error) return (error); NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, @@ -896,8 +898,8 @@ /* * Common routine for kern_chroot() and jail_attach(). The caller is - * responsible for invoking suser() and mac_check_chroot() to authorize this - * operation. + * responsible for invoking priv_check() and mac_check_chroot() to authorize + * this operation. */ int change_root(vp, td) @@ -1186,10 +1188,16 @@ switch (mode & S_IFMT) { case S_IFCHR: case S_IFBLK: - error = suser(td); + error = priv_check(td, PRIV_VFS_MKNOD_DEV); + break; + case S_IFMT: + error = priv_check(td, PRIV_VFS_MKNOD_BAD); + break; + case S_IFWHT: + error = priv_check(td, PRIV_VFS_MKNOD_WHT); break; default: - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + error = EINVAL; break; } if (error) @@ -1234,8 +1242,7 @@ whiteout = 1; break; default: - error = EINVAL; - break; + panic("kern_mknod: invalid mode"); } } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { @@ -1390,9 +1397,6 @@ struct vattr va; int error; - if (suser_cred(cred, SUSER_ALLOWJAIL) == 0) - return (0); - if (!hardlink_check_uid && !hardlink_check_gid) return (0); @@ -1400,14 +1404,18 @@ if (error != 0) return (error); - if (hardlink_check_uid) { - if (cred->cr_uid != va.va_uid) - return (EPERM); + if (hardlink_check_uid && cred->cr_uid != va.va_uid) { + error = priv_check_cred(cred, PRIV_VFS_LINK, + SUSER_ALLOWJAIL); + if (error) + return (error); } - if (hardlink_check_gid) { - if (!groupmember(va.va_gid, cred)) - return (EPERM); + if (hardlink_check_gid && !groupmember(va.va_gid, cred)) { + error = priv_check_cred(cred, PRIV_VFS_LINK, + SUSER_ALLOWJAIL); + if (error) + return (error); } return (0); @@ -2361,7 +2369,8 @@ * chown can't fail when done as root. */ if (vp->v_type == VCHR || vp->v_type == VBLK) { - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(td->td_ucred, PRIV_VFS_CHFLAGS_DEV, + SUSER_ALLOWJAIL); if (error) return (error); } @@ -3894,7 +3903,8 @@ if (error) goto out; if (td->td_ucred->cr_uid != vattr.va_uid) { - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN, + SUSER_ALLOWJAIL); if (error) goto out; } @@ -3960,7 +3970,7 @@ int vfslocked; int error; - error = suser(td); + error = priv_check(td, PRIV_VFS_GETFH); if (error) return (error); NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, @@ -3999,7 +4009,7 @@ int vfslocked; int error; - error = suser(td); + error = priv_check(td, PRIV_VFS_GETFH); if (error) return (error); NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, @@ -4022,10 +4032,10 @@ } /* - * syscall for the rpc.lockd to use to translate a NFS file handle into - * an open descriptor. + * syscall for the rpc.lockd to use to translate a NFS file handle into an + * open descriptor. * - * warning: do not remove the suser() call or this becomes one giant + * warning: do not remove the priv_check() call or this becomes one giant * security hole. * * MP SAFE @@ -4058,7 +4068,7 @@ int vfslocked; int indx; - error = suser(td); + error = priv_check(td, PRIV_VFS_FHOPEN); if (error) return (error); fmode = FFLAGS(uap->flags); @@ -4242,7 +4252,7 @@ int vfslocked; int error; - error = suser(td); + error = priv_check(td, PRIV_VFS_FHSTAT); if (error) return (error); error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); @@ -4307,7 +4317,7 @@ int vfslocked; int error; - error = suser(td); + error = priv_check(td, PRIV_VFS_FHSTATFS); if (error) return (error); if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) Index: sys/kern/vfs_vnops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/kern/vfs_vnops.c,v retrieving revision 1.245 diff -u -r1.245 vfs_vnops.c --- sys/kern/vfs_vnops.c 22 Oct 2006 11:52:14 -0000 1.245 +++ sys/kern/vfs_vnops.c 30 Oct 2006 17:07:55 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -709,7 +710,7 @@ sb->st_blksize = PAGE_SIZE; sb->st_flags = vap->va_flags; - if (suser(td)) + if (priv_check(td, PRIV_VFS_GENERATION)) sb->st_gen = 0; else sb->st_gen = vap->va_gen; Index: sys/net/bpf.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/bpf.c,v retrieving revision 1.173 diff -u -r1.173 bpf.c --- sys/net/bpf.c 22 Oct 2006 11:52:15 -0000 1.173 +++ sys/net/bpf.c 30 Oct 2006 17:07:55 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -1724,7 +1725,7 @@ * if the users who opened the devices were able to retrieve * the statistics for them, too. */ - error = suser(req->td); + error = priv_check(req->td, PRIV_NET_BPF); if (error) return (error); if (req->oldptr == NULL) Index: sys/net/if.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if.c,v retrieving revision 1.263 diff -u -r1.263 if.c --- sys/net/if.c 22 Oct 2006 11:52:15 -0000 1.263 +++ sys/net/if.c 30 Oct 2006 17:07:55 -0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -1489,7 +1490,7 @@ break; case SIOCSIFFLAGS: - error = suser(td); + error = priv_check(td, PRIV_NET_SETIFFLAGS); if (error) return (error); /* @@ -1532,7 +1533,7 @@ break; case SIOCSIFCAP: - error = suser(td); + error = priv_check(td, PRIV_NET_SETIFCAP); if (error) return (error); if (ifp->if_ioctl == NULL) @@ -1553,8 +1554,8 @@ #endif case SIOCSIFNAME: - error = suser(td); - if (error != 0) + error = priv_check(td, PRIV_NET_SETIFNAME); + if (error) return (error); error = copyinstr(ifr->ifr_data, new_name, IFNAMSIZ, NULL); if (error != 0) @@ -1600,7 +1601,7 @@ break; case SIOCSIFMETRIC: - error = suser(td); + error = priv_check(td, PRIV_NET_SETIFMETRIC); if (error) return (error); ifp->if_metric = ifr->ifr_metric; @@ -1608,7 +1609,7 @@ break; case SIOCSIFPHYS: - error = suser(td); + error = priv_check(td, PRIV_NET_SETIFPHYS); if (error) return (error); if (ifp->if_ioctl == NULL) @@ -1624,7 +1625,7 @@ { u_long oldmtu = ifp->if_mtu; - error = suser(td); + error = priv_check(td, PRIV_NET_SETIFMTU); if (error) return (error); if (ifr->ifr_mtu < IF_MINMTU || ifr->ifr_mtu > IF_MAXMTU) @@ -1651,7 +1652,10 @@ case SIOCADDMULTI: case SIOCDELMULTI: - error = suser(td); + if (cmd == SIOCADDMULTI) + error = priv_check(td, PRIV_NET_ADDMULTI); + else + error = priv_check(td, PRIV_NET_DELMULTI); if (error) return (error); @@ -1681,7 +1685,7 @@ case SIOCSLIFPHYADDR: case SIOCSIFMEDIA: case SIOCSIFGENERIC: - error = suser(td); + error = priv_check(td, PRIV_NET_HWIOCTL); if (error) return (error); if (ifp->if_ioctl == NULL) @@ -1710,7 +1714,7 @@ break; case SIOCSIFLLADDR: - error = suser(td); + error = priv_check(td, PRIV_NET_SETLLADDR); if (error) return (error); error = if_setlladdr(ifp, @@ -1721,7 +1725,7 @@ { struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr; - error = suser(td); + error = priv_check(td, PRIV_NET_ADDIFGROUP); if (error) return (error); if ((error = if_addgroup(ifp, ifgr->ifgr_group))) @@ -1738,7 +1742,7 @@ { struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr; - error = suser(td); + error = priv_check(td, PRIV_NET_DELIFGROUP); if (error) return (error); if ((error = if_delgroup(ifp, ifgr->ifgr_group))) @@ -1777,12 +1781,14 @@ switch (cmd) { case SIOCIFCREATE: case SIOCIFCREATE2: - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_IFCREATE); + if (error) return (error); return (if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name), cmd == SIOCIFCREATE2 ? ifr->ifr_data : NULL)); case SIOCIFDESTROY: - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_IFDESTROY); + if (error) return (error); return if_clone_destroy(ifr->ifr_name); Index: sys/net/if_bridge.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_bridge.c,v retrieving revision 1.82 diff -u -r1.82 if_bridge.c --- sys/net/if_bridge.c 9 Oct 2006 00:49:57 -0000 1.82 +++ sys/net/if_bridge.c 30 Oct 2006 17:07:55 -0000 @@ -101,6 +101,7 @@ #include #include #include +#include #include #include #include @@ -678,7 +679,7 @@ } if (bc->bc_flags & BC_F_SUSER) { - error = suser(td); + error = priv_check(td, PRIV_NET_BRIDGE); if (error) break; } Index: sys/net/if_gre.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_gre.c,v retrieving revision 1.44 diff -u -r1.44 if_gre.c --- sys/net/if_gre.c 4 Aug 2006 21:27:37 -0000 1.44 +++ sys/net/if_gre.c 30 Oct 2006 17:07:55 -0000 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -452,7 +453,11 @@ case SIOCSIFDSTADDR: break; case SIOCSIFFLAGS: - if ((error = suser(curthread)) != 0) + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ + if ((error = priv_check(curthread, PRIV_NET_SETIFFLAGS)) != 0) break; if ((ifr->ifr_flags & IFF_LINK0) != 0) sc->g_proto = IPPROTO_GRE; @@ -464,7 +469,11 @@ sc->wccp_ver = WCCP_V1; goto recompute; case SIOCSIFMTU: - if ((error = suser(curthread)) != 0) + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ + if ((error = priv_check(curthread, PRIV_NET_SETIFMTU)) != 0) break; if (ifr->ifr_mtu < 576) { error = EINVAL; @@ -476,8 +485,36 @@ ifr->ifr_mtu = GRE2IFP(sc)->if_mtu; break; case SIOCADDMULTI: + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ + if ((error = priv_check(curthread, PRIV_NET_ADDMULTI)) != 0) + break; + if (ifr == 0) { + error = EAFNOSUPPORT; + break; + } + switch (ifr->ifr_addr.sa_family) { +#ifdef INET + case AF_INET: + break; +#endif +#ifdef INET6 + case AF_INET6: + break; +#endif + default: + error = EAFNOSUPPORT; + break; + } + break; case SIOCDELMULTI: - if ((error = suser(curthread)) != 0) + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ + if ((error = priv_check(curthread, PRIV_NET_DELIFGROUP)) != 0) break; if (ifr == 0) { error = EAFNOSUPPORT; @@ -498,7 +535,11 @@ } break; case GRESPROTO: - if ((error = suser(curthread)) != 0) + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ + if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0) break; sc->g_proto = ifr->ifr_flags; switch (sc->g_proto) { @@ -518,8 +559,9 @@ break; case GRESADDRS: case GRESADDRD: - if ((error = suser(curthread)) != 0) - break; + error = priv_check(curthread, PRIV_NET_GRE); + if (error) + return (error); /* * set tunnel endpoints, compute a less specific route * to the remote end and mark if as up @@ -584,7 +626,11 @@ ifr->ifr_addr = *sa; break; case SIOCSIFPHYADDR: - if ((error = suser(curthread)) != 0) + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ + if ((error = priv_check(curthread, PRIV_NET_SETIFPHYS)) != 0) break; if (aifr->ifra_addr.sin_family != AF_INET || aifr->ifra_dstaddr.sin_family != AF_INET) { @@ -600,7 +646,11 @@ sc->g_dst = aifr->ifra_dstaddr.sin_addr; goto recompute; case SIOCSLIFPHYADDR: - if ((error = suser(curthread)) != 0) + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ + if ((error = priv_check(curthread, PRIV_NET_SETIFPHYS)) != 0) break; if (lifr->addr.ss_family != AF_INET || lifr->dstaddr.ss_family != AF_INET) { @@ -617,7 +667,11 @@ (satosin(&lifr->dstaddr))->sin_addr; goto recompute; case SIOCDIFPHYADDR: - if ((error = suser(curthread)) != 0) + /* + * XXXRW: Isn't this suser() redundant to the ifnet layer + * check? + */ + if ((error = priv_check(curthread, PRIV_NET_SETIFPHYS)) != 0) break; sc->g_src.s_addr = INADDR_ANY; sc->g_dst.s_addr = INADDR_ANY; Index: sys/net/if_ppp.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_ppp.c,v retrieving revision 1.116 diff -u -r1.116 if_ppp.c --- sys/net/if_ppp.c 22 Oct 2006 11:52:15 -0000 1.116 +++ sys/net/if_ppp.c 30 Oct 2006 17:07:55 -0000 @@ -87,6 +87,7 @@ #include #include +#include #include #include #include @@ -451,7 +452,8 @@ break; case PPPIOCSFLAGS: - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_PPP); + if (error) break; flags = *(int *)data & SC_MASK; s = splsoftnet(); @@ -465,8 +467,9 @@ break; case PPPIOCSMRU: - if ((error = suser(td)) != 0) - return (error); + error = priv_check(td, PRIV_NET_PPP); + if (error) + return (error); mru = *(int *)data; if (mru >= PPP_MRU && mru <= PPP_MAXMRU) sc->sc_mru = mru; @@ -478,7 +481,8 @@ #ifdef VJC case PPPIOCSMAXCID: - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_PPP); + if (error) break; if (sc->sc_comp) { s = splsoftnet(); @@ -489,14 +493,16 @@ #endif case PPPIOCXFERUNIT: - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_PPP); + if (error) break; sc->sc_xfer = p->p_pid; break; #ifdef PPP_COMPRESS case PPPIOCSCOMPRESS: - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_PPP); + if (error) break; odp = (struct ppp_option_data *) data; nb = odp->length; @@ -569,7 +575,8 @@ if (cmd == PPPIOCGNPMODE) { npi->mode = sc->sc_npmode[npx]; } else { - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_PPP); + if (error) break; if (npi->mode != sc->sc_npmode[npx]) { s = splsoftnet(); @@ -695,6 +702,10 @@ break; case SIOCSIFMTU: + /* + * XXXRW: Isn't this suser() check redundant to the one at the ifnet + * layer? + */ if ((error = suser(td)) != 0) break; if (ifr->ifr_mtu > PPP_MAXMTU) Index: sys/net/if_sl.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_sl.c,v retrieving revision 1.132 diff -u -r1.132 if_sl.c --- sys/net/if_sl.c 2 Jun 2006 19:59:32 -0000 1.132 +++ sys/net/if_sl.c 30 Oct 2006 17:07:55 -0000 @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -366,7 +367,7 @@ register struct sl_softc *sc; int s, error; - error = suser(curthread); + error = priv_check(curthread, PRIV_NET_SLIP); if (error) return (error); Index: sys/net/if_tap.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_tap.c,v retrieving revision 1.63 diff -u -r1.63 if_tap.c --- sys/net/if_tap.c 27 Sep 2006 19:57:01 -0000 1.63 +++ sys/net/if_tap.c 30 Oct 2006 17:07:55 -0000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -373,10 +374,13 @@ { struct tap_softc *tp = NULL; struct ifnet *ifp = NULL; - int s; + int error, s; - if (tapuopen == 0 && suser(td) != 0) - return (EPERM); + if (tapuopen == 0) { + error = priv_check(td, PRIV_NET_TAP); + if (error) + return (error); + } if ((dev2unit(dev) & CLONE_UNITMASK) > TAPMAXUNIT) return (ENXIO); Index: sys/net/if_tun.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/if_tun.c,v retrieving revision 1.159 diff -u -r1.159 if_tun.c --- sys/net/if_tun.c 22 Oct 2006 11:52:15 -0000 1.159 +++ sys/net/if_tun.c 30 Oct 2006 17:07:55 -0000 @@ -23,6 +23,7 @@ #include "opt_mac.h" #include +#include #include #include #include @@ -597,9 +598,11 @@ tunp = (struct tuninfo *)data; if (tunp->mtu < IF_MINMTU) return (EINVAL); - if (TUN2IFP(tp)->if_mtu != tunp->mtu - && (error = suser(td)) != 0) - return (error); + if (TUN2IFP(tp)->if_mtu != tunp->mtu) { + error = priv_check(td, PRIV_NET_SETIFMTU); + if (error) + return (error); + } TUN2IFP(tp)->if_mtu = tunp->mtu; TUN2IFP(tp)->if_type = tunp->type; TUN2IFP(tp)->if_baudrate = tunp->baudrate; Index: sys/net/ppp_tty.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/ppp_tty.c,v retrieving revision 1.69 diff -u -r1.69 ppp_tty.c --- sys/net/ppp_tty.c 16 Oct 2005 20:44:18 -0000 1.69 +++ sys/net/ppp_tty.c 30 Oct 2006 17:07:55 -0000 @@ -79,6 +79,7 @@ #include #include +#include #include #include #include @@ -179,7 +180,8 @@ register struct ppp_softc *sc; int error, s; - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_PPP); + if (error) return (error); s = spltty(); @@ -423,7 +425,8 @@ error = 0; switch (cmd) { case PPPIOCSASYNCMAP: - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_PPP); + if (error) break; sc->sc_asyncmap[0] = *(u_int *)data; break; @@ -433,7 +436,8 @@ break; case PPPIOCSRASYNCMAP: - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_PPP); + if (error) break; sc->sc_rasyncmap = *(u_int *)data; break; @@ -443,7 +447,8 @@ break; case PPPIOCSXASYNCMAP: - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_PPP); + if (error) break; s = spltty(); bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap)); Index: sys/net/raw_usrreq.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/raw_usrreq.c,v retrieving revision 1.43 diff -u -r1.43 raw_usrreq.c --- sys/net/raw_usrreq.c 21 Jul 2006 17:11:12 -0000 1.43 +++ sys/net/raw_usrreq.c 30 Oct 2006 17:07:55 -0000 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -171,8 +172,11 @@ */ KASSERT(sotorawcb(so) != NULL, ("raw_uattach: so_pcb == NULL")); - if (td && (error = suser(td)) != 0) - return error; + if (td != NULL) { + error = priv_check(td, PRIV_NET_RAW); + if (error) + return error; + } return raw_attach(so, proto); } Index: sys/net/rtsock.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net/rtsock.c,v retrieving revision 1.137 diff -u -r1.137 rtsock.c --- sys/net/rtsock.c 21 Jul 2006 17:11:12 -0000 1.137 +++ sys/net/rtsock.c 30 Oct 2006 17:07:55 -0000 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -368,8 +369,11 @@ * Verify that the caller has the appropriate privilege; RTM_GET * is the only operation the non-superuser is allowed. */ - if (rtm->rtm_type != RTM_GET && (error = suser(curthread)) != 0) - senderr(error); + if (rtm->rtm_type != RTM_GET) { + error = priv_check(curthread, PRIV_NET_ROUTE); + if (error) + senderr(error); + } switch (rtm->rtm_type) { struct rtentry *saved_nrt; Index: sys/net80211/ieee80211_ioctl.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/net80211/ieee80211_ioctl.c,v retrieving revision 1.50 diff -u -r1.50 ieee80211_ioctl.c --- sys/net80211/ieee80211_ioctl.c 26 Sep 2006 12:41:13 -0000 1.50 +++ sys/net80211/ieee80211_ioctl.c 30 Oct 2006 17:07:55 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -344,7 +345,7 @@ case WI_RID_DEFLT_CRYPT_KEYS: keys = (struct wi_ltv_keys *)&wreq; /* do not show keys to non-root user */ - error = suser(curthread); + error = priv_check(curthread, PRIV_NET80211_GETKEY); if (error) { memset(keys, 0, sizeof(*keys)); error = 0; @@ -861,7 +862,7 @@ ik.ik_flags = wk->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV); if (wk->wk_keyix == ic->ic_def_txkey) ik.ik_flags |= IEEE80211_KEY_DEFAULT; - if (suser(curthread) == 0) { + if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) { /* NB: only root can read key data */ ik.ik_keyrsc = wk->wk_keyrsc; ik.ik_keytsc = wk->wk_keytsc; @@ -1510,7 +1511,7 @@ return EINVAL; len = (u_int) ic->ic_nw_keys[kid].wk_keylen; /* NB: only root can read WEP keys */ - if (suser(curthread) == 0) { + if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) { bcopy(ic->ic_nw_keys[kid].wk_key, tmpkey, len); } else { bzero(tmpkey, len); @@ -2692,7 +2693,7 @@ (struct ieee80211req *) data); break; case SIOCS80211: - error = suser(curthread); + error = priv_check(curthread, PRIV_NET80211_MANAGE); if (error == 0) error = ieee80211_ioctl_set80211(ic, cmd, (struct ieee80211req *) data); @@ -2701,7 +2702,7 @@ error = ieee80211_cfgget(ic, cmd, data); break; case SIOCSIFGENERIC: - error = suser(curthread); + error = priv_check(curthread, PRIV_NET80211_MANAGE); if (error) break; error = ieee80211_cfgset(ic, cmd, data); Index: sys/netatalk/at_control.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netatalk/at_control.c,v retrieving revision 1.44 diff -u -r1.44 at_control.c --- sys/netatalk/at_control.c 22 Feb 2005 14:20:29 -0000 1.44 +++ sys/netatalk/at_control.c 30 Oct 2006 17:07:55 -0000 @@ -118,6 +118,8 @@ case SIOCSIFADDR: /* * If we are not superuser, then we don't get to do these ops. + * + * XXXRW: Layering? */ if (suser(td)) return (EPERM); Index: sys/netatalk/ddp_pcb.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netatalk/ddp_pcb.c,v retrieving revision 1.49 diff -u -r1.49 ddp_pcb.c --- sys/netatalk/ddp_pcb.c 2 Aug 2006 16:22:34 -0000 1.49 +++ sys/netatalk/ddp_pcb.c 30 Oct 2006 17:07:55 -0000 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -100,7 +101,7 @@ return (EINVAL); } if (sat->sat_port < ATPORT_RESERVED && - suser(td)) { + priv_check(td, PRIV_NETATALK_RESERVEDPORT)) { return (EACCES); } } Index: sys/netatm/atm_usrreq.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netatm/atm_usrreq.c,v retrieving revision 1.27 diff -u -r1.27 atm_usrreq.c --- sys/netatm/atm_usrreq.c 21 Jul 2006 17:11:13 -0000 1.27 +++ sys/netatm/atm_usrreq.c 30 Oct 2006 17:07:55 -0000 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -181,8 +182,11 @@ struct atmcfgreq *acp = (struct atmcfgreq *)data; struct atm_pif *pip; - if (td && (suser(td) != 0)) - ATM_RETERR(EPERM); + if (td != 0) { + err = priv_check(td, PRIV_NETATM_CFG); + if (err) + ATM_RETERR(err); + } switch (acp->acr_opcode) { @@ -214,8 +218,11 @@ struct atmaddreq *aap = (struct atmaddreq *)data; Atm_endpoint *epp; - if (td && (suser(td) != 0)) - ATM_RETERR(EPERM); + if (td != NULL) { + err = priv_check(td, PRIV_NETATM_ADD); + if (err) + ATM_RETERR(err); + } switch (aap->aar_opcode) { @@ -264,8 +271,11 @@ struct sigmgr *smp; Atm_endpoint *epp; - if (td && (suser(td) != 0)) - ATM_RETERR(EPERM); + if (td != NULL) { + err = priv_check(td, PRIV_NETATM_DEL); + if (err) + ATM_RETERR(err); + } switch (adp->adr_opcode) { @@ -317,8 +327,11 @@ struct sigmgr *smp; struct ifnet *ifp2; - if (td && (suser(td) != 0)) - ATM_RETERR(EPERM); + if (td != NULL) { + err = priv_check(td, PRIV_NETATM_SET); + if (err) + ATM_RETERR(err); + } switch (asp->asr_opcode) { Index: sys/netgraph/ng_socket.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netgraph/ng_socket.c,v retrieving revision 1.80 diff -u -r1.80 ng_socket.c --- sys/netgraph/ng_socket.c 18 Oct 2006 07:47:07 -0000 1.80 +++ sys/netgraph/ng_socket.c 30 Oct 2006 17:07:55 -0000 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -167,9 +168,11 @@ ngc_attach(struct socket *so, int proto, struct thread *td) { struct ngpcb *const pcbp = sotongpcb(so); + int error; - if (suser(td)) - return (EPERM); + error = priv_check(td, PRIV_NETGRAPH_CONTROL); + if (error) + return (error); if (pcbp != NULL) return (EISCONN); return (ng_attach_cntl(so)); Index: sys/netgraph/ng_tty.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netgraph/ng_tty.c,v retrieving revision 1.36 diff -u -r1.36 ng_tty.c --- sys/netgraph/ng_tty.c 16 Oct 2005 20:44:18 -0000 1.36 +++ sys/netgraph/ng_tty.c 30 Oct 2006 17:07:55 -0000 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -189,7 +190,8 @@ int error; /* Super-user only */ - if ((error = suser(td))) + error = priv_check(td, PRIV_NETGRAPH_TTY); + if (error) return (error); /* Initialize private struct */ Index: sys/netgraph/bluetooth/drivers/h4/ng_h4.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netgraph/bluetooth/drivers/h4/ng_h4.c,v retrieving revision 1.14 diff -u -r1.14 ng_h4.c --- sys/netgraph/bluetooth/drivers/h4/ng_h4.c 16 Oct 2005 20:44:18 -0000 1.14 +++ sys/netgraph/bluetooth/drivers/h4/ng_h4.c 30 Oct 2006 17:07:55 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -156,7 +157,7 @@ int s, error; /* Super-user only */ - error = suser(curthread); /* XXX */ + error = priv_check(curthread, PRIV_NETGRAPH_TTY); /* XXX */ if (error != 0) return (error); Index: sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c,v retrieving revision 1.22 diff -u -r1.22 ng_btsocket_hci_raw.c --- sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c 21 Jul 2006 17:11:13 -0000 1.22 +++ sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c 30 Oct 2006 17:07:55 -0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -916,7 +917,7 @@ so->so_pcb = (caddr_t) pcb; pcb->so = so; - if (suser(td) == 0) + if (priv_check(td, PRIV_NETBLUETOOTH_RAW) == 0) pcb->flags |= NG_BTSOCKET_HCI_RAW_PRIVILEGED; /* Index: sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c,v retrieving revision 1.19 diff -u -r1.19 ng_btsocket_l2cap_raw.c --- sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c 21 Jul 2006 17:11:13 -0000 1.19 +++ sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c 30 Oct 2006 17:07:55 -0000 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -620,7 +621,7 @@ so->so_pcb = (caddr_t) pcb; pcb->so = so; - if (suser(td) == 0) + if (priv_check(td, PRIV_NETBLUETOOTH_RAW) == 0) pcb->flags |= NG_BTSOCKET_L2CAP_RAW_PRIVILEGED; mtx_init(&pcb->pcb_mtx, "btsocks_l2cap_raw_pcb_mtx", NULL, MTX_DEF); Index: sys/netinet/in.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/in.c,v retrieving revision 1.94 diff -u -r1.94 in.c --- sys/netinet/in.c 28 Sep 2006 10:04:07 -0000 1.94 +++ sys/netinet/in.c 30 Oct 2006 17:07:55 -0000 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -232,10 +233,25 @@ switch (cmd) { case SIOCALIFADDR: + if (td != NULL) { + error = priv_check(td, PRIV_NET_ADDIFADDR); + if (error) + return (error); + } + if (!ifp) + return EINVAL; + return in_lifaddr_ioctl(so, cmd, data, ifp, td); + case SIOCDLIFADDR: - if (td && (error = suser(td)) != 0) - return error; - /*fall through*/ + if (td != NULL) { + error = priv_check(td, PRIV_NET_DELIFADDR); + if (error) + return (error); + } + if (!ifp) + return EINVAL; + return in_lifaddr_ioctl(so, cmd, data, ifp, td); + case SIOCGLIFADDR: if (!ifp) return EINVAL; @@ -292,8 +308,11 @@ case SIOCSIFADDR: case SIOCSIFNETMASK: case SIOCSIFDSTADDR: - if (td && (error = suser(td)) != 0) - return error; + if (td != NULL) { + error = priv_check(td, PRIV_NET_ADDIFADDR); + if (error) + return (error); + } if (ifp == 0) return (EADDRNOTAVAIL); @@ -330,8 +349,11 @@ break; case SIOCSIFBRDADDR: - if (td && (error = suser(td)) != 0) - return error; + if (td != NULL) { + error = priv_check(td, PRIV_NET_ADDIFADDR); + if (error) + return (error); + } /* FALLTHROUGH */ case SIOCGIFADDR: Index: sys/netinet/in_pcb.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/in_pcb.c,v retrieving revision 1.182 diff -u -r1.182 in_pcb.c --- sys/netinet/in_pcb.c 22 Oct 2006 11:52:16 -0000 1.182 +++ sys/netinet/in_pcb.c 30 Oct 2006 17:07:55 -0000 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -331,7 +332,8 @@ /* GROSS */ if (ntohs(lport) <= ipport_reservedhigh && ntohs(lport) >= ipport_reservedlow && - suser_cred(cred, SUSER_ALLOWJAIL)) + priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT, + SUSER_ALLOWJAIL)) return (EACCES); if (jailed(cred)) prison = 1; @@ -400,7 +402,9 @@ last = ipport_hilastauto; lastport = &pcbinfo->lasthi; } else if (inp->inp_flags & INP_LOWPORT) { - if ((error = suser_cred(cred, SUSER_ALLOWJAIL)) != 0) + error = priv_check_cred(cred, + PRIV_NETINET_RESERVEDPORT, SUSER_ALLOWJAIL); + if (error) return error; first = ipport_lowfirstauto; /* 1023 */ last = ipport_lowlastauto; /* 600 */ Index: sys/netinet/ip_carp.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/ip_carp.c,v retrieving revision 1.44 diff -u -r1.44 ip_carp.c --- sys/netinet/ip_carp.c 7 Oct 2006 10:19:58 -0000 1.44 +++ sys/netinet/ip_carp.c 30 Oct 2006 17:07:55 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1853,7 +1854,8 @@ break; case SIOCSVH: - if ((error = suser(curthread)) != 0) + error = priv_check(curthread, PRIV_NETINET_CARP); + if (error) break; if ((error = copyin(ifr->ifr_data, &carpr, sizeof carpr))) break; @@ -1928,7 +1930,8 @@ carpr.carpr_vhid = sc->sc_vhid; carpr.carpr_advbase = sc->sc_advbase; carpr.carpr_advskew = sc->sc_advskew; - if (suser(curthread) == 0) + error = priv_check(curthread, PRIV_NETINET_CARP); + if (error == 0) bcopy(sc->sc_key, carpr.carpr_key, sizeof(carpr.carpr_key)); error = copyout(&carpr, ifr->ifr_data, sizeof(carpr)); Index: sys/netinet/ip_divert.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/ip_divert.c,v retrieving revision 1.121 diff -u -r1.121 ip_divert.c --- sys/netinet/ip_divert.c 22 Oct 2006 11:52:16 -0000 1.121 +++ sys/netinet/ip_divert.c 30 Oct 2006 17:07:55 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -420,8 +421,11 @@ inp = sotoinpcb(so); KASSERT(inp == NULL, ("div_attach: inp != NULL")); - if (td && (error = suser(td)) != 0) - return error; + if (td != NULL) { + error = priv_check(td, PRIV_NETINET_DIVERT); + if (error) + return (error); + } error = soreserve(so, div_sendspace, div_recvspace); if (error) return error; Index: sys/netinet/ip_fw2.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/ip_fw2.c,v retrieving revision 1.152 diff -u -r1.152 ip_fw2.c --- sys/netinet/ip_fw2.c 22 Oct 2006 11:52:16 -0000 1.152 +++ sys/netinet/ip_fw2.c 30 Oct 2006 17:07:55 -0000 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -3980,7 +3981,7 @@ struct ip_fw *buf, *rule; u_int32_t rulenum[2]; - error = suser(sopt->sopt_td); + error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW); if (error) return (error); Index: sys/netinet/ip_mroute.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/ip_mroute.c,v retrieving revision 1.121 diff -u -r1.121 ip_mroute.c --- sys/netinet/ip_mroute.c 22 Oct 2006 11:52:16 -0000 1.121 +++ sys/netinet/ip_mroute.c 30 Oct 2006 17:07:56 -0000 @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -576,7 +577,7 @@ * Typically, only root can create the raw socket in order to execute * this ioctl method, however the request might be coming from a prison */ - error = suser(curthread); + error = priv_check(curthread, PRIV_NETINET_MROUTE); if (error) return (error); switch (cmd) { Index: sys/netinet/ip_output.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/ip_output.c,v retrieving revision 1.267 diff -u -r1.267 ip_output.c --- sys/netinet/ip_output.c 22 Oct 2006 11:52:16 -0000 1.267 +++ sys/netinet/ip_output.c 30 Oct 2006 17:07:56 -0000 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -987,8 +988,20 @@ break; if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */ break; - priv = (sopt->sopt_td != NULL && - suser(sopt->sopt_td) != 0) ? 0 : 1; + if (sopt->sopt_td != NULL) { + /* + * XXXRW: Would be more desirable to do this + * one layer down so that we only exercise + * privilege if it is needed. + */ + error = priv_check(sopt->sopt_td, + PRIV_NETINET_IPSEC); + if (error) + priv = 0; + else + priv = 1; + } else + priv = 1; req = mtod(m, caddr_t); len = m->m_len; optname = sopt->sopt_name; Index: sys/netinet/raw_ip.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/raw_ip.c,v retrieving revision 1.166 diff -u -r1.166 raw_ip.c --- sys/netinet/raw_ip.c 22 Oct 2006 11:52:16 -0000 1.166 +++ sys/netinet/raw_ip.c 30 Oct 2006 17:07:56 -0000 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -387,7 +388,11 @@ case IP_FW_GET: case IP_FW_TABLE_GETSIZE: case IP_FW_TABLE_LIST: - error = suser(curthread); + /* + * XXXRW: Isn't this checked one layer down? Yes, it + * is. + */ + error = priv_check(curthread, PRIV_NETINET_IPFW); if (error != 0) return (error); if (ip_fw_ctl_ptr != NULL) @@ -397,7 +402,7 @@ break; case IP_DUMMYNET_GET: - error = suser(curthread); + error = priv_check(curthread, PRIV_NETINET_DUMMYNET); if (error != 0) return (error); if (ip_dn_ctl_ptr != NULL) @@ -418,7 +423,7 @@ case MRT_API_CONFIG: case MRT_ADD_BW_UPCALL: case MRT_DEL_BW_UPCALL: - error = suser(curthread); + error = priv_check(curthread, PRIV_NETINET_MROUTE); if (error != 0) return (error); error = ip_mrouter_get ? ip_mrouter_get(so, sopt) : @@ -452,7 +457,10 @@ case IP_FW_TABLE_ADD: case IP_FW_TABLE_DEL: case IP_FW_TABLE_FLUSH: - error = suser(curthread); + /* + * XXXRW: Isn't this checked one layer down? + */ + error = priv_check(curthread, PRIV_NETINET_IPFW); if (error != 0) return (error); if (ip_fw_ctl_ptr != NULL) @@ -464,7 +472,7 @@ case IP_DUMMYNET_CONFIGURE: case IP_DUMMYNET_DEL: case IP_DUMMYNET_FLUSH: - error = suser(curthread); + error = priv_check(curthread, PRIV_NETINET_DUMMYNET); if (error != 0) return (error); if (ip_dn_ctl_ptr != NULL) @@ -474,14 +482,14 @@ break ; case IP_RSVP_ON: - error = suser(curthread); + error = priv_check(curthread, PRIV_NETINET_MROUTE); if (error != 0) return (error); error = ip_rsvp_init(so); break; case IP_RSVP_OFF: - error = suser(curthread); + error = priv_check(curthread, PRIV_NETINET_MROUTE); if (error != 0) return (error); error = ip_rsvp_done(); @@ -489,7 +497,7 @@ case IP_RSVP_VIF_ON: case IP_RSVP_VIF_OFF: - error = suser(curthread); + error = priv_check(curthread, PRIV_NETINET_MROUTE); if (error != 0) return (error); error = ip_rsvp_vif ? @@ -508,7 +516,7 @@ case MRT_API_CONFIG: case MRT_ADD_BW_UPCALL: case MRT_DEL_BW_UPCALL: - error = suser(curthread); + error = priv_check(curthread, PRIV_NETINET_MROUTE); if (error != 0) return (error); error = ip_mrouter_set ? ip_mrouter_set(so, sopt) : @@ -598,9 +606,14 @@ inp = sotoinpcb(so); KASSERT(inp == NULL, ("rip_attach: inp != NULL")); + /* + * XXXRW: Centralize privilege decision in kern_jail.c. + */ if (jailed(td->td_ucred) && !jail_allow_raw_sockets) return (EPERM); - if ((error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0) + error = priv_check_cred(td->td_ucred, PRIV_NETINET_RAW, + SUSER_ALLOWJAIL); + if (error) return error; if (proto >= IPPROTO_MAX || proto < 0) return EPROTONOSUPPORT; Index: sys/netinet/tcp_subr.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/tcp_subr.c,v retrieving revision 1.265 diff -u -r1.265 tcp_subr.c --- sys/netinet/tcp_subr.c 22 Oct 2006 11:52:16 -0000 1.265 +++ sys/netinet/tcp_subr.c 30 Oct 2006 17:07:56 -0000 @@ -48,6 +48,7 @@ #ifdef INET6 #include #endif +#include #include #include #include @@ -1081,7 +1082,8 @@ struct inpcb *inp; int error; - error = suser_cred(req->td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED, + SUSER_ALLOWJAIL); if (error) return (error); error = SYSCTL_IN(req, addrs, sizeof(addrs)); @@ -1125,7 +1127,8 @@ struct inpcb *inp; int error, mapped = 0; - error = suser_cred(req->td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED, + SUSER_ALLOWJAIL); if (error) return (error); error = SYSCTL_IN(req, addrs, sizeof(addrs)); Index: sys/netinet/udp_usrreq.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet/udp_usrreq.c,v retrieving revision 1.195 diff -u -r1.195 udp_usrreq.c --- sys/netinet/udp_usrreq.c 22 Oct 2006 11:52:17 -0000 1.195 +++ sys/netinet/udp_usrreq.c 30 Oct 2006 17:07:56 -0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -687,7 +688,8 @@ struct inpcb *inp; int error; - error = suser_cred(req->td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED, + SUSER_ALLOWJAIL); if (error) return (error); error = SYSCTL_IN(req, addrs, sizeof(addrs)); Index: sys/netinet6/in6.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet6/in6.c,v retrieving revision 1.64 diff -u -r1.64 in6.c --- sys/netinet6/in6.c 22 Sep 2006 01:42:22 -0000 1.64 +++ sys/netinet6/in6.c 30 Oct 2006 17:07:56 -0000 @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -325,12 +326,8 @@ struct in6_ifreq *ifr = (struct in6_ifreq *)data; struct in6_ifaddr *ia = NULL; struct in6_aliasreq *ifra = (struct in6_aliasreq *)data; - int error, privileged; struct sockaddr_in6 *sa6; - - privileged = 0; - if (td == NULL || !suser(td)) - privileged++; + int error; switch (cmd) { case SIOCGETSGCNT_IN6: @@ -341,8 +338,11 @@ switch(cmd) { case SIOCAADDRCTL_POLICY: case SIOCDADDRCTL_POLICY: - if (!privileged) - return (EPERM); + if (td != NULL) { + error = priv_check(td, PRIV_NETINET_ADDRCTRL6); + if (error) + return (error); + } return (in6_src_ioctl(cmd, data)); } @@ -355,8 +355,11 @@ case SIOCSRTRFLUSH_IN6: case SIOCSDEFIFACE_IN6: case SIOCSIFINFO_FLAGS: - if (!privileged) - return (EPERM); + if (td != NULL) { + error = priv_check(td, PRIV_NETINET_ND6); + if (error) + return (error); + } /* FALLTHROUGH */ case OSIOCGIFINFO_IN6: case SIOCGIFINFO_IN6: @@ -383,8 +386,11 @@ switch (cmd) { case SIOCSSCOPE6: - if (!privileged) - return (EPERM); + if (td != NULL) { + error = priv_check(td, PRIV_NETINET_SCOPE6); + if (error) + return (error); + } return (scope6_set(ifp, (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); case SIOCGSCOPE6: @@ -398,8 +404,15 @@ switch (cmd) { case SIOCALIFADDR: case SIOCDLIFADDR: - if (!privileged) - return (EPERM); + /* + * XXXRW: Is this checked at another layer? What priv to use + * here? + */ + if (td != NULL) { + error = suser(td); + if (error) + return (error); + } /* FALLTHROUGH */ case SIOCGLIFADDR: return in6_lifaddr_ioctl(so, cmd, data, ifp, td); @@ -488,8 +501,16 @@ if (ifra->ifra_addr.sin6_family != AF_INET6 || ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6)) return (EAFNOSUPPORT); - if (!privileged) - return (EPERM); + + /* + * XXXRW: Is this checked at another layer? What priv to use + * here? + */ + if (td != NULL) { + error = suser(td); + if (error) + return (error); + } break; @@ -508,8 +529,11 @@ { struct in6_addrlifetime *lt; - if (!privileged) - return (EPERM); + if (td != NULL) { + error = priv_check(td, PRIV_NETINET_ALIFETIME6); + if (error) + return (error); + } if (ia == NULL) return (EADDRNOTAVAIL); /* sanity for overflow - beware unsigned */ Index: sys/netinet6/in6_pcb.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet6/in6_pcb.c,v retrieving revision 1.73 diff -u -r1.73 in6_pcb.c --- sys/netinet6/in6_pcb.c 18 Jul 2006 22:34:27 -0000 1.73 +++ sys/netinet6/in6_pcb.c 30 Oct 2006 17:07:56 -0000 @@ -77,6 +77,7 @@ #include #include #include +#include #include #include @@ -190,8 +191,12 @@ /* GROSS */ if (ntohs(lport) <= ipport_reservedhigh && ntohs(lport) >= ipport_reservedlow && - suser_cred(cred, SUSER_ALLOWJAIL)) + priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT, + SUSER_ALLOWJAIL)) return (EACCES); + /* + * XXXRW: What priv to use here? + */ if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) && suser_cred(so->so_cred, SUSER_ALLOWJAIL) != 0) { t = in6_pcblookup_local(pcbinfo, Index: sys/netinet6/in6_src.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet6/in6_src.c,v retrieving revision 1.39 diff -u -r1.39 in6_src.c --- sys/netinet6/in6_src.c 4 Aug 2006 21:27:38 -0000 1.39 +++ sys/netinet6/in6_src.c 30 Oct 2006 17:07:56 -0000 @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -772,7 +773,9 @@ last = ipport_hilastauto; lastport = &pcbinfo->lasthi; } else if (inp->inp_flags & INP_LOWPORT) { - if ((error = suser_cred(cred, 0))) + error = priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT, + SUSER_ALLOWJAIL); + if (error) return error; first = ipport_lowfirstauto; /* 1023 */ last = ipport_lowlastauto; /* 600 */ Index: sys/netinet6/ipsec.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet6/ipsec.c,v retrieving revision 1.46 diff -u -r1.46 ipsec.c --- sys/netinet6/ipsec.c 4 Aug 2006 21:27:39 -0000 1.46 +++ sys/netinet6/ipsec.c 30 Oct 2006 17:07:56 -0000 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -1221,8 +1222,14 @@ } bzero(new, sizeof(*new)); - if (so->so_cred != NULL && - suser_cred(so->so_cred, SUSER_ALLOWJAIL) == 0) + /* + * XXXRW: Can we avoid caching the privilege decision here, and + * instead cache the credential? + * + * XXXRW: Why is suser_allowjail set here? + */ + if (so->so_cred != NULL && priv_check_cred(so->so_cred, + PRIV_NETINET_IPSEC, 0) == 0) new->priv = 1; else new->priv = 0; Index: sys/netinet6/udp6_usrreq.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netinet6/udp6_usrreq.c,v retrieving revision 1.68 diff -u -r1.68 udp6_usrreq.c --- sys/netinet6/udp6_usrreq.c 7 Sep 2006 18:44:54 -0000 1.68 +++ sys/netinet6/udp6_usrreq.c 30 Oct 2006 17:07:56 -0000 @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -434,7 +435,8 @@ struct inpcb *inp; int error; - error = suser(req->td); + error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED, + SUSER_ALLOWJAIL); if (error) return (error); Index: sys/netipsec/ipsec_osdep.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netipsec/ipsec_osdep.h,v retrieving revision 1.3 diff -u -r1.3 ipsec_osdep.h --- sys/netipsec/ipsec_osdep.h 27 Jun 2006 11:41:21 -0000 1.3 +++ sys/netipsec/ipsec_osdep.h 30 Oct 2006 17:07:56 -0000 @@ -215,11 +215,13 @@ * NetBSD (1.6N) tests (so)->so_uid == 0). * This difference is wrapped inside the IPSEC_PRIVILEGED_SO() macro. * + * XXXRW: Why was this suser_allowjail? */ #ifdef __FreeBSD__ #define IPSEC_IS_PRIVILEGED_SO(_so) \ ((_so)->so_cred != NULL && \ - suser_cred((_so)->so_cred, SUSER_ALLOWJAIL) == 0) + priv_check_cred((_so)->so_cred, PRIV_NETINET_IPSEC, 0) \ + == 0) #endif /* __FreeBSD__ */ #ifdef __NetBSD__ Index: sys/netipx/ipx_pcb.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netipx/ipx_pcb.c,v retrieving revision 1.45 diff -u -r1.45 ipx_pcb.c --- sys/netipx/ipx_pcb.c 25 Mar 2006 17:28:42 -0000 1.45 +++ sys/netipx/ipx_pcb.c 30 Oct 2006 17:07:56 -0000 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -107,11 +108,10 @@ lport = sipx->sipx_port; if (lport) { u_short aport = ntohs(lport); - int error; - if (aport < IPXPORT_RESERVED && - td != NULL && (error = suser(td)) != 0) - return (error); + if (aport < IPXPORT_RESERVED && td != NULL && + priv_check(td, PRIV_NETIPX_RESERVEDPORT)) + return (EACCES); if (ipx_pcblookup(&zeroipx_addr, lport, 0)) return (EADDRINUSE); } Index: sys/netipx/ipx_usrreq.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netipx/ipx_usrreq.c,v retrieving revision 1.57 diff -u -r1.57 ipx_usrreq.c --- sys/netipx/ipx_usrreq.c 21 Jul 2006 17:11:14 -0000 1.57 +++ sys/netipx/ipx_usrreq.c 30 Oct 2006 17:07:56 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -658,8 +659,13 @@ struct ipxpcb *ipxp = sotoipxpcb(so); KASSERT(ipxp == NULL, ("ripx_attach: ipxp != NULL")); - if (td != NULL && (error = suser(td)) != 0) - return (error); + + if (td != NULL) { + error = priv_check(td, PRIV_NETIPX_RAW); + if (error) + return (error); + } + /* * We hold the IPX list lock for the duration as address parameters * of the IPX pcb are changed. Since no one else holds a reference Index: sys/netncp/ncp_conn.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netncp/ncp_conn.c,v retrieving revision 1.28 diff -u -r1.28 ncp_conn.c --- sys/netncp/ncp_conn.c 14 Jan 2006 11:40:32 -0000 1.28 +++ sys/netncp/ncp_conn.c 30 Oct 2006 17:07:56 -0000 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include Index: sys/netncp/ncp_mod.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netncp/ncp_mod.c,v retrieving revision 1.15 diff -u -r1.15 ncp_mod.c --- sys/netncp/ncp_mod.c 7 Jan 2005 01:45:48 -0000 1.15 +++ sys/netncp/ncp_mod.c 30 Oct 2006 17:07:56 -0000 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include Index: sys/netncp/ncp_subr.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netncp/ncp_subr.h,v retrieving revision 1.9 diff -u -r1.9 ncp_subr.h --- sys/netncp/ncp_subr.h 7 Jan 2005 01:45:49 -0000 1.9 +++ sys/netncp/ncp_subr.h 30 Oct 2006 17:07:56 -0000 @@ -84,7 +84,7 @@ #define checkbad(fn) {error=(fn);if(error) goto bad;} -#define ncp_suser(cred) suser_cred(cred, 0) +#define ncp_suser(cred) priv_check_cred(cred, PRIV_NETNCP, 0) #define ncp_isowner(conn,cred) ((cred)->cr_uid == (conn)->nc_owner->cr_uid) Index: sys/netsmb/smb_conn.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netsmb/smb_conn.c,v retrieving revision 1.17 diff -u -r1.17 smb_conn.c --- sys/netsmb/smb_conn.c 17 Jul 2006 16:12:59 -0000 1.17 +++ sys/netsmb/smb_conn.c 30 Oct 2006 17:07:56 -0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include Index: sys/netsmb/smb_subr.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/netsmb/smb_subr.h,v retrieving revision 1.12 diff -u -r1.12 smb_subr.h --- sys/netsmb/smb_subr.h 7 Jan 2005 01:45:49 -0000 1.12 +++ sys/netsmb/smb_subr.h 30 Oct 2006 17:07:56 -0000 @@ -68,7 +68,7 @@ SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) || \ SIGISMEMBER(set, SIGQUIT)) -#define smb_suser(cred) suser_cred(cred, 0) +#define smb_suser(cred) priv_check_cred(cred, PRIV_NETSMB, 0) /* * Compatibility wrappers for simple locks Index: sys/nfsserver/nfs_syscalls.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/nfsserver/nfs_syscalls.c,v retrieving revision 1.107 diff -u -r1.107 nfs_syscalls.c --- sys/nfsserver/nfs_syscalls.c 22 Oct 2006 11:52:17 -0000 1.107 +++ sys/nfsserver/nfs_syscalls.c 30 Oct 2006 17:07:56 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -142,7 +143,7 @@ if (error) return (error); #endif - error = suser(td); + error = priv_check(td, PRIV_NFSD); if (error) return (error); NET_LOCK_GIANT(); Index: sys/pc98/cbus/fdc.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/pc98/cbus/fdc.c,v retrieving revision 1.167 diff -u -r1.167 fdc.c --- sys/pc98/cbus/fdc.c 8 Sep 2006 21:46:01 -0000 1.167 +++ sys/pc98/cbus/fdc.c 30 Oct 2006 17:07:56 -0000 @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -2512,7 +2513,7 @@ #endif case FD_CLRERR: - if (suser(td) != 0) + if (priv_check(td, PRIV_DRIVER) != 0) return (EPERM); fd->fdc->fdc_errs = 0; return (0); @@ -2556,7 +2557,7 @@ case FD_STYPE: /* set drive type */ /* this is considered harmful; only allow for superuser */ - if (suser(td) != 0) + if (priv_check(td, PRIV_DRIVER) != 0) return (EPERM); *fd->ft = *(struct fd_type *)addr; break; @@ -2580,7 +2581,7 @@ #endif case FD_CLRERR: - if (suser(td) != 0) + if (priv_check(td, PRIV_DRIVER) != 0) return (EPERM); fd->fdc->fdc_errs = 0; break; Index: sys/posix4/p1003_1b.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/posix4/p1003_1b.c,v retrieving revision 1.30 diff -u -r1.30 p1003_1b.c --- sys/posix4/p1003_1b.c 13 Jul 2006 06:41:26 -0000 1.30 +++ sys/posix4/p1003_1b.c 30 Oct 2006 17:07:56 -0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -186,9 +187,10 @@ struct thread *targettd; struct proc *targetp; - /* Don't allow non root user to set a scheduler policy */ - if (suser(td) != 0) - return (EPERM); + /* Don't allow non root user to set a scheduler policy. */ + e = priv_check(td, PRIV_SCHED_SET); + if (e) + return (e); e = copyin(uap->param, &sched_param, sizeof(sched_param)); if (e) Index: sys/security/audit/audit.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/audit/audit.c,v retrieving revision 1.21 diff -u -r1.21 audit.c --- sys/security/audit/audit.c 2 Oct 2006 11:32:23 -0000 1.21 +++ sys/security/audit/audit.c 30 Oct 2006 17:07:56 -0000 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -509,7 +510,8 @@ * audit record is still required for this event by * re-calling au_preselect(). */ - if (audit_in_failure && suser(td) != 0) { + if (audit_in_failure && + priv_check(td, PRIV_AUDIT_FAILSTOP) != 0) { cv_wait(&audit_fail_cv, &audit_mtx); panic("audit_failing_stop: thread continued"); } Index: sys/security/audit/audit_pipe.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/audit/audit_pipe.c,v retrieving revision 1.9 diff -u -r1.9 audit_pipe.c --- sys/security/audit/audit_pipe.c 26 Aug 2006 17:59:31 -0000 1.9 +++ sys/security/audit/audit_pipe.c 30 Oct 2006 17:07:56 -0000 @@ -626,9 +626,9 @@ } /* - * Audit pipe open method. Explicit suser check isn't used as this allows - * file permissions on the special device to be used to grant audit review - * access. + * Audit pipe open method. Explicit privilege check isn't used as this + * allows file permissions on the special device to be used to grant audit + * review access. Those file permissions should be managed carefully. */ static int audit_pipe_open(struct cdev *dev, int oflags, int devtype, struct thread *td) Index: sys/security/audit/audit_syscalls.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/audit/audit_syscalls.c,v retrieving revision 1.8 diff -u -r1.8 audit_syscalls.c --- sys/security/audit/audit_syscalls.c 10 Oct 2006 15:49:10 -0000 1.8 +++ sys/security/audit/audit_syscalls.c 30 Oct 2006 17:07:56 -0000 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -66,7 +67,7 @@ if (jailed(td->td_ucred)) return (ENOSYS); - error = suser(td); + error = priv_check(td, PRIV_AUDIT_SUBMIT); if (error) return (error); @@ -156,7 +157,7 @@ if (jailed(td->td_ucred)) return (ENOSYS); AUDIT_ARG(cmd, uap->cmd); - error = suser(td); + error = priv_check(td, PRIV_AUDIT_CONTROL); if (error) return (error); @@ -404,7 +405,7 @@ if (jailed(td->td_ucred)) return (ENOSYS); - error = suser(td); + error = priv_check(td, PRIV_AUDIT_GETAUDIT); if (error) return (error); @@ -428,7 +429,7 @@ if (jailed(td->td_ucred)) return (ENOSYS); - error = suser(td); + error = priv_check(td, PRIV_AUDIT_SETAUDIT); if (error) return (error); @@ -468,7 +469,7 @@ if (jailed(td->td_ucred)) return (ENOSYS); - error = suser(td); + error = priv_check(td, PRIV_AUDIT_GETAUDIT); if (error) return (error); @@ -489,7 +490,7 @@ if (jailed(td->td_ucred)) return (ENOSYS); - error = suser(td); + error = priv_check(td, PRIV_AUDIT_SETAUDIT); if (error) return (error); @@ -518,7 +519,7 @@ if (jailed(td->td_ucred)) return (ENOSYS); - error = suser(td); + error = priv_check(td, PRIV_AUDIT_GETAUDIT); if (error) return (error); return (ENOSYS); @@ -533,7 +534,7 @@ if (jailed(td->td_ucred)) return (ENOSYS); - error = suser(td); + error = priv_check(td, PRIV_AUDIT_SETAUDIT); if (error) return (error); return (ENOSYS); @@ -557,7 +558,7 @@ if (jailed(td->td_ucred)) return (ENOSYS); - error = suser(td); + error = priv_check(td, PRIV_AUDIT_CONTROL); if (error) return (error); Index: sys/security/mac/mac_framework.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac/mac_framework.h,v retrieving revision 1.74 diff -u -r1.74 mac_framework.h --- sys/security/mac/mac_framework.h 25 Oct 2006 13:14:25 -0000 1.74 +++ sys/security/mac/mac_framework.h 30 Oct 2006 17:07:56 -0000 @@ -407,6 +407,8 @@ struct label *label); void mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred); void mac_associate_nfsd_label(struct ucred *cred); +int mac_priv_check(struct ucred *cred, int priv); +int mac_priv_grant(struct ucred *cred, int priv); /* * Calls to help various file systems implement labeling functionality Index: sys/security/mac/mac_internal.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac/mac_internal.h,v retrieving revision 1.114 diff -u -r1.114 mac_internal.h --- sys/security/mac/mac_internal.h 20 Sep 2006 13:33:40 -0000 1.114 +++ sys/security/mac/mac_internal.h 30 Oct 2006 17:07:56 -0000 @@ -2,6 +2,7 @@ * Copyright (c) 1999-2002 Robert N. M. Watson * Copyright (c) 2001 Ilmar S. Habibulin * Copyright (c) 2001-2004 Networks Associates Technology, Inc. + * Copyright (c) 2006 nCircle Network Security, Inc. * All rights reserved. * * This software was developed by Robert Watson and Ilmar Habibulin for the @@ -12,6 +13,9 @@ * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), * as part of the DARPA CHATS research program. * + * This software was developed by Robert N. M. Watson for the TrustedBSD + * Project under contract to nCircle Network Security, Inc. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -152,6 +156,36 @@ } while (0) /* + * MAC_GRANT performs the designated check by walking the policy module + * list and checking with each as to how it feels about the request. Unlike + * MAC_CHECK, it grants if any policies return '0', and otherwise returns + * EPERM. Note that it returns its value via 'error' in the scope of the + * caller. + */ +#define MAC_GRANT(check, args...) do { \ + struct mac_policy_conf *mpc; \ + int entrycount; \ + \ + error = EPERM; \ + LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ + if (mpc->mpc_ops->mpo_ ## check != NULL) { \ + if (mpc->mpc_ops->mpo_ ## check(args) == 0) \ + error = 0; \ + } \ + } \ + if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ + LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ + if (mpc->mpc_ops->mpo_ ## check != NULL) { \ + if (mpc->mpc_ops->mpo_ ## check (args) \ + == 0) \ + error = 0; \ + } \ + } \ + mac_policy_list_unbusy(); \ + } \ +} while (0) + +/* * MAC_BOOLEAN performs the designated boolean composition by walking * the module list, invoking each instance of the operation, and * combining the results using the passed C operator. Note that it Index: sys/security/mac/mac_net.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac/mac_net.c,v retrieving revision 1.119 diff -u -r1.119 mac_net.c --- sys/security/mac/mac_net.c 22 Oct 2006 11:52:18 -0000 1.119 +++ sys/security/mac/mac_net.c 30 Oct 2006 17:07:56 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -470,11 +471,11 @@ } /* - * XXX: Note that this is a redundant privilege check, since - * policies impose this check themselves if required by the - * policy. Eventually, this should go away. + * XXX: Note that this is a redundant privilege check, since policies + * impose this check themselves if required by the policy. + * Eventually, this should go away. */ - error = suser_cred(cred, 0); + error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0); if (error) { mac_ifnet_label_free(intlabel); return (error); Index: sys/security/mac/mac_priv.c =================================================================== RCS file: sys/security/mac/mac_priv.c diff -N sys/security/mac/mac_priv.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/security/mac/mac_priv.c 30 Oct 2006 18:53:30 -0000 @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2006 nCircle Network Security, Inc. + * All rights reserved. + * + * This software was developed by Robert N. M. Watson for the TrustedBSD + * Project under contract to nCircle Network Security, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY, + * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * MAC checks for system privileges. + */ + +#include "opt_mac.h" + +#include +#include +#include +#include + +#include +#include + +int +mac_priv_check(struct ucred *cred, int priv) +{ + int error; + + MAC_CHECK(priv_check, cred, priv); + + return (error); +} + +int +mac_priv_grant(struct ucred *cred, int priv) +{ + int error; + + MAC_GRANT(priv_grant, cred, priv); + + return (error); +} Index: sys/security/mac/mac_system.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac/mac_system.c,v retrieving revision 1.106 diff -u -r1.106 mac_system.c --- sys/security/mac/mac_system.c 22 Oct 2006 11:52:18 -0000 1.106 +++ sys/security/mac/mac_system.c 30 Oct 2006 17:07:56 -0000 @@ -60,6 +60,12 @@ &mac_enforce_system, 0, "Enforce MAC policy on system operations"); TUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); +/* + * XXXRW: Some of these checks now duplicate privilege checks. However, + * others provide additional security context that may be useful to policies. + * We need to review these and remove ones that are pure duplicates. + */ + int mac_check_kenv_dump(struct ucred *cred) { Index: sys/security/mac_bsdextended/mac_bsdextended.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac_bsdextended/mac_bsdextended.c,v retrieving revision 1.29 diff -u -r1.29 mac_bsdextended.c --- sys/security/mac_bsdextended/mac_bsdextended.c 23 Apr 2006 17:06:18 -0000 1.29 +++ sys/security/mac_bsdextended/mac_bsdextended.c 30 Oct 2006 17:07:56 -0000 @@ -456,6 +456,9 @@ { int error, i; + /* + * XXXRW: More specific privilege selection needed? + */ if (suser_cred(cred, 0) == 0) return (0); Index: sys/security/mac_lomac/mac_lomac.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac_lomac/mac_lomac.c,v retrieving revision 1.41 diff -u -r1.41 mac_lomac.c --- sys/security/mac_lomac/mac_lomac.c 22 Oct 2006 11:52:19 -0000 1.41 +++ sys/security/mac_lomac/mac_lomac.c 30 Oct 2006 17:07:56 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -1697,8 +1698,10 @@ * Rely on the traditional superuser status for the LOMAC * interface relabel requirements. XXXMAC: This will go * away. + * + * XXXRW: This is also redundant to a higher layer check. */ - error = suser_cred(cred, 0); + error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0); if (error) return (EPERM); Index: sys/security/mac_partition/mac_partition.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac_partition/mac_partition.c,v retrieving revision 1.11 diff -u -r1.11 mac_partition.c --- sys/security/mac_partition/mac_partition.c 19 Sep 2005 18:52:50 -0000 1.11 +++ sys/security/mac_partition/mac_partition.c 30 Oct 2006 17:07:56 -0000 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -191,7 +192,7 @@ * in a partition in the first place, but this didn't * interact well with sendmail. */ - error = suser_cred(cred, 0); + error = priv_check_cred(cred, PRIV_MAC_PARTITION, 0); } return (error); Index: sys/security/mac_portacl/mac_portacl.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac_portacl/mac_portacl.c,v retrieving revision 1.9 diff -u -r1.9 mac_portacl.c --- sys/security/mac_portacl/mac_portacl.c 10 Oct 2006 17:04:19 -0000 1.9 +++ sys/security/mac_portacl/mac_portacl.c 30 Oct 2006 17:07:56 -0000 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -427,7 +428,8 @@ mtx_unlock(&rule_mtx); if (error != 0 && mac_portacl_suser_exempt != 0) - error = suser_cred(cred, SUSER_ALLOWJAIL); + error = priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT, + SUSER_ALLOWJAIL); return (error); } Index: sys/security/mac_seeotheruids/mac_seeotheruids.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/security/mac_seeotheruids/mac_seeotheruids.c,v retrieving revision 1.8 diff -u -r1.8 mac_seeotheruids.c --- sys/security/mac_seeotheruids/mac_seeotheruids.c 30 Sep 2005 23:41:10 -0000 1.8 +++ sys/security/mac_seeotheruids/mac_seeotheruids.c 30 Oct 2006 17:07:56 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -126,7 +127,7 @@ return (0); if (suser_privileged) { - if (suser_cred(u1, 0) == 0) + if (priv_check_cred(u1, PRIV_SEEOTHERUIDS, 0) == 0) return (0); } Index: sys/sun4v/sun4v/hvcons.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/sun4v/sun4v/hvcons.c,v retrieving revision 1.2 diff -u -r1.2 hvcons.c --- sys/sun4v/sun4v/hvcons.c 13 Oct 2006 06:45:50 -0000 1.2 +++ sys/sun4v/sun4v/hvcons.c 30 Oct 2006 17:07:56 -0000 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -118,7 +119,8 @@ ttyconsolemode(tp, 0); setuptimeout = 1; - } else if ((tp->t_state & TS_XCLUDE) && suser(td)) { + } else if ((tp->t_state & TS_XCLUDE) && priv_check(td, + PRIV_TTY_EXCLUSIVE)) { return (EBUSY); } Index: sys/sys/jail.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/sys/jail.h,v retrieving revision 1.26 diff -u -r1.26 jail.h --- sys/sys/jail.h 9 Jun 2005 18:49:19 -0000 1.26 +++ sys/sys/jail.h 30 Oct 2006 18:52:31 -0000 @@ -110,6 +110,7 @@ void prison_hold(struct prison *pr); int prison_if(struct ucred *cred, struct sockaddr *sa); int prison_ip(struct ucred *cred, int flag, u_int32_t *ip); +int prison_priv_check(struct ucred *cred, int priv); void prison_remote_ip(struct ucred *cred, int flags, u_int32_t *ip); #endif /* _KERNEL */ Index: sys/sys/mac_policy.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/sys/mac_policy.h,v retrieving revision 1.77 diff -u -r1.77 mac_policy.h --- sys/sys/mac_policy.h 30 Oct 2006 15:20:49 -0000 1.77 +++ sys/sys/mac_policy.h 30 Oct 2006 17:07:56 -0000 @@ -596,6 +596,8 @@ struct ucred *file_cred, struct vnode *vp, struct label *label); typedef void (*mpo_associate_nfsd_label_t)(struct ucred *cred); +typedef int (*mpo_priv_check_t)(struct ucred *cred, int priv); +typedef int (*mpo_priv_grant_t)(struct ucred *cred, int priv); struct mac_policy_ops { /* @@ -886,6 +888,8 @@ mpo_check_vnode_write_t mpo_check_vnode_write; mpo_associate_nfsd_label_t mpo_associate_nfsd_label; mpo_create_mbuf_from_firewall_t mpo_create_mbuf_from_firewall; + mpo_priv_check_t mpo_priv_check; + mpo_priv_grant_t mpo_priv_grant; }; /* Index: sys/sys/priv.h =================================================================== RCS file: sys/sys/priv.h diff -N sys/sys/priv.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sys/priv.h 31 Oct 2006 08:20:40 -0000 @@ -0,0 +1,457 @@ +/*- + * Copyright (c) 2006 nCircle Network Security, Inc. + * All rights reserved. + * + * This software was developed by Robert N. M. Watson for the TrustedBSD + * Project under contract to nCircle Network Security, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY, + * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * Privilege checking interface for BSD kernel. + */ +#ifndef _SYS_PRIV_H_ +#define _SYS_PRIV_H_ + +/* + * Privilege list. In no particular order. + * + * Think carefully before adding or reusing one of these privileges -- are + * there existing instances referring to the same privilege? Third party + * vendors may request the assignment of privileges to be used in loadable + * modules. Particular numeric privilege assignments are part of the + * loadable kernel module ABI, and should not be changed across minor + * releases. + * + * When adding a new privilege, remember to determine if it's appropriate for + * use in jail, and update the privilege switch in kern_jail.c as necessary. + */ + +/* + * Track beginning of privilege list. + */ +#define _PRIV_LOWEST 0 + +/* + * PRIV_ROOT is a catch-all for as yet unnamed privileges. No new + * references to this privilege should be added. + */ +#define PRIV_ROOT 1 /* Catch-all during development. */ + +/* + * The remaining privileges typically correspond to one or a small + * number of specific privilege checks, and have (relatively) precise + * meanings. They are loosely sorted into a set of base system + * privileges, such as the ability to reboot, and then loosely by + * subsystem, indicated by a subsystem name. + */ +#define PRIV_ACCT 2 /* Manage process accounting. */ +#define PRIV_MAXFILES 3 /* Exceed system open files limit. */ +#define PRIV_MAXPROC 4 /* Exceed system processes limit. */ +#define PRIV_KTRACE 5 /* Set/clear KTRFAC_ROOT on ktrace. */ +#define PRIV_SETDUMPER 6 /* Configure dump device. */ +#define PRIV_NFSD 7 /* Can become NFS daemon. */ +#define PRIV_REBOOT 8 /* Can reboot system. */ +#define PRIV_SWAPON 9 /* Can swapon(). */ +#define PRIV_SWAPOFF 10 /* Can swapoff(). */ +#define PRIV_MSGBUF 11 /* Can read kernel message buffer. */ +#define PRIV_WITNESS 12 /* Can configure WITNESS. */ +#define PRIV_IO 13 /* Can perform low-level I/O. */ +#define PRIV_KEYBOARD 14 /* Reprogram keyboard. */ +#define PRIV_DRIVER 15 /* Low-level driver privilege. */ +#define PRIV_ADJTIME 16 /* Set time adjustment. */ +#define PRIV_NTP_ADJTIME 17 /* Set NTP time adjustment. */ +#define PRIV_CLOCK_SETTIME 18 /* Can call clock_settime. */ +#define PRIV_SETTIMEOFDAY 19 /* Can call settimeofday. */ +#define PRIV_SETHOSTID 20 /* Can call sethostid. */ +#define PRIV_SETDOMAINNAME 21 /* Can call setdomainname. */ + +/* + * Audit subsystem privileges. + */ +#define PRIV_AUDIT_CONTROL 40 /* Can configure audit. */ +#define PRIV_AUDIT_FAILSTOP 41 /* Can run during audit fail stop. */ +#define PRIV_AUDIT_GETAUDIT 42 /* Can get proc audit properties. */ +#define PRIV_AUDIT_SETAUDIT 43 /* Can set proc audit properties. */ +#define PRIV_AUDIT_SUBMIT 44 /* Can submit an audit record. */ + +/* + * Credential management privileges. + */ +#define PRIV_CRED_SETUID 50 /* setuid. */ +#define PRIV_CRED_SETEUID 51 /* seteuid to !ruid and !svuid. */ +#define PRIV_CRED_SETGID 52 /* setgid. */ +#define PRIV_CRED_SETEGID 53 /* setgid to !rgid and !svgid. */ +#define PRIV_CRED_SETGROUPS 54 /* Set process additional groups. */ +#define PRIV_CRED_SETREUID 55 /* setreuid. */ +#define PRIV_CRED_SETREGID 56 /* setregid. */ +#define PRIV_CRED_SETRESUID 57 /* setresuid. */ +#define PRIV_CRED_SETRESGID 58 /* setresgid. */ +#define PRIV_SEEOTHERGIDS 59 /* Exempt bsd.seeothergids. */ +#define PRIV_SEEOTHERUIDS 60 /* Exempt bsd.seeotheruids. */ + +/* + * Debugging privileges. + */ +#define PRIV_DEBUG_DIFFCRED 80 /* Exempt debugging other users. */ +#define PRIV_DEBUG_SUGID 81 /* Exempt debugging setuid proc. */ +#define PRIV_DEBUG_UNPRIV 82 /* Exempt unprivileged debug limit. */ + +/* + * Dtrace privileges. + */ +#define PRIV_DTRACE_KERNEL 90 /* Allow use of DTrace on the kernel. */ +#define PRIV_DTRACE_PROC 91 /* Allow attaching DTrace to process. */ +#define PRIV_DTRACE_USER 92 /* Process may submit DTrace events. */ + +/* + * Firmware privilegs. + */ +#define PRIV_FIRMWARE_LOAD 100 /* Can load firmware. */ + +/* + * Jail privileges. + */ +#define PRIV_JAIL_ATTACH 110 /* Attach to a jail. */ + +/* + * Kernel environment priveleges. + */ +#define PRIV_KENV_SET 120 /* Set kernel env. variables. */ +#define PRIV_KENV_UNSET 121 /* Unset kernel env. variables. */ + +/* + * Loadable kernel module privileges. + */ +#define PRIV_KLD_LOAD 130 /* Load a kernel module. */ +#define PRIV_KLD_UNLOAD 131 /* Unload a kernel module. */ + +/* + * Privileges associated with the MAC Framework and specific MAC policy + * modules. + */ +#define PRIV_MAC_PARTITION 140 /* Privilege in mac_partition policy. */ +#define PRIV_MAC_PRIVS 141 /* Privilege in the mac_privs policy. */ + +/* + * Process-related privileges. + */ +#define PRIV_PROC_LIMIT 160 /* Exceed user process limit. */ +#define PRIV_PROC_SETLOGIN 161 /* Can call setlogin. */ +#define PRIV_PROC_SETRLIMIT 162 /* Can raise resources limits. */ + +/* System V IPC privileges. + */ +#define PRIV_IPC_READ 170 /* Can override IPC read perm. */ +#define PRIV_IPC_WRITE 171 /* Can override IPC write perm. */ +#define PRIV_IPC_EXEC 172 /* Can override IPC exec perm. */ +#define PRIV_IPC_ADMIN 173 /* Can override IPC owner-only perm. */ +#define PRIV_IPC_MSGSIZE 174 /* Exempt IPC message queue limit. */ + +/* + * POSIX message queue privileges. + */ +#define PRIV_MQ_ADMIN 180 /* Can override msgq owner-only perm. */ + +/* + * Performance monitoring counter privileges. + */ +#define PRIV_PMC_MANAGE 190 /* Can administer PMC. */ +#define PRIV_PMC_SYSTEM 191 /* Can allocate a system-wide PMC. */ + +/* + * Scheduling privileges. + */ +#define PRIV_SCHED_DIFFCRED 200 /* Exempt scheduling other users. */ +#define PRIV_SCHED_SETPRIORITY 201 /* Can set lower nice value for proc. */ +#define PRIV_SCHED_RTPRIO 202 /* Can set real time scheduling. */ +#define PRIV_SCHED_SETPOLICY 203 /* Can set scheduler policy. */ +#define PRIV_SCHED_SET 204 /* Can set thread scheduler. */ +#define PRIV_SCHED_SETPARAM 205 /* Can set thread scheduler params. */ + +/* + * POSIX semaphore privileges. + */ +#define PRIV_SEM_WRITE 220 /* Can override sem write perm. */ + +/* + * Signal privileges. + */ +#define PRIV_SIGNAL_DIFFCRED 230 /* Exempt signalling other users. */ +#define PRIV_SIGNAL_SUGID 231 /* Non-conserv signal setuid proc. */ + +/* + * Sysctl privileges. + */ +#define PRIV_SYSCTL_DEBUG 240 /* Can invoke sysctl.debug. */ +#define PRIV_SYSCTL_WRITE 241 /* Can write sysctls. */ +#define PRIV_SYSCTL_WRITEJAIL 242 /* Can write sysctls, jail permitted. */ + +/* + * TTY privileges. + */ +#define PRIV_TTY_CONSOLE 250 /* Set console to tty. */ +#define PRIV_TTY_DRAINWAIT 251 /* Set tty drain wait time. */ +#define PRIV_TTY_DTRWAIT 252 /* Set DTR wait on tty. */ +#define PRIV_TTY_EXCLUSIVE 253 /* Override tty exclusive flag. */ +#define PRIV_TTY_PRISON 254 /* Can open pts across jails. */ +#define PRIV_TTY_STI 255 /* Simulate input on another tty. */ +#define PRIV_TTY_SETA 256 /* Set tty termios structure. */ + +/* + * UFS-specific privileges. + */ +#define PRIV_UFS_EXTATTRCTL 270 /* Can configure EAs on UFS1. */ +#define PRIV_UFS_GETQUOTA 271 /* getquota(). */ +#define PRIV_UFS_QUOTAOFF 272 /* quotaoff(). */ +#define PRIV_UFS_QUOTAON 273 /* quotaon(). */ +#define PRIV_UFS_SETQUOTA 274 /* setquota(). */ +#define PRIV_UFS_SETUSE 275 /* setuse(). */ +#define PRIV_UFS_EXCEEDQUOTA 276 /* Exempt from quota restrictions. */ + +/* + * VFS privileges. + */ +#define PRIV_VFS_READ 310 /* Override vnode DAC read perm. */ +#define PRIV_VFS_WRITE 311 /* Override vnode DAC write perm. */ +#define PRIV_VFS_ADMIN 312 /* Override vnode DAC admin perm. */ +#define PRIV_VFS_EXEC 313 /* Override vnode DAC exec perm. */ +#define PRIV_VFS_LOOKUP 314 /* Override vnode DAC lookup perm. */ +#define PRIV_VFS_BLOCKRESERVE 315 /* Can use free block reserve. */ +#define PRIV_VFS_CHFLAGS_DEV 316 /* Can chflags() a device node. */ +#define PRIV_VFS_CHOWN 317 /* Can set user; group to non-member. */ +#define PRIV_VFS_CHROOT 318 /* chroot(). */ +#define PRIV_VFS_CLEARSUGID 319 /* Don't clear sugid on change. */ +#define PRIV_VFS_EXTATTR_SYSTEM 320 /* Operate on system EA namespace. */ +#define PRIV_VFS_FCHROOT 321 /* fchroot(). */ +#define PRIV_VFS_FHOPEN 322 /* Can fhopen(). */ +#define PRIV_VFS_FHSTAT 323 /* Can fhstat(). */ +#define PRIV_VFS_FHSTATFS 324 /* Can fhstatfs(). */ +#define PRIV_VFS_GENERATION 325 /* stat() returns generation number. */ +#define PRIV_VFS_GETFH 326 /* Can retrieve file handles. */ +#define PRIV_VFS_LINK 327 /* bsd.hardlink_check_uid */ +#define PRIV_VFS_MKNOD_BAD 328 /* Can mknod() to mark bad inodes. */ +#define PRIV_VFS_MKNOD_DEV 329 /* Can mknod() to create dev nodes. */ +#define PRIV_VFS_MKNOD_WHT 330 /* Can mknod() to create whiteout. */ +#define PRIV_VFS_MOUNT 331 /* Can mount(). */ +#define PRIV_VFS_MOUNT_OWNER 332 /* Override owner on user mounts. */ +#define PRIV_VFS_MOUNT_EXPORTED 333 /* Can set MNT_EXPORTED on mount. */ +#define PRIV_VFS_MOUNT_PERM 334 /* Override dev node perms at mount. */ +#define PRIV_VFS_MOUNT_SUIDDIR 335 /* Can set MNT_SUIDDIR on mount. */ +#define PRIV_VFS_MOUNT_NONUSER 336 /* Can perform a non-user mount. */ +#define PRIV_VFS_SETGID 337 /* Can setgid if not in group. */ +#define PRIV_VFS_STICKYFILE 338 /* Can set sticky bit on file. */ +#define PRIV_VFS_SYSFLAGS 339 /* Can modify system flags. */ +#define PRIV_VFS_UNMOUNT 340 /* Can unmount(). */ + +/* + * Virtual memory privileges. + */ +#define PRIV_VM_MADV_PROTECT 360 /* Can set MADV_PROTECT. */ +#define PRIV_VM_MLOCK 361 /* Can mlock(), mlockall(). */ +#define PRIV_VM_MUNLOCK 362 /* Can munlock(), munlockall(). */ + +/* + * Device file system privileges. + */ +#define PRIV_DEVFS_RULE 370 /* Can manage devfs rules. */ +#define PRIV_DEVFS_SYMLINK 371 /* Can create symlinks in devfs. */ + +/* + * Random number generator privileges. + */ +#define PRIV_RANDOM_RESEED 380 /* Closing /dev/random reseeds. */ + +/* + * Network stack privileges. + */ +#define PRIV_NET_BRIDGE 390 /* Administer bridge. */ +#define PRIV_NET_GRE 391 /* Administer GRE. */ +#define PRIV_NET_PPP 392 /* Administer PPP. */ +#define PRIV_NET_SLIP 393 /* Administer SLIP. */ +#define PRIV_NET_BPF 394 /* Monitor BPF. */ +#define PRIV_NET_RAW 395 /* Open raw socket. */ +#define PRIV_NET_ROUTE 396 /* Administer routing. */ +#define PRIV_NET_TAP 397 /* Can open tap device. */ +#define PRIV_NET_SETIFMTU 398 /* Set interface MTU. */ +#define PRIV_NET_SETIFFLAGS 399 /* Set interface flags. */ +#define PRIV_NET_SETIFCAP 400 /* Set interface capabilities. */ +#define PRIV_NET_SETIFNAME 401 /* Set interface name. */ +#define PRIV_NET_SETIFMETRIC 402 /* Set interface metrics. */ +#define PRIV_NET_SETIFPHYS 403 /* Set interface physical layer prop. */ +#define PRIV_NET_SETIFMAC 404 /* Set interface MAC label. */ +#define PRIV_NET_ADDMULTI 405 /* Add multicast addr. to ifnet. */ +#define PRIV_NET_DELMULTI 406 /* Delete multicast addr. from ifnet. */ +#define PRIV_NET_HWIOCTL 507 /* Issue hardware ioctl on ifnet. */ +#define PRIV_NET_SETLLADDR 508 +#define PRIV_NET_ADDIFGROUP 509 /* Add new interface group. */ +#define PRIV_NET_DELIFGROUP 510 /* Delete interface group. */ +#define PRIV_NET_IFCREATE 511 /* Create cloned interface. */ +#define PRIV_NET_IFDESTROY 512 /* Destroy cloned interface. */ +#define PRIV_NET_ADDIFADDR 513 /* Add protocol addr to interface. */ +#define PRIV_NET_DELIFADDR 514 /* Delete protocol addr on interface. */ + +/* + * 802.11-related privileges. + */ +#define PRIV_NET80211_GETKEY 540 /* Query 802.11 keys. */ +#define PRIV_NET80211_MANAGE 541 /* Administer 802.11. */ + +/* + * AppleTalk privileges. + */ +#define PRIV_NETATALK_RESERVEDPORT 550 /* Bind low port number. */ + +/* + * ATM privileges. + */ +#define PRIV_NETATM_CFG 560 +#define PRIV_NETATM_ADD 561 +#define PRIV_NETATM_DEL 562 +#define PRIV_NETATM_SET 563 + +/* + * Bluetooth privileges. + */ +#define PRIV_NETBLUETOOTH_RAW 570 /* Open raw bluetooth socket. */ + +/* + * Netgraph and netgraph module privileges. + */ +#define PRIV_NETGRAPH_CONTROL 580 /* Open netgraph control socket. */ +#define PRIV_NETGRAPH_TTY 581 /* Configure tty for netgraph. */ + +/* + * IPv4 and IPv6 privileges. + */ +#define PRIV_NETINET_RESERVEDPORT 590 /* Bind low port number. */ +#define PRIV_NETINET_IPFW 591 /* Administer IPFW firewall. */ +#define PRIV_NETINET_DIVERT 592 /* Open IP divert socket. */ +#define PRIV_NETINET_PF 593 /* Administer pf firewall. */ +#define PRIV_NETINET_DUMMYNET 594 /* Administer DUMMYNET. */ +#define PRIV_NETINET_CARP 595 /* Administer CARP. */ +#define PRIV_NETINET_MROUTE 596 /* Administer multicast routing. */ +#define PRIV_NETINET_RAW 597 /* Open netinet raw socket. */ +#define PRIV_NETINET_GETCRED 598 /* Query netinet pcb credentials. */ +#define PRIV_NETINET_ADDRCTRL6 599 /* Administer IPv6 address scopes. */ +#define PRIV_NETINET_ND6 600 /* Administer IPv6 neighbor disc. */ +#define PRIV_NETINET_SCOPE6 601 /* Administer IPv6 address scopes. */ +#define PRIV_NETINET_ALIFETIME6 602 /* Administer IPv6 address lifetimes. */ +#define PRIV_NETINET_IPSEC 603 /* Administer IPSEC. */ + +/* + * IPX/SPX privileges. + */ +#define PRIV_NETIPX_RESERVEDPORT 620 /* Bind low port number. */ +#define PRIV_NETIPX_RAW 621 /* Open netipx raw socket. */ + +/* + * NCP privileges. + */ +#define PRIV_NETNCP 630 /* Use another user's connection. */ + +/* + * SMB privileges. + */ +#define PRIV_NETSMB 640 /* Use another user's connection. */ + +/* + * VM86 privileges. + */ +#define PRIV_VM86_INTCALL 650/* Allow invoking vm86 int handlers. */ + +/* + * Set of reserved privilege values, which will be allocated to code as + * needed, in order to avoid renumbering later privileges due to insertion. + */ +#define _PRIV_RESERVED0 660 +#define _PRIV_RESERVED1 661 +#define _PRIV_RESERVED2 662 +#define _PRIV_RESERVED3 663 +#define _PRIV_RESERVED4 664 +#define _PRIV_RESERVED5 665 +#define _PRIV_RESERVED6 666 +#define _PRIV_RESERVED7 667 +#define _PRIV_RESERVED8 668 +#define _PRIV_RESERVED9 669 +#define _PRIV_RESERVED10 670 +#define _PRIV_RESERVED11 671 +#define _PRIV_RESERVED12 672 +#define _PRIV_RESERVED13 673 +#define _PRIV_RESERVED14 674 +#define _PRIV_RESERVED15 675 + +/* + * Define a set of valid privilege numbers that can be used by loadable + * modules that don't yet have privilege reservations. Ideally, these should + * not be used, since their meaning is opaque to any policies that are aware + * of specific privileges, such as jail, and as such may be arbitrarily + * denied. + */ +#define PRIV_MODULE0 700 +#define PRIV_MODULE1 701 +#define PRIV_MODULE2 702 +#define PRIV_MODULE3 703 +#define PRIV_MODULE4 704 +#define PRIV_MODULE5 705 +#define PRIV_MODULE6 706 +#define PRIV_MODULE7 707 +#define PRIV_MODULE8 708 +#define PRIV_MODULE9 709 +#define PRIV_MODULE10 710 +#define PRIV_MODULE11 711 +#define PRIV_MODULE12 712 +#define PRIV_MODULE13 713 +#define PRIV_MODULE14 714 +#define PRIV_MODULE15 715 + +/* + * Track end of privilege list. + */ +#define _PRIV_HIGHEST 716 + +/* + * Validate that a named privilege is known by the privilege system. Invalid + * privileges presented to the privilege system by a priv_check interface + * will result in a panic. This is only approximate due to sparse allocation + * of the privilege space. + */ +#define PRIV_VALID(x) ((x) > _PRIV_LOWEST && (x) < _PRIV_HIGHEST) + +#ifdef _KERNEL +/* + * Privilege check interfaces, modeled after historic suser() interfacs, but + * with the addition of a specific privilege name. The existing SUSER_* flag + * name space is used here. The jail flag will likely be something that can + * be removed at some point as jail itself will be able to decide if the priv + * is appropriate, rather than the caller. + */ +struct thread; +struct ucred; +int priv_check(struct thread *td, int priv); +int priv_check_cred(struct ucred *cred, int priv, int flags); +#endif + +#endif /* !_SYS_PRIV_H_ */ Index: sys/sys/systm.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/sys/systm.h,v retrieving revision 1.245 diff -u -r1.245 systm.h --- sys/sys/systm.h 17 Oct 2006 02:24:47 -0000 1.245 +++ sys/sys/systm.h 30 Oct 2006 17:07:56 -0000 @@ -230,7 +230,7 @@ #define SUSER_RUID 2 int suser(struct thread *td); -int suser_cred(struct ucred *cred, int flag); +int suser_cred(struct ucred *cred, int flags); int cr_cansee(struct ucred *u1, struct ucred *u2); int cr_canseesocket(struct ucred *cred, struct socket *so); Index: sys/ufs/ffs/ffs_alloc.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ffs/ffs_alloc.c,v retrieving revision 1.140 diff -u -r1.140 ffs_alloc.c --- sys/ufs/ffs/ffs_alloc.c 18 Jul 2006 07:03:43 -0000 1.140 +++ sys/ufs/ffs/ffs_alloc.c 30 Oct 2006 17:07:56 -0000 @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -171,7 +172,7 @@ #endif if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0) goto nospace; - if (suser_cred(cred, SUSER_ALLOWJAIL) && + if (priv_check_cred(cred, PRIV_VFS_BLOCKRESERVE, SUSER_ALLOWJAIL) && freespace(fs, fs->fs_minfree) - numfrags(fs, size) < 0) goto nospace; if (bpref >= fs->fs_size) @@ -259,7 +260,7 @@ #endif /* DIAGNOSTIC */ reclaimed = 0; retry: - if (suser_cred(cred, SUSER_ALLOWJAIL) && + if (priv_check_cred(cred, PRIV_VFS_BLOCKRESERVE, SUSER_ALLOWJAIL) && freespace(fs, fs->fs_minfree) - numfrags(fs, nsize - osize) < 0) { goto nospace; } Index: sys/ufs/ffs/ffs_vfsops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.321 diff -u -r1.321 ffs_vfsops.c --- sys/ufs/ffs/ffs_vfsops.c 22 Oct 2006 11:52:19 -0000 1.321 +++ sys/ufs/ffs/ffs_vfsops.c 30 Oct 2006 17:07:56 -0000 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -257,15 +258,16 @@ * If upgrade to read-write by non-root, then verify * that user has necessary permissions on the device. */ - if (suser(td)) { - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); - if ((error = VOP_ACCESS(devvp, VREAD | VWRITE, - td->td_ucred, td)) != 0) { - VOP_UNLOCK(devvp, 0, td); - return (error); - } + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); + error = VOP_ACCESS(devvp, VREAD | VWRITE, + td->td_ucred, td); + if (error) + error = priv_check(td, PRIV_VFS_MOUNT_PERM); + if (error) { VOP_UNLOCK(devvp, 0, td); + return (error); } + VOP_UNLOCK(devvp, 0, td); fs->fs_flags &= ~FS_UNCLEAN; if (fs->fs_clean == 0) { fs->fs_flags |= FS_UNCLEAN; @@ -364,14 +366,15 @@ * If mount by non-root, then verify that user has necessary * permissions on the device. */ - if (suser(td)) { - accessmode = VREAD; - if ((mp->mnt_flag & MNT_RDONLY) == 0) - accessmode |= VWRITE; - if ((error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td))!= 0){ - vput(devvp); - return (error); - } + accessmode = VREAD; + if ((mp->mnt_flag & MNT_RDONLY) == 0) + accessmode |= VWRITE; + error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td); + if (error) + error = priv_check(td, PRIV_VFS_MOUNT_PERM); + if (error) { + vput(devvp); + return (error); } if (mp->mnt_flag & MNT_UPDATE) { Index: sys/ufs/ffs/ffs_vnops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ffs/ffs_vnops.c,v retrieving revision 1.161 diff -u -r1.161 ffs_vnops.c --- sys/ufs/ffs/ffs_vnops.c 10 Oct 2006 09:20:54 -0000 1.161 +++ sys/ufs/ffs/ffs_vnops.c 30 Oct 2006 17:07:56 -0000 @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -781,7 +782,8 @@ * tampering. */ if (resid > uio->uio_resid && ap->a_cred && - suser_cred(ap->a_cred, SUSER_ALLOWJAIL)) { + priv_check_cred(ap->a_cred, PRIV_VFS_CLEARSUGID, + SUSER_ALLOWJAIL)) { ip->i_mode &= ~(ISUID | ISGID); DIP_SET(ip, i_mode, ip->i_mode); } @@ -1107,7 +1109,7 @@ * tampering. */ if (resid > uio->uio_resid && ucred && - suser_cred(ucred, SUSER_ALLOWJAIL)) { + priv_check_cred(ucred, PRIV_VFS_CLEARSUGID, SUSER_ALLOWJAIL)) { ip->i_mode &= ~(ISUID | ISGID); dp->di_mode = ip->i_mode; } Index: sys/ufs/ufs/ufs_extattr.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ufs/ufs_extattr.c,v retrieving revision 1.84 diff -u -r1.84 ufs_extattr.c --- sys/ufs/ufs/ufs_extattr.c 1 Feb 2006 00:25:26 -0000 1.84 +++ sys/ufs/ufs/ufs_extattr.c 30 Oct 2006 17:07:56 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -699,7 +700,8 @@ * Processes with privilege, but in jail, are not allowed to * configure extended attributes. */ - if ((error = suser(td))) { + error = priv_check(td, PRIV_UFS_EXTATTRCTL); + if (error) { if (filename_vp != NULL) VOP_UNLOCK(filename_vp, 0, td); return (error); Index: sys/ufs/ufs/ufs_quota.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ufs/ufs_quota.c,v retrieving revision 1.84 diff -u -r1.84 ufs_quota.c --- sys/ufs/ufs/ufs_quota.c 26 Sep 2006 04:12:49 -0000 1.84 +++ sys/ufs/ufs/ufs_quota.c 30 Oct 2006 17:07:56 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -165,7 +166,8 @@ } return (0); } - if ((flags & FORCE) == 0 && suser_cred(cred, 0)) { + if ((flags & FORCE) == 0 && priv_check_cred(cred, + PRIV_UFS_EXCEEDQUOTA, 0)) { for (i = 0; i < MAXQUOTAS; i++) { if ((dq = ip->i_dquot[i]) == NODQUOT) continue; @@ -288,7 +290,8 @@ } return (0); } - if ((flags & FORCE) == 0 && suser_cred(cred, 0)) { + if ((flags & FORCE) == 0 && priv_check_cred(cred, + PRIV_UFS_EXCEEDQUOTA, 0)) { for (i = 0; i < MAXQUOTAS; i++) { if ((dq = ip->i_dquot[i]) == NODQUOT) continue; @@ -423,7 +426,11 @@ int error, flags; struct nameidata nd; - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + /* + * XXXRW: Can this be right? Jail is allowed to do this? + */ + error = priv_check_cred(td->td_ucred, PRIV_UFS_QUOTAON, + SUSER_ALLOWJAIL); if (error) return (error); @@ -517,7 +524,11 @@ struct inode *ip; int error; - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + /* + * XXXRW: This also seems wrong to allow in a jail? + */ + error = priv_check_cred(td->td_ucred, PRIV_UFS_QUOTAOFF, + SUSER_ALLOWJAIL); if (error) return (error); @@ -589,15 +600,18 @@ switch (type) { case USRQUOTA: if ((td->td_ucred->cr_uid != id) && !unprivileged_get_quota) { - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(td->td_ucred, + PRIV_UFS_GETQUOTA, SUSER_ALLOWJAIL); if (error) return (error); } break; case GRPQUOTA: - if (!groupmember(id, td->td_ucred) && !unprivileged_get_quota) { - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + if (!groupmember(id, td->td_ucred) && + !unprivileged_get_quota) { + error = priv_check_cred(td->td_ucred, + PRIV_UFS_GETQUOTA, SUSER_ALLOWJAIL); if (error) return (error); } @@ -632,7 +646,8 @@ struct dqblk newlim; int error; - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(td->td_ucred, PRIV_UFS_SETQUOTA, + SUSER_ALLOWJAIL); if (error) return (error); @@ -698,7 +713,8 @@ struct dqblk usage; int error; - error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL); + error = priv_check_cred(td->td_ucred, PRIV_UFS_SETUSE, + SUSER_ALLOWJAIL); if (error) return (error); Index: sys/ufs/ufs/ufs_vnops.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/ufs/ufs/ufs_vnops.c,v retrieving revision 1.281 diff -u -r1.281 ufs_vnops.c --- sys/ufs/ufs/ufs_vnops.c 22 Oct 2006 11:52:19 -0000 1.281 +++ sys/ufs/ufs/ufs_vnops.c 30 Oct 2006 17:07:56 -0000 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -490,8 +491,11 @@ * processes if the security.jail.chflags_allowed sysctl is * is non-zero; otherwise, they behave like unprivileged * processes. + * + * XXXRW: Move implementation of jail_chflags_allowed to + * kern_jail.c. */ - if (!suser_cred(cred, + if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS, jail_chflags_allowed ? SUSER_ALLOWJAIL : 0)) { if (ip->i_flags & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) { @@ -582,10 +586,19 @@ * super-user. * If times is non-NULL, ... The caller must be the owner of * the file or be the super-user. + * + * Possibly for historical reasons, try to use VADMIN in + * preference to VADMIN for a NULL timestamp. This means we + * will return EACCES in preference to EPERM if neither + * check succeeds. */ - if ((error = VOP_ACCESS(vp, VADMIN, cred, td)) && - ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || - (error = VOP_ACCESS(vp, VWRITE, cred, td)))) + if (vap->va_vaflags & VA_UTIMES_NULL) { + error = VOP_ACCESS(vp, VADMIN, cred, td); + if (error) + error = VOP_ACCESS(vp, VWRITE, cred, td); + } else + error = VOP_ACCESS(vp, VADMIN, cred, td); + if (error) return (error); if (vap->va_atime.tv_sec != VNOVAL) ip->i_flag |= IN_ACCESS; @@ -651,11 +664,13 @@ * jail(8). */ if (vp->v_type != VDIR && (mode & S_ISTXT)) { - if (suser_cred(cred, SUSER_ALLOWJAIL)) + if (priv_check_cred(cred, PRIV_VFS_STICKYFILE, + SUSER_ALLOWJAIL)) return (EFTYPE); } if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) { - error = suser_cred(cred, SUSER_ALLOWJAIL); + error = priv_check_cred(cred, PRIV_VFS_SETGID, + SUSER_ALLOWJAIL); if (error) return (error); } @@ -692,19 +707,19 @@ if (gid == (gid_t)VNOVAL) gid = ip->i_gid; /* - * To modify the ownership of a file, must possess VADMIN - * for that file. + * To modify the ownership of a file, must possess VADMIN for that + * file. */ if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) return (error); /* - * To change the owner of a file, or change the group of a file - * to a group of which we are not a member, the caller must - * have privilege. + * To change the owner of a file, or change the group of a file to a + * group of which we are not a member, the caller must have + * privilege. */ if ((uid != ip->i_uid || (gid != ip->i_gid && !groupmember(gid, cred))) && - (error = suser_cred(cred, SUSER_ALLOWJAIL))) + (error = priv_check_cred(cred, PRIV_VFS_CHOWN, SUSER_ALLOWJAIL))) return (error); ogid = ip->i_gid; ouid = ip->i_uid; @@ -775,7 +790,8 @@ panic("ufs_chown: lost quota"); #endif /* QUOTA */ ip->i_flag |= IN_CHANGE; - if (suser_cred(cred, SUSER_ALLOWJAIL) && (ouid != uid || ogid != gid)) { + if (priv_check_cred(cred, PRIV_VFS_CLEARSUGID, SUSER_ALLOWJAIL) && + (ouid != uid || ogid != gid)) { ip->i_mode &= ~(ISUID | ISGID); DIP_SET(ip, i_mode, ip->i_mode); } @@ -2348,7 +2364,8 @@ if (DOINGSOFTDEP(tvp)) softdep_change_linkcnt(ip); if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) && - suser_cred(cnp->cn_cred, SUSER_ALLOWJAIL)) { + priv_check_cred(cnp->cn_cred, PRIV_VFS_SETGID, + SUSER_ALLOWJAIL)) { ip->i_mode &= ~ISGID; DIP_SET(ip, i_mode, ip->i_mode); } Index: sys/vm/swap_pager.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/vm/swap_pager.c,v retrieving revision 1.284 diff -u -r1.284 swap_pager.c --- sys/vm/swap_pager.c 23 Oct 2006 05:27:31 -0000 1.284 +++ sys/vm/swap_pager.c 30 Oct 2006 17:07:56 -0000 @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -1966,11 +1967,11 @@ struct nameidata nd; int error; - mtx_lock(&Giant); - error = suser(td); + error = priv_check(td, PRIV_SWAPON); if (error) - goto done2; + return (error); + mtx_lock(&Giant); while (swdev_syscall_active) tsleep(&swdev_syscall_active, PUSER - 1, "swpon", 0); swdev_syscall_active = 1; @@ -2009,7 +2010,6 @@ done: swdev_syscall_active = 0; wakeup_one(&swdev_syscall_active); -done2: mtx_unlock(&Giant); return (error); } @@ -2105,7 +2105,7 @@ struct swdevt *sp; int error; - error = suser(td); + error = priv_check(td, PRIV_SWAPOFF); if (error) return (error); Index: sys/vm/vm_mmap.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/vm/vm_mmap.c,v retrieving revision 1.207 diff -u -r1.207 vm_mmap.c --- sys/vm/vm_mmap.c 22 Oct 2006 11:52:19 -0000 1.207 +++ sys/vm/vm_mmap.c 30 Oct 2006 17:07:56 -0000 @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -684,7 +685,7 @@ * "immortal." */ if (uap->behav == MADV_PROTECT) { - error = suser(td); + error = priv_check(td, PRIV_VM_MADV_PROTECT); if (error == 0) { p = td->td_proc; PROC_LOCK(p); @@ -951,7 +952,7 @@ vm_size_t npages, size; int error; - error = suser(td); + error = priv_check(td, PRIV_VM_MLOCK); if (error) return (error); addr = (vm_offset_t)uap->addr; @@ -1016,7 +1017,7 @@ } PROC_UNLOCK(td->td_proc); #else - error = suser(td); + error = priv_check(td, PRIV_VM_MLOCK); if (error) return (error); #endif @@ -1061,7 +1062,7 @@ int error; map = &td->td_proc->p_vmspace->vm_map; - error = suser(td); + error = priv_check(td, PRIV_VM_MUNLOCK); if (error) return (error); @@ -1095,7 +1096,7 @@ vm_size_t size; int error; - error = suser(td); + error = priv_check(td, PRIV_VM_MUNLOCK); if (error) return (error); addr = (vm_offset_t)uap->addr;