summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-11-06 13:42:10 +0000
committerrwatson <rwatson@FreeBSD.org>2006-11-06 13:42:10 +0000
commit10d0d9cf473dc5f0ce1bf263ead445ffe7819154 (patch)
treeb9dd284620eeaddbff089cef10e4b1afb7918279
parent7288104e2094825a9c98b9923f039817a76e2983 (diff)
downloadFreeBSD-src-10d0d9cf473dc5f0ce1bf263ead445ffe7819154.zip
FreeBSD-src-10d0d9cf473dc5f0ce1bf263ead445ffe7819154.tar.gz
Sweep kernel replacing suser(9) calls with priv(9) calls, assigning
specific privilege names to a broad range of privileges. These may require some future tweaking. Sponsored by: nCircle Network Security, Inc. Obtained from: TrustedBSD Project Discussed on: arch@ Reviewed (at least in part) by: mlaier, jmg, pjd, bde, ceri, Alex Lyashkov <umka at sevcity dot net>, Skip Ford <skip dot ford at verizon dot net>, Antoine Brodin <antoine dot brodin at laposte dot net>
-rw-r--r--sys/amd64/amd64/io.c3
-rw-r--r--sys/compat/linux/linux_misc.c6
-rw-r--r--sys/compat/linux/linux_uid16.c4
-rw-r--r--sys/compat/svr4/svr4_fcntl.c4
-rw-r--r--sys/compat/svr4/svr4_misc.c4
-rw-r--r--sys/contrib/altq/altq/altq_cbq.c4
-rw-r--r--sys/contrib/altq/altq/altq_cdnr.c4
-rw-r--r--sys/contrib/altq/altq/altq_hfsc.c5
-rw-r--r--sys/contrib/altq/altq/altq_priq.c5
-rw-r--r--sys/contrib/altq/altq/altq_red.c4
-rw-r--r--sys/contrib/altq/altq/altq_rio.c5
-rw-r--r--sys/contrib/pf/net/if_pfsync.c5
-rw-r--r--sys/dev/an/if_an.c11
-rw-r--r--sys/dev/arl/if_arl.c7
-rw-r--r--sys/dev/asr/asr.c3
-rw-r--r--sys/dev/ata/atapi-cd.c6
-rw-r--r--sys/dev/ce/if_ce.c87
-rw-r--r--sys/dev/cnw/if_cnw.c7
-rw-r--r--sys/dev/cp/if_cp.c55
-rw-r--r--sys/dev/ctau/if_ct.c33
-rw-r--r--sys/dev/cx/if_cx.c21
-rw-r--r--sys/dev/dcons/dcons_os.c4
-rw-r--r--sys/dev/drm/drmP.h7
-rw-r--r--sys/dev/fdc/fdc.c6
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c19
-rw-r--r--sys/dev/if_ndis/if_ndis.c11
-rw-r--r--sys/dev/kbd/kbd.c19
-rw-r--r--sys/dev/lmc/if_lmc.c3
-rw-r--r--sys/dev/lmc/if_lmc.h6
-rw-r--r--sys/dev/nmdm/nmdm.c4
-rw-r--r--sys/dev/null/null.c3
-rw-r--r--sys/dev/ofw/ofw_console.c3
-rw-r--r--sys/dev/random/randomdev.c3
-rw-r--r--sys/dev/sbni/if_sbni.c5
-rw-r--r--sys/dev/sbsh/if_sbsh.c7
-rw-r--r--sys/dev/si/si.c3
-rw-r--r--sys/dev/syscons/syscons.c5
-rw-r--r--sys/dev/syscons/sysmouse.c4
-rw-r--r--sys/dev/wi/if_wi.c7
-rw-r--r--sys/dev/wl/if_wl.c11
-rw-r--r--sys/dev/zs/zs.c2
-rw-r--r--sys/fs/cd9660/cd9660_vfsops.c3
-rw-r--r--sys/fs/devfs/devfs_rule.c11
-rw-r--r--sys/fs/devfs/devfs_vnops.c24
-rw-r--r--sys/fs/hpfs/hpfs_vnops.c11
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c37
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c50
-rw-r--r--sys/fs/procfs/procfs_ioctl.c16
-rw-r--r--sys/fs/smbfs/smbfs_vnops.c12
-rw-r--r--sys/fs/udf/udf_vfsops.c3
-rw-r--r--sys/fs/umapfs/umap_vfsops.c3
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vfsops.c35
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vnops.c44
-rw-r--r--sys/gnu/fs/reiserfs/reiserfs_fs.h1
-rw-r--r--sys/gnu/fs/reiserfs/reiserfs_vfsops.c18
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_super.c19
-rw-r--r--sys/i386/i386/io.c3
-rw-r--r--sys/i386/i386/sys_machdep.c3
-rw-r--r--sys/i386/i386/vm86.c3
-rw-r--r--sys/i386/ibcs2/ibcs2_misc.c22
-rw-r--r--sys/i386/ibcs2/ibcs2_socksys.c3
-rw-r--r--sys/i386/ibcs2/ibcs2_sysi86.c2
-rw-r--r--sys/i386/linux/linux_machdep.c3
-rw-r--r--sys/i4b/driver/i4b_ipr.c2
-rw-r--r--sys/ia64/ia64/ssc.c3
-rw-r--r--sys/isofs/cd9660/cd9660_vfsops.c3
-rw-r--r--sys/kern/kern_acct.c4
-rw-r--r--sys/kern/kern_descrip.c3
-rw-r--r--sys/kern/kern_environment.c14
-rw-r--r--sys/kern/kern_exec.c6
-rw-r--r--sys/kern/kern_fork.c8
-rw-r--r--sys/kern/kern_ktrace.c6
-rw-r--r--sys/kern/kern_linker.c5
-rw-r--r--sys/kern/kern_ntptime.c5
-rw-r--r--sys/kern/kern_resource.c8
-rw-r--r--sys/kern/kern_shutdown.c3
-rw-r--r--sys/kern/kern_sysctl.c11
-rw-r--r--sys/kern/kern_thr.c3
-rw-r--r--sys/kern/kern_time.c5
-rw-r--r--sys/kern/kern_umtx.c5
-rw-r--r--sys/kern/kern_xxx.c10
-rw-r--r--sys/kern/p1003_1b.c8
-rw-r--r--sys/kern/subr_acl_posix1e.c91
-rw-r--r--sys/kern/subr_firmware.c4
-rw-r--r--sys/kern/subr_prf.c3
-rw-r--r--sys/kern/subr_witness.c6
-rw-r--r--sys/kern/sysv_ipc.c104
-rw-r--r--sys/kern/sysv_msg.c3
-rw-r--r--sys/kern/tty.c14
-rw-r--r--sys/kern/tty_cons.c3
-rw-r--r--sys/kern/tty_pts.c7
-rw-r--r--sys/kern/tty_pty.c7
-rw-r--r--sys/kern/uipc_mqueue.c20
-rw-r--r--sys/kern/uipc_sem.c17
-rw-r--r--sys/kern/vfs_extattr.c68
-rw-r--r--sys/kern/vfs_mount.c30
-rw-r--r--sys/kern/vfs_subr.c63
-rw-r--r--sys/kern/vfs_syscalls.c68
-rw-r--r--sys/kern/vfs_vnops.c3
-rw-r--r--sys/net/bpf.c3
-rw-r--r--sys/net/if.c34
-rw-r--r--sys/net/if_bridge.c3
-rw-r--r--sys/net/if_gre.c72
-rw-r--r--sys/net/if_ppp.c25
-rw-r--r--sys/net/if_sl.c3
-rw-r--r--sys/net/if_tap.c10
-rw-r--r--sys/net/if_tun.c9
-rw-r--r--sys/net/ppp_tty.c13
-rw-r--r--sys/net/raw_usrreq.c8
-rw-r--r--sys/net/rtsock.c8
-rw-r--r--sys/net80211/ieee80211_ioctl.c11
-rw-r--r--sys/netatalk/at_control.c2
-rw-r--r--sys/netatalk/ddp_pcb.c3
-rw-r--r--sys/netatm/atm_usrreq.c29
-rw-r--r--sys/netgraph/bluetooth/drivers/h4/ng_h4.c3
-rw-r--r--sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c3
-rw-r--r--sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c3
-rw-r--r--sys/netgraph/ng_socket.c7
-rw-r--r--sys/netgraph/ng_tty.c4
-rw-r--r--sys/netinet/in.c36
-rw-r--r--sys/netinet/in_pcb.c8
-rw-r--r--sys/netinet/ip_carp.c7
-rw-r--r--sys/netinet/ip_divert.c8
-rw-r--r--sys/netinet/ip_fw2.c3
-rw-r--r--sys/netinet/ip_mroute.c3
-rw-r--r--sys/netinet/ip_output.c17
-rw-r--r--sys/netinet/raw_ip.c33
-rw-r--r--sys/netinet/tcp_subr.c7
-rw-r--r--sys/netinet/tcp_timewait.c7
-rw-r--r--sys/netinet/udp_usrreq.c4
-rw-r--r--sys/netinet6/in6.c58
-rw-r--r--sys/netinet6/in6_pcb.c7
-rw-r--r--sys/netinet6/in6_src.c5
-rw-r--r--sys/netinet6/ipsec.c11
-rw-r--r--sys/netinet6/udp6_usrreq.c4
-rw-r--r--sys/netipsec/ipsec_osdep.h4
-rw-r--r--sys/netipx/ipx_pcb.c8
-rw-r--r--sys/netipx/ipx_usrreq.c10
-rw-r--r--sys/netncp/ncp_conn.c1
-rw-r--r--sys/netncp/ncp_mod.c1
-rw-r--r--sys/netncp/ncp_subr.h2
-rw-r--r--sys/netsmb/smb_conn.c1
-rw-r--r--sys/netsmb/smb_subr.h2
-rw-r--r--sys/nfsserver/nfs_syscalls.c3
-rw-r--r--sys/pc98/cbus/fdc.c7
-rw-r--r--sys/posix4/p1003_1b.c8
-rw-r--r--sys/security/audit/audit.c4
-rw-r--r--sys/security/audit/audit_pipe.c6
-rw-r--r--sys/security/audit/audit_syscalls.c19
-rw-r--r--sys/security/mac/mac_net.c9
-rw-r--r--sys/security/mac/mac_policy.h4
-rw-r--r--sys/security/mac/mac_system.c6
-rw-r--r--sys/security/mac_bsdextended/mac_bsdextended.c3
-rw-r--r--sys/security/mac_lomac/mac_lomac.c5
-rw-r--r--sys/security/mac_partition/mac_partition.c3
-rw-r--r--sys/security/mac_portacl/mac_portacl.c4
-rw-r--r--sys/security/mac_seeotheruids/mac_seeotheruids.c3
-rw-r--r--sys/sun4v/sun4v/hvcons.c4
-rw-r--r--sys/sys/mac_policy.h4
-rw-r--r--sys/ufs/ffs/ffs_alloc.c5
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c33
-rw-r--r--sys/ufs/ffs/ffs_vnops.c6
-rw-r--r--sys/ufs/ufs/ufs_extattr.c4
-rw-r--r--sys/ufs/ufs/ufs_quota.c34
-rw-r--r--sys/ufs/ufs/ufs_vnops.c45
-rw-r--r--sys/vm/swap_pager.c10
-rw-r--r--sys/vm/vm_mmap.c11
167 files changed, 1367 insertions, 737 deletions
diff --git a/sys/amd64/amd64/io.c b/sys/amd64/amd64/io.c
index 1aaf2ef..02d9c8d 100644
--- a/sys/amd64/amd64/io.c
+++ b/sys/amd64/amd64/io.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/systm.h>
@@ -54,7 +55,7 @@ ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
{
int error;
- error = suser(td);
+ error = priv_check(td, PRIV_IO);
if (error != 0)
return (error);
error = securelevel_gt(td->td_ucred, 0);
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 962e94f..cab95c7 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/resourcevar.h>
@@ -1020,7 +1021,8 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
* 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 @@ linux_reboot(struct thread *td, struct linux_reboot_args *args)
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;
diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c
index ba01aef..ec15826 100644
--- a/sys/compat/linux/linux_uid16.c
+++ b/sys/compat/linux/linux_uid16.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
@@ -123,7 +124,8 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
* 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);
diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c
index ca135f0..6073e0d 100644
--- a/sys/compat/svr4/svr4_fcntl.c
+++ b/sys/compat/svr4/svr4_fcntl.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/syscallsubr.h>
@@ -280,7 +281,8 @@ fd_revoke(td, fd)
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)
diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c
index 9ed5bb3..f1f44ea 100644
--- a/sys/compat/svr4/svr4_misc.c
+++ b/sys/compat/svr4/svr4_misc.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/msg.h>
#include <sys/mutex.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/ptrace.h>
#include <sys/resource.h>
@@ -611,7 +612,8 @@ svr4_sys_fchroot(td, uap)
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;
diff --git a/sys/contrib/altq/altq/altq_cbq.c b/sys/contrib/altq/altq/altq_cbq.c
index ef75916..aafa5c8 100644
--- a/sys/contrib/altq/altq/altq_cbq.c
+++ b/sys/contrib/altq/altq/altq_cbq.c
@@ -1062,7 +1062,9 @@ cbqioctl(dev, cmd, addr, flag, p)
/* 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);
diff --git a/sys/contrib/altq/altq/altq_cdnr.c b/sys/contrib/altq/altq/altq_cdnr.c
index d0a1313..3139d51 100644
--- a/sys/contrib/altq/altq/altq_cdnr.c
+++ b/sys/contrib/altq/altq/altq_cdnr.c
@@ -1262,7 +1262,9 @@ cdnrioctl(dev, cmd, addr, flag, p)
case CDNR_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)
diff --git a/sys/contrib/altq/altq/altq_hfsc.c b/sys/contrib/altq/altq/altq_hfsc.c
index 7eea5c7..8fea4dd 100644
--- a/sys/contrib/altq/altq/altq_hfsc.c
+++ b/sys/contrib/altq/altq/altq_hfsc.c
@@ -1975,7 +1975,10 @@ hfscioctl(dev, cmd, addr, flag, p)
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
diff --git a/sys/contrib/altq/altq/altq_priq.c b/sys/contrib/altq/altq/altq_priq.c
index e4e84e6..28b0ddb 100644
--- a/sys/contrib/altq/altq/altq_priq.c
+++ b/sys/contrib/altq/altq/altq_priq.c
@@ -772,7 +772,10 @@ priqioctl(dev, cmd, addr, flag, p)
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
diff --git a/sys/contrib/altq/altq/altq_red.c b/sys/contrib/altq/altq/altq_red.c
index ff6d832..6010033 100644
--- a/sys/contrib/altq/altq/altq_red.c
+++ b/sys/contrib/altq/altq/altq_red.c
@@ -781,7 +781,9 @@ redioctl(dev, cmd, addr, flag, p)
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)
diff --git a/sys/contrib/altq/altq/altq_rio.c b/sys/contrib/altq/altq/altq_rio.c
index 2acf87e..a05dba7 100644
--- a/sys/contrib/altq/altq/altq_rio.c
+++ b/sys/contrib/altq/altq/altq_rio.c
@@ -531,7 +531,10 @@ rioioctl(dev, cmd, addr, flag, p)
case RIO_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
diff --git a/sys/contrib/pf/net/if_pfsync.c b/sys/contrib/pf/net/if_pfsync.c
index 957bc7e..bec33e4 100644
--- a/sys/contrib/pf/net/if_pfsync.c
+++ b/sys/contrib/pf/net/if_pfsync.c
@@ -54,6 +54,9 @@
#endif
#include <sys/param.h>
+#ifdef __FreeBSD__
+#include <sys/priv.h>
+#endif
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/time.h>
@@ -1057,7 +1060,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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
diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c
index 0dc49b4..224d51f 100644
--- a/sys/dev/an/if_an.c
+++ b/sys/dev/an/if_an.c
@@ -92,6 +92,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/socket.h>
@@ -1920,7 +1921,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
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 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
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_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
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 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
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 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
break;
case SIOCS80211:
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_NET80211_MANAGE)))
goto out;
sc->areq.an_len = sizeof(sc->areq);
/*
diff --git a/sys/dev/arl/if_arl.c b/sys/dev/arl/if_arl.c
index 75ab4fd..62d9afa 100644
--- a/sys/dev/arl/if_arl.c
+++ b/sys/dev/arl/if_arl.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/conf.h>
@@ -504,7 +505,7 @@ arl_ioctl(ifp, cmd, data)
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 @@ arl_ioctl(ifp, cmd, data)
}
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 @@ arl_ioctl(ifp, cmd, data)
} while (0)
case SIOCSARLALL:
- if (suser(td))
+ if (priv_check(td, PRIV_DRIVER))
break;
user = (void *)ifr->ifr_data;
diff --git a/sys/dev/asr/asr.c b/sys/dev/asr/asr.c
index 85cd848..2d5e062 100644
--- a/sys/dev/asr/asr.c
+++ b/sys/dev/asr/asr.c
@@ -117,6 +117,7 @@
#include <sys/malloc.h>
#include <sys/conf.h>
#include <sys/ioccom.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/bus.h>
#include <machine/resource.h>
@@ -3125,7 +3126,7 @@ asr_open(struct cdev *dev, int32_t flags, int32_t ifmt, struct thread *td)
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);
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index 1fd0929..cca1623 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/bio.h>
#include <sys/bus.h>
@@ -257,8 +258,11 @@ acd_geom_ioctl(struct g_provider *pp, u_long cmd, void *addr, int fflag, struct
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);
diff --git a/sys/dev/ce/if_ce.c b/sys/dev/ce/if_ce.c
index d072179..b81d226 100644
--- a/sys/dev/ce/if_ce.c
+++ b/sys/dev/ce/if_ce.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#if NPCI > 0
#include <sys/ucred.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@@ -1341,9 +1342,11 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
/* 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;
diff --git a/sys/dev/cnw/if_cnw.c b/sys/dev/cnw/if_cnw.c
index 2d97c36..cbc86f0 100644
--- a/sys/dev/cnw/if_cnw.c
+++ b/sys/dev/cnw/if_cnw.c
@@ -236,6 +236,7 @@ struct cfattach cnw_ca = {
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/ucred.h>
#include <sys/socket.h>
@@ -1339,7 +1340,7 @@ cnw_ioctl(ifp, cmd, data)
#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 @@ cnw_ioctl(ifp, cmd, data)
#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 @@ cnw_ioctl(ifp, cmd, data)
#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;
diff --git a/sys/dev/cp/if_cp.c b/sys/dev/cp/if_cp.c
index d995c01..fefe9e6 100644
--- a/sys/dev/cp/if_cp.c
+++ b/sys/dev/cp/if_cp.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/conf.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
@@ -1071,7 +1072,7 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 ();
diff --git a/sys/dev/ctau/if_ct.c b/sys/dev/ctau/if_ct.c
index 4d22f49..d46ef89 100644
--- a/sys/dev/ctau/if_ct.c
+++ b/sys/dev/ctau/if_ct.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/sockio.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/conf.h>
@@ -1300,7 +1301,7 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int ct_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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)
diff --git a/sys/dev/cx/if_cx.c b/sys/dev/cx/if_cx.c
index a48f76b..be136b3 100644
--- a/sys/dev/cx/if_cx.c
+++ b/sys/dev/cx/if_cx.c
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/mbuf.h>
#include <sys/sockio.h>
@@ -1632,7 +1633,7 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
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 ();
diff --git a/sys/dev/dcons/dcons_os.c b/sys/dev/dcons/dcons_os.c
index 38803ac..a6d78aa 100644
--- a/sys/dev/dcons/dcons_os.c
+++ b/sys/dev/dcons/dcons_os.c
@@ -48,6 +48,7 @@
#include <sys/consio.h>
#include <sys/tty.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/ucred.h>
@@ -293,7 +294,8 @@ dcons_open(DEV dev, int flag, int mode, THREAD *td)
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);
}
diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h
index 1171425..8e2855a 100644
--- a/sys/dev/drm/drmP.h
+++ b/sys/dev/drm/drmP.h
@@ -50,6 +50,9 @@ typedef struct drm_file drm_file_t;
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/stat.h>
+#if __FreeBSD_version >= 700000
+#include <sys/priv.h>
+#endif
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/fcntl.h>
@@ -233,7 +236,11 @@ enum {
#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
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index 0ee2deb..4f48ead 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
@@ -1489,8 +1490,9 @@ fd_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread
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);
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 37d272a..c61314c 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/pmc.h>
#include <sys/pmckern.h>
#include <sys/pmclog.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/resourcevar.h>
@@ -2782,10 +2783,9 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
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 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
*/
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)
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index 6532978..d90bd70 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/queue.h>
@@ -2836,7 +2837,7 @@ ndis_ioctl(ifp, command, data)
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 @@ ndis_ioctl(ifp, command, data)
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 @@ ndis_ioctl(ifp, command, data)
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 @@ ndis_wi_ioctl_set(ifp, command, data)
uint32_t foo;
int error, len;
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_DRIVER);
if (error)
return (error);
@@ -3370,7 +3371,7 @@ ndis_80211_ioctl_set(struct ifnet *ifp, u_long command, caddr_t data)
break;
#endif
case IEEE80211_IOC_STATIONNAME:
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NET80211_MANAGE);
if (error)
break;
if (ireq->i_val != 0 ||
diff --git a/sys/dev/kbd/kbd.c b/sys/dev/kbd/kbd.c
index 1c004c3..462983f 100644
--- a/sys/dev/kbd/kbd.c
+++ b/sys/dev/kbd/kbd.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/fcntl.h>
#include <sys/tty.h>
#include <sys/poll.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/uio.h>
@@ -972,11 +973,11 @@ key_change_ok(struct keyent_t *oldkey, struct keyent_t *newkey, struct thread *t
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 @@ key_change_ok(struct keyent_t *oldkey, struct keyent_t *newkey, struct thread *t
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 @@ accent_change_ok(accentmap_t *oldmap, accentmap_t *newmap, struct thread *td)
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 @@ fkey_change_ok(fkeytab_t *oldkey, fkeyarg_t *newkey, struct thread *td)
if (oldkey->len != newkey->flen ||
bcmp(oldkey->str, newkey->keydef, oldkey->len) != 0)
- return suser(td);
+ return priv_check(td, PRIV_KEYBOARD);
return (0);
}
diff --git a/sys/dev/lmc/if_lmc.c b/sys/dev/lmc/if_lmc.c
index 35ce7a9..f970d31 100644
--- a/sys/dev/lmc/if_lmc.c
+++ b/sys/dev/lmc/if_lmc.c
@@ -113,6 +113,9 @@
# include <sys/rman.h>
# include <vm/vm.h>
# include <vm/pmap.h>
+# if (__FreeBSD_version >= 700000)
+# include <sys/priv.h>
+# endif
# if (__FreeBSD_version >= 500000)
# include <sys/mutex.h>
# include <dev/pci/pcivar.h>
diff --git a/sys/dev/lmc/if_lmc.h b/sys/dev/lmc/if_lmc.h
index 85dfc55..140750d 100644
--- a/sys/dev/lmc/if_lmc.h
+++ b/sys/dev/lmc/if_lmc.h
@@ -1223,7 +1223,11 @@ struct softc
# 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)
diff --git a/sys/dev/nmdm/nmdm.c b/sys/dev/nmdm/nmdm.c
index fb9648b..31b1805 100644
--- a/sys/dev/nmdm/nmdm.c
+++ b/sys/dev/nmdm/nmdm.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/tty.h>
#include <sys/conf.h>
@@ -286,7 +287,8 @@ nmdmopen(struct cdev *dev, int flag, int devtype, struct thread *td)
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);
}
diff --git a/sys/dev/null/null.c b/sys/dev/null/null.c
index ee42a1c..0b94eb7 100644
--- a/sys/dev/null/null.c
+++ b/sys/dev/null/null.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
+#include <sys/priv.h>
#include <sys/disk.h>
#include <sys/bus.h>
#include <machine/bus.h>
@@ -87,7 +88,7 @@ null_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data __unused,
if (cmd != DIOCSKERNELDUMP)
return (ENOIOCTL);
- error = suser(td);
+ error = priv_check(td, PRIV_SETDUMPER);
if (error)
return (error);
return (set_dumper(NULL));
diff --git a/sys/dev/ofw/ofw_console.c b/sys/dev/ofw/ofw_console.c
index e305e7b..33ee0d6 100644
--- a/sys/dev/ofw/ofw_console.c
+++ b/sys/dev/ofw/ofw_console.c
@@ -140,7 +140,8 @@ ofw_dev_open(struct cdev *dev, int flag, int mode, struct thread *td)
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);
}
diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c
index 4d2b1bb..7cc78e6 100644
--- a/sys/dev/random/randomdev.c
+++ b/sys/dev/random/randomdev.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/poll.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/selinfo.h>
#include <sys/uio.h>
@@ -85,7 +86,7 @@ static int
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;
diff --git a/sys/dev/sbni/if_sbni.c b/sys/dev/sbni/if_sbni.c
index 282a5ea..3e1296f 100644
--- a/sys/dev/sbni/if_sbni.c
+++ b/sys/dev/sbni/if_sbni.c
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/callout.h>
#include <sys/syslog.h>
@@ -1110,7 +1111,7 @@ sbni_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
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 @@ sbni_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
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;
diff --git a/sys/dev/sbsh/if_sbsh.c b/sys/dev/sbsh/if_sbsh.c
index 2970474..c23f889 100644
--- a/sys/dev/sbsh/if_sbsh.c
+++ b/sys/dev/sbsh/if_sbsh.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/random.h>
@@ -424,7 +425,7 @@ sbsh_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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 @@ sbsh_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCGETSTATS :
- if ((error = suser(curthread)) != 0)
+ if ((error = priv_check(curthread, PRIV_DRIVER)) != 0)
break;
t = 0;
@@ -478,7 +479,7 @@ sbsh_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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))
diff --git a/sys/dev/si/si.c b/sys/dev/si/si.c
index e821a9e..584e851 100644
--- a/sys/dev/si/si.c
+++ b/sys/dev/si/si.c
@@ -53,6 +53,7 @@ static const char si_copyright1[] = "@(#) Copyright (C) Specialix International
#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/sysctl.h>
#include <sys/bus.h>
#include <machine/bus.h>
@@ -650,7 +651,7 @@ si_Sioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
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:
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 4976896..87ada19 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/random.h>
#include <sys/reboot.h>
@@ -517,7 +518,7 @@ scopen(struct cdev *dev, int flag, int mode, struct thread *td)
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 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
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);
diff --git a/sys/dev/syscons/sysmouse.c b/sys/dev/syscons/sysmouse.c
index 394351e..fa89a23 100644
--- a/sys/dev/syscons/sysmouse.c
+++ b/sys/dev/syscons/sysmouse.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
+#include <sys/priv.h>
#include <sys/tty.h>
#include <sys/kernel.h>
#include <sys/consio.h>
@@ -83,7 +84,8 @@ smopen(struct cdev *dev, int flag, int mode, struct thread *td)
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;
}
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index 5a52a5f..2b767a3 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <sys/sockio.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/socket.h>
@@ -1273,7 +1274,7 @@ wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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 @@ wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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 @@ wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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 ||
diff --git a/sys/dev/wl/if_wl.c b/sys/dev/wl/if_wl.c
index 81cef7b..cf131f8 100644
--- a/sys/dev/wl/if_wl.c
+++ b/sys/dev/wl/if_wl.c
@@ -197,6 +197,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <machine/bus.h>
@@ -1310,7 +1311,7 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
/* 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 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
/* 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 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
*/
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 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
/* 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 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
/* 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;
diff --git a/sys/dev/zs/zs.c b/sys/dev/zs/zs.c
index 199a26e..21195a2 100644
--- a/sys/dev/zs/zs.c
+++ b/sys/dev/zs/zs.c
@@ -453,7 +453,7 @@ zsttyopen(struct cdev *dev, int flags, int mode, struct thread *td)
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) {
diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c
index 9a5e836..58f2add 100644
--- a/sys/fs/cd9660/cd9660_vfsops.c
+++ b/sys/fs/cd9660/cd9660_vfsops.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
@@ -174,7 +175,7 @@ cd9660_mount(struct mount *mp, struct thread *td)
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);
diff --git a/sys/fs/devfs/devfs_rule.c b/sys/fs/devfs/devfs_rule.c
index a0caad9..f6aef03 100644
--- a/sys/fs/devfs/devfs_rule.c
+++ b/sys/fs/devfs/devfs_rule.c
@@ -67,6 +67,7 @@
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/dirent.h>
#include <sys/ioccom.h>
#include <sys/lock.h>
@@ -164,11 +165,13 @@ devfs_rules_ioctl(struct devfs_mount *dm, u_long cmd, caddr_t data, struct threa
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);
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 6ae4467..47cc01c 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -55,6 +55,7 @@
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/sx.h>
@@ -1145,19 +1146,25 @@ devfs_setattr(struct vop_setattr_args *ap)
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 @@ devfs_symlink(struct vop_symlink_args *ap)
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);
diff --git a/sys/fs/hpfs/hpfs_vnops.c b/sys/fs/hpfs/hpfs_vnops.c
index 4c73fe4..550f613 100644
--- a/sys/fs/hpfs/hpfs_vnops.c
+++ b/sys/fs/hpfs/hpfs_vnops.c
@@ -501,11 +501,12 @@ hpfs_setattr(ap)
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)
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index c0963cb..b6d81f4 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -52,6 +52,7 @@
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
@@ -293,17 +294,17 @@ msdosfs_mount(struct mount *mp, struct thread *td)
* 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 @@ msdosfs_mount(struct mount *mp, struct thread *td)
* 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);
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index e7a64e7..ae17f89 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -59,6 +59,7 @@
#include <sys/conf.h>
#include <sys/clock.h>
#include <sys/buf.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/unistd.h>
@@ -404,9 +405,12 @@ msdosfs_setattr(ap)
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 @@ msdosfs_setattr(ap)
* 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 @@ msdosfs_setattr(ap)
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 @@ msdosfs_setattr(ap)
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 @@ msdosfs_setattr(ap)
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)
diff --git a/sys/fs/procfs/procfs_ioctl.c b/sys/fs/procfs/procfs_ioctl.c
index 3808a2b..04fe603 100644
--- a/sys/fs/procfs/procfs_ioctl.c
+++ b/sys/fs/procfs/procfs_ioctl.c
@@ -34,6 +34,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/pioctl.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/systm.h>
@@ -104,8 +105,19 @@ procfs_ioctl(PFS_IOCTL_ARGS)
#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:
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c
index f65d2e0..bfac2aa 100644
--- a/sys/fs/smbfs/smbfs_vnops.c
+++ b/sys/fs/smbfs/smbfs_vnops.c
@@ -366,11 +366,13 @@ smbfs_setattr(ap)
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;
diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c
index 672bdeb..d21301e 100644
--- a/sys/fs/udf/udf_vfsops.c
+++ b/sys/fs/udf/udf_vfsops.c
@@ -84,6 +84,7 @@
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/vnode.h>
@@ -238,7 +239,7 @@ udf_mount(struct mount *mp, struct thread *td)
/* 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);
diff --git a/sys/fs/umapfs/umap_vfsops.c b/sys/fs/umapfs/umap_vfsops.c
index a692998..694ce33 100644
--- a/sys/fs/umapfs/umap_vfsops.c
+++ b/sys/fs/umapfs/umap_vfsops.c
@@ -88,7 +88,8 @@ umapfs_omount(mp, path, data, ndp, td)
/*
* Only for root
*/
- if ((error = suser(td)) != 0)
+ error = priv_check(td, PRIV_VFS_MOUNT);
+ if (error)
return (error);
#ifdef DEBUG
diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c
index 4fdc727..c1b58cb 100644
--- a/sys/gnu/fs/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c
@@ -57,6 +57,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
@@ -197,15 +198,16 @@ ext2_mount(mp, td)
* 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 @@ ext2_mount(mp, td)
/*
* 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) {
diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c
index c755f66..4ea62c6 100644
--- a/sys/gnu/fs/ext2fs/ext2_vnops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vnops.c
@@ -52,6 +52,7 @@
#include <sys/stat.h>
#include <sys/bio.h>
#include <sys/buf.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/unistd.h>
@@ -411,7 +412,8 @@ ext2_setattr(ap)
* 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 @@ ext2_chmod(vp, mode, cred, td)
* 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 @@ ext2_chown(vp, uid, gid, cred, td)
* 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 @@ ext2_makeinode(mode, dvp, vpp, cnp)
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;
diff --git a/sys/gnu/fs/reiserfs/reiserfs_fs.h b/sys/gnu/fs/reiserfs/reiserfs_fs.h
index 691f612..b33995f 100644
--- a/sys/gnu/fs/reiserfs/reiserfs_fs.h
+++ b/sys/gnu/fs/reiserfs/reiserfs_fs.h
@@ -18,6 +18,7 @@
#include <sys/kernel.h>
#include <sys/mount.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/unistd.h>
diff --git a/sys/gnu/fs/reiserfs/reiserfs_vfsops.c b/sys/gnu/fs/reiserfs/reiserfs_vfsops.c
index 066d5b2..4ace2da 100644
--- a/sys/gnu/fs/reiserfs/reiserfs_vfsops.c
+++ b/sys/gnu/fs/reiserfs/reiserfs_vfsops.c
@@ -125,15 +125,15 @@ reiserfs_mount(struct mount *mp, struct thread *td)
/* 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) {
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_super.c b/sys/gnu/fs/xfs/FreeBSD/xfs_super.c
index f840297..97c6586 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_super.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_super.c
@@ -53,6 +53,8 @@
#include "xfs_version.h"
#include "xfs_buf.h"
+#include <sys/priv.h>
+
#include <geom/geom.h>
#include <geom/geom_vfs.h>
@@ -149,14 +151,15 @@ xfs_blkdev_get(
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();
diff --git a/sys/i386/i386/io.c b/sys/i386/i386/io.c
index 1c0866d..eb0deb6 100644
--- a/sys/i386/i386/io.c
+++ b/sys/i386/i386/io.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/systm.h>
@@ -54,7 +55,7 @@ ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
{
int error;
- error = suser(td);
+ error = priv_check(td, PRIV_IO);
if (error != 0)
return (error);
error = securelevel_gt(td->td_ucred, 0);
diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c
index d633736..f53f49a 100644
--- a/sys/i386/i386/sys_machdep.c
+++ b/sys/i386/i386/sys_machdep.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/smp.h>
#include <sys/sysproto.h>
@@ -292,7 +293,7 @@ i386_set_ioperm(td, uap)
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);
diff --git a/sys/i386/i386/vm86.c b/sys/i386/i386/vm86.c
index e22929b..875b775 100644
--- a/sys/i386/i386/vm86.c
+++ b/sys/i386/i386/vm86.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -724,7 +725,7 @@ vm86_sysarch(td, args)
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);
diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c
index 164c369..46542ba1 100644
--- a/sys/i386/ibcs2/ibcs2_misc.c
+++ b/sys/i386/ibcs2/ibcs2_misc.c
@@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/file.h> /* Must come after sys/malloc.h */
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/reboot.h>
#include <sys/resourcevar.h>
#include <sys/stat.h>
@@ -1008,14 +1009,22 @@ ibcs2_plock(td, uap)
#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 @@ ibcs2_uadmin(td, uap)
#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 @@ ibcs2_uadmin(td, uap)
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:
diff --git a/sys/i386/ibcs2/ibcs2_socksys.c b/sys/i386/ibcs2/ibcs2_socksys.c
index 515f318..f4939cf 100644
--- a/sys/i386/ibcs2/ibcs2_socksys.c
+++ b/sys/i386/ibcs2/ibcs2_socksys.c
@@ -174,9 +174,6 @@ ibcs2_setipdomainname(td, uap)
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;
diff --git a/sys/i386/ibcs2/ibcs2_sysi86.c b/sys/i386/ibcs2/ibcs2_sysi86.c
index 12321d1..4d76218 100644
--- a/sys/i386/ibcs2/ibcs2_sysi86.c
+++ b/sys/i386/ibcs2/ibcs2_sysi86.c
@@ -76,8 +76,6 @@ ibcs2_sysi86(struct thread *td, struct ibcs2_sysi86_args *args)
int name[2];
int error;
- if ((error = suser(td)))
- return (error);
name[0] = CTL_KERN;
name[1] = KERN_HOSTNAME;
mtx_lock(&Giant);
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c
index 5839411..0129bd0 100644
--- a/sys/i386/linux/linux_machdep.c
+++ b/sys/i386/linux/linux_machdep.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mman.h>
#include <sys/mutex.h>
#include <sys/sx.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/resource.h>
@@ -812,7 +813,7 @@ linux_iopl(struct thread *td, struct linux_iopl_args *args)
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);
diff --git a/sys/i4b/driver/i4b_ipr.c b/sys/i4b/driver/i4b_ipr.c
index 7fbebc8..537ef3d 100644
--- a/sys/i4b/driver/i4b_ipr.c
+++ b/sys/i4b/driver/i4b_ipr.c
@@ -490,7 +490,7 @@ i4biprioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
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);
}
diff --git a/sys/ia64/ia64/ssc.c b/sys/ia64/ia64/ssc.c
index d5e6d97..42a995c 100644
--- a/sys/ia64/ia64/ssc.c
+++ b/sys/ia64/ia64/ssc.c
@@ -147,7 +147,8 @@ ssc_open(struct cdev *dev, int flag, int mode, struct thread *td)
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;
}
diff --git a/sys/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c
index 9a5e836..58f2add 100644
--- a/sys/isofs/cd9660/cd9660_vfsops.c
+++ b/sys/isofs/cd9660/cd9660_vfsops.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
@@ -174,7 +175,7 @@ cd9660_mount(struct mount *mp, struct thread *td)
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);
diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c
index ec7289f..e3b108c 100644
--- a/sys/kern/kern_acct.c
+++ b/sys/kern/kern_acct.c
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/sched.h>
@@ -166,8 +167,7 @@ acct(struct thread *td, struct acct_args *uap)
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);
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index b62c977..685222c 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mqueue.h>
#include <sys/mutex.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
@@ -1351,7 +1352,7 @@ falloc(struct thread *td, struct file **resultfp, int *resultfd)
sx_xlock(&filelist_lock);
if ((openfiles >= maxuserfiles &&
- suser_cred(td->td_ucred, SUSER_RUID) != 0) ||
+ 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",
diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c
index ff26529..1d33626 100644
--- a/sys/kern/kern_environment.c
+++ b/sys/kern/kern_environment.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/sysent.h>
@@ -125,11 +126,18 @@ kenv(td, uap)
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);
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index e513908..75843eb 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <sys/imgact_elf.h>
#include <sys/wait.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/pioctl.h>
#include <sys/namei.h>
@@ -571,8 +572,11 @@ interpret:
* 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;
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index e92720b..9c5597e 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/pioctl.h>
#include <sys/resourcevar.h>
@@ -310,7 +311,7 @@ fork1(td, flags, pages, procp)
*/
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 @@ fork1(td, flags, pages, procp)
/*
* 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 {
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index e79fa7c..b5a4456 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
@@ -807,7 +808,8 @@ ktrops(td, p, ops, facs, vp)
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 @@ ktrcanset(td, targetp)
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)
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index 0bdd9f8..6d0dd0f 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/sysproto.h>
#include <sys/sysent.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -854,7 +855,7 @@ kern_kldload(struct thread *td, const char *file, int *fileid)
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 @@ kern_kldunload(struct thread *td, int fileid, int flags)
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();
diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c
index 53deb9f..87d10d7 100644
--- a/sys/kern/kern_ntptime.c
+++ b/sys/kern/kern_ntptime.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/kernel.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -333,7 +334,7 @@ ntp_adjtime(struct thread *td, struct ntp_adjtime_args *uap)
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 @@ kern_adjtime(struct thread *td, struct timeval *delta, struct timeval *olddelta)
struct timeval atv;
int error;
- if ((error = suser(td)))
+ if ((error = priv_check(td, PRIV_ADJTIME)))
return (error);
mtx_lock(&Giant);
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 524631f..3ba110f 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/refcount.h>
#include <sys/resourcevar.h>
@@ -264,7 +265,7 @@ donice(struct thread *td, struct proc *p, int n)
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 @@ rtprio(td, uap)
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 @@ kern_setrlimit(td, which, limp)
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);
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index a5bcfa8..a20daa7 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kthread.h>
#include <sys/malloc.h>
#include <sys/mount.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/resourcevar.h>
@@ -164,7 +165,7 @@ reboot(struct thread *td, struct reboot_args *uap)
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);
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index a929291..6015551 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -512,7 +513,7 @@ sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS)
{
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 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
/* 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);
}
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index bfa1e2b..72798ac 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/sched.h>
@@ -164,7 +165,7 @@ create_thread(struct thread *td, mcontext_t *ctx,
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);
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 479348e..53ce9e4 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/timers.h>
@@ -286,7 +287,7 @@ kern_clock_settime(struct thread *td, clockid_t clock_id, struct timespec *ats)
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 @@ kern_settimeofday(struct thread *td, struct timeval *tv, struct timezone *tzp)
if (error)
return (error);
#endif
- error = suser(td);
+ error = priv_check(td, PRIV_SETTIMEOFDAY);
if (error)
return (error);
/* Verify all parameters before changing time. */
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index d6c8c2d..e9513c8 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/sched.h>
#include <sys/sysctl.h>
@@ -1813,7 +1814,7 @@ _do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags, int timo,
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 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags)
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.
diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c
index d93ba37..81c2df4 100644
--- a/sys/kern/kern_xxx.c
+++ b/sys/kern/kern_xxx.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/kernel.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -139,7 +140,8 @@ osethostid(td, uap)
{
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 @@ setdomainname(td, uap)
{
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 @@ done2:
mtx_unlock(&Giant);
return (error);
}
-
diff --git a/sys/kern/p1003_1b.c b/sys/kern/p1003_1b.c
index 189f593..8ed0de5 100644
--- a/sys/kern/p1003_1b.c
+++ b/sys/kern/p1003_1b.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
@@ -186,9 +187,10 @@ sched_setscheduler(struct thread *td, struct sched_setscheduler_args *uap)
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)
diff --git a/sys/kern/subr_acl_posix1e.c b/sys/kern/subr_acl_posix1e.c
index a3ea703..94c612f 100644
--- a/sys/kern/subr_acl_posix1e.c
+++ b/sys/kern/subr_acl_posix1e.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mount.h>
+#include <sys/priv.h>
#include <sys/vnode.h>
#include <sys/errno.h>
#include <sys/stat.h>
@@ -46,9 +47,9 @@ __FBSDID("$FreeBSD$");
/*
* 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 @@ vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid,
{
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 @@ vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid,
/*
* 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.
+ * entry that matches but has failed to allow access.
+ *
+ * XXXRW: Ideally, we'd determine the privileges required before
+ * asking for them.
*/
-#ifndef CAPABILITIES
- if (suser_cred(cred, SUSER_ALLOWJAIL) == 0)
- cap_granted = VALLPERM;
- else
- cap_granted = 0;
-#else
- cap_granted = 0;
+ 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 @@ vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid,
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 @@ vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid,
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 @@ vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid,
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 @@ vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid,
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 @@ vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid,
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 @@ vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid,
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);
diff --git a/sys/kern/subr_firmware.c b/sys/kern/subr_firmware.c
index 6de4fa4..a83e567 100644
--- a/sys/kern/subr_firmware.c
+++ b/sys/kern/subr_firmware.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/errno.h>
#include <sys/linker.h>
#include <sys/firmware.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/module.h>
@@ -190,7 +191,8 @@ again:
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;
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index b6ffc91..c53bf98 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/msgbuf.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/stddef.h>
#include <sys/sysctl.h>
@@ -925,7 +926,7 @@ sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)
int error, len;
if (!unprivileged_read_msgbuf) {
- error = suser(req->td);
+ error = priv_check(req->td, PRIV_MSGBUF);
if (error)
return (error);
}
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index 4018d3f..a99172e 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -95,6 +95,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
@@ -533,7 +534,10 @@ sysctl_debug_witness_watch(SYSCTL_HANDLER_ARGS)
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)
diff --git a/sys/kern/sysv_ipc.c b/sys/kern/sysv_ipc.c
index 8fec1da..0cbb4bb 100644
--- a/sys/kern/sysv_ipc.c
+++ b/sys/kern/sysv_ipc.c
@@ -1,8 +1,12 @@
/* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */
/*-
* Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
+ * 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 @@ __FBSDID("$FreeBSD$");
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/ipc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/ucred.h>
@@ -72,50 +77,73 @@ shmexit(struct vmspace *vm)
* 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;
-
- 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;
+ int error, obj_mode, dac_granted, priv_granted;
+
+ 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;
}
- if ((mode & perm->mode) != mode) {
- if (suser(td) != 0)
- return (EACCES);
+ /*
+ * 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;
}
- return (0);
+
+ if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) {
+ error = priv_check(td, PRIV_IPC_READ);
+ if (error == 0)
+ priv_granted |= IPC_R;
+ }
+
+ 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);
}
diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c
index 464a7e5..a3db14c 100644
--- a/sys/kern/sysv_msg.c
+++ b/sys/kern/sysv_msg.c
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/kernel.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -507,7 +508,7 @@ kern_msgctl(td, msqid, cmd, msqbuf)
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;
}
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 29ddde3..17205f2 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -86,6 +86,7 @@ __FBSDID("$FreeBSD$");
#if defined(COMPAT_43TTY)
#include <sys/ioctl_compat.h>
#endif
+#include <sys/priv.h>
#include <sys/proc.h>
#define TTYDEFCHARS
#include <sys/tty.h>
@@ -1020,7 +1021,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
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 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
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 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
}
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 @@ open_top:
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 @@ ttysioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
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;
diff --git a/sys/kern/tty_cons.c b/sys/kern/tty_cons.c
index 4472470..8e9e2a5 100644
--- a/sys/kern/tty_cons.c
+++ b/sys/kern/tty_cons.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/msgbuf.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/reboot.h>
@@ -510,7 +511,7 @@ cnioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
* 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;
diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c
index d5880a2..205cf57 100644
--- a/sys/kern/tty_pts.c
+++ b/sys/kern/tty_pts.c
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
#if defined(COMPAT_43TTY)
#include <sys/ioctl_compat.h>
#endif
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/tty.h>
@@ -268,9 +269,11 @@ ptsopen(struct cdev *dev, int flag, int devtype, struct thread *td)
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. */
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c
index a973f6a..a59430f 100644
--- a/sys/kern/tty_pty.c
+++ b/sys/kern/tty_pty.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#if defined(COMPAT_43TTY)
#include <sys/ioctl_compat.h>
#endif
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/tty.h>
#include <sys/conf.h>
@@ -207,9 +208,11 @@ ptsopen(struct cdev *dev, int flag, int devtype, struct thread *td)
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);
diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
index d6cf2e5..9185c0e 100644
--- a/sys/kern/uipc_mqueue.c
+++ b/sys/kern/uipc_mqueue.c
@@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/namei.h>
#include <sys/poll.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/sysproto.h>
@@ -955,8 +956,12 @@ int do_unlink(struct mqfs_node *pn, struct ucred *ucred)
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 @@ mqfs_setattr(struct vop_setattr_args *ap)
*/
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 @@ mqfs_setattr(struct vop_setattr_args *ap)
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;
diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c
index 8de7d8f..340c1a6 100644
--- a/sys/kern/uipc_sem.c
+++ b/sys/kern/uipc_sem.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysproto.h>
#include <sys/eventhandler.h>
#include <sys/kernel.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -419,15 +420,23 @@ sem_perm(struct thread *td, struct ksem *ks)
{
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
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 8a57786..bb51d01 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sx.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/dirent.h>
#include <sys/extattr.h>
@@ -272,7 +273,7 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
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 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
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 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
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 @@ chroot(td, uap)
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 @@ change_dir(vp, td)
/*
* 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 @@ kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode,
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 @@ restart:
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 @@ can_hardlink(struct vnode *vp, struct thread *td, struct ucred *cred)
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 @@ can_hardlink(struct vnode *vp, struct thread *td, struct ucred *cred)
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 @@ setfflags(td, vp, flags)
* 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 @@ revoke(td, uap)
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 @@ lgetfh(td, uap)
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 @@ getfh(td, uap)
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 @@ getfh(td, uap)
}
/*
- * 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 @@ fhopen(td, uap)
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 @@ fhstat(td, uap)
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 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
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)
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index af07f44..ef757b8 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/filedesc.h>
#include <sys/reboot.h>
@@ -808,23 +809,31 @@ vfs_domount(
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 @@ vfs_domount(
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 @@ unmount(td, uap)
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);
}
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 46ffd8f..d584606 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/reboot.h>
#include <sys/sleepqueue.h>
#include <sys/stat.h>
@@ -412,7 +413,7 @@ vfs_suser(struct mount *mp, struct thread *td)
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);
@@ -3178,9 +3179,7 @@ vaccess(enum vtype type, mode_t file_mode, uid_t file_uid, gid_t file_gid,
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
@@ -3234,59 +3233,46 @@ vaccess(enum vtype type, mode_t file_mode, uid_t file_uid, gid_t file_gid,
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);
}
@@ -3307,16 +3293,13 @@ extattr_check_cred(struct vnode *vp, int attrnamespace, struct ucred *cred,
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:
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 8a57786..bb51d01 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sx.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/dirent.h>
#include <sys/extattr.h>
@@ -272,7 +273,7 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
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 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
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 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
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 @@ chroot(td, uap)
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 @@ change_dir(vp, td)
/*
* 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 @@ kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode,
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 @@ restart:
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 @@ can_hardlink(struct vnode *vp, struct thread *td, struct ucred *cred)
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 @@ can_hardlink(struct vnode *vp, struct thread *td, struct ucred *cred)
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 @@ setfflags(td, vp, flags)
* 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 @@ revoke(td, uap)
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 @@ lgetfh(td, uap)
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 @@ getfh(td, uap)
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 @@ getfh(td, uap)
}
/*
- * 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 @@ fhopen(td, uap)
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 @@ fhstat(td, uap)
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 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
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)
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 4a516a7..3511044 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/file.h>
#include <sys/kdb.h>
#include <sys/stat.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/limits.h>
#include <sys/lock.h>
@@ -709,7 +710,7 @@ vn_stat(vp, sb, active_cred, file_cred, td)
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;
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 571d730..3389e1f 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -48,6 +48,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/time.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/filio.h>
@@ -1724,7 +1725,7 @@ bpf_stats_sysctl(SYSCTL_HANDLER_ARGS)
* 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)
diff --git a/sys/net/if.c b/sys/net/if.c
index ba981d4..ad32a44 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -44,6 +44,7 @@
#include <sys/bus.h>
#include <sys/mbuf.h>
#include <sys/systm.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -1489,7 +1490,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
break;
case SIOCSIFFLAGS:
- error = suser(td);
+ error = priv_check(td, PRIV_NET_SETIFFLAGS);
if (error)
return (error);
/*
@@ -1532,7 +1533,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
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 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
#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 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
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 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
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 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
{
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 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
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 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
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 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
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 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
{
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 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
{
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 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td)
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);
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 35bbfa4..83866ee 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -101,6 +101,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <vm/uma.h>
#include <sys/module.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -694,7 +695,7 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
if (bc->bc_flags & BC_F_SUSER) {
- error = suser(td);
+ error = priv_check(td, PRIV_NET_BRIDGE);
if (error)
break;
}
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index 2aa7b52..ebd0226 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -57,6 +57,7 @@
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/sockio.h>
@@ -452,7 +453,11 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
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 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
(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;
diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c
index 87f9a41..d01ed8f 100644
--- a/sys/net/if_ppp.c
+++ b/sys/net/if_ppp.c
@@ -87,6 +87,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@@ -451,7 +452,8 @@ pppioctl(sc, cmd, data, flag, td)
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 @@ pppioctl(sc, cmd, data, flag, td)
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 @@ pppioctl(sc, cmd, data, flag, td)
#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 @@ pppioctl(sc, cmd, data, flag, td)
#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 @@ pppioctl(sc, cmd, data, flag, td)
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 @@ pppsioctl(ifp, cmd, data)
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)
diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c
index d33e081..3e33970 100644
--- a/sys/net/if_sl.c
+++ b/sys/net/if_sl.c
@@ -68,6 +68,7 @@
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/sockio.h>
@@ -366,7 +367,7 @@ slopen(struct cdev *dev, register struct tty *tp)
register struct sl_softc *sc;
int s, error;
- error = suser(curthread);
+ error = priv_check(curthread, PRIV_NET_SLIP);
if (error)
return (error);
diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c
index 05b39d0..ddb14cd 100644
--- a/sys/net/if_tap.c
+++ b/sys/net/if_tap.c
@@ -47,6 +47,7 @@
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/poll.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/selinfo.h>
#include <sys/signalvar.h>
@@ -373,10 +374,13 @@ tapopen(struct cdev *dev, int flag, int mode, struct thread *td)
{
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);
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
index 610c4b5..b313b18 100644
--- a/sys/net/if_tun.c
+++ b/sys/net/if_tun.c
@@ -23,6 +23,7 @@
#include "opt_mac.h"
#include <sys/param.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@@ -597,9 +598,11 @@ tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td
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;
diff --git a/sys/net/ppp_tty.c b/sys/net/ppp_tty.c
index a90bfc8..6e79985 100644
--- a/sys/net/ppp_tty.c
+++ b/sys/net/ppp_tty.c
@@ -79,6 +79,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@@ -179,7 +180,8 @@ pppopen(dev, tp)
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 @@ ppptioctl(tp, cmd, data, flag, td)
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 @@ ppptioctl(tp, cmd, data, flag, td)
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 @@ ppptioctl(tp, cmd, data, flag, td)
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));
diff --git a/sys/net/raw_usrreq.c b/sys/net/raw_usrreq.c
index b584860..22f3e7b 100644
--- a/sys/net/raw_usrreq.c
+++ b/sys/net/raw_usrreq.c
@@ -36,6 +36,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
@@ -171,8 +172,11 @@ raw_uattach(struct socket *so, int proto, struct thread *td)
*/
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);
}
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index c4eebf7..c13f4ec 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -36,6 +36,7 @@
#include <sys/jail.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
@@ -372,8 +373,11 @@ route_output(struct mbuf *m, struct socket *so)
* 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;
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index e73648f..e5e6f42 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/priv.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/systm.h>
@@ -344,7 +345,7 @@ ieee80211_cfgget(struct ieee80211com *ic, u_long cmd, caddr_t data)
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 @@ ieee80211_ioctl_getkey(struct ieee80211com *ic, struct ieee80211req *ireq)
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 @@ ieee80211_ioctl_get80211(struct ieee80211com *ic, u_long cmd, struct ieee80211re
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 @@ ieee80211_ioctl(struct ieee80211com *ic, u_long cmd, caddr_t data)
(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 @@ ieee80211_ioctl(struct ieee80211com *ic, u_long cmd, caddr_t data)
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);
diff --git a/sys/netatalk/at_control.c b/sys/netatalk/at_control.c
index 4dc0a71..a5dbe93 100644
--- a/sys/netatalk/at_control.c
+++ b/sys/netatalk/at_control.c
@@ -118,6 +118,8 @@ at_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
case SIOCSIFADDR:
/*
* If we are not superuser, then we don't get to do these ops.
+ *
+ * XXXRW: Layering?
*/
if (suser(td))
return (EPERM);
diff --git a/sys/netatalk/ddp_pcb.c b/sys/netatalk/ddp_pcb.c
index 66ece43..e51d575 100644
--- a/sys/netatalk/ddp_pcb.c
+++ b/sys/netatalk/ddp_pcb.c
@@ -30,6 +30,7 @@
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
@@ -100,7 +101,7 @@ at_pcbsetaddr(struct ddpcb *ddp, struct sockaddr *addr, struct thread *td)
return (EINVAL);
}
if (sat->sat_port < ATPORT_RESERVED &&
- suser(td)) {
+ priv_check(td, PRIV_NETATALK_RESERVEDPORT)) {
return (EACCES);
}
}
diff --git a/sys/netatm/atm_usrreq.c b/sys/netatm/atm_usrreq.c
index ad14e84..6f40a46 100644
--- a/sys/netatm/atm_usrreq.c
+++ b/sys/netatm/atm_usrreq.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sockio.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -181,8 +182,11 @@ atm_dgram_control(so, cmd, data, ifp, td)
struct atmcfgreq *acp = (struct atmcfgreq *)data;
struct atm_pif *pip;
- if (td && (suser(td) != 0))
- ATM_RETERR(EPERM);
+ if (td != NULL) {
+ err = priv_check(td, PRIV_NETATM_CFG);
+ if (err)
+ ATM_RETERR(err);
+ }
switch (acp->acr_opcode) {
@@ -214,8 +218,11 @@ atm_dgram_control(so, cmd, data, ifp, td)
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 @@ atm_dgram_control(so, cmd, data, ifp, td)
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 @@ atm_dgram_control(so, cmd, data, ifp, td)
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) {
diff --git a/sys/netgraph/bluetooth/drivers/h4/ng_h4.c b/sys/netgraph/bluetooth/drivers/h4/ng_h4.c
index 0aaf37f..cf26468 100644
--- a/sys/netgraph/bluetooth/drivers/h4/ng_h4.c
+++ b/sys/netgraph/bluetooth/drivers/h4/ng_h4.c
@@ -48,6 +48,7 @@
#include <sys/ioccom.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/tty.h>
#include <sys/ttycom.h>
#include <netgraph/ng_message.h>
@@ -156,7 +157,7 @@ ng_h4_open(struct cdev *dev, struct tty *tp)
int s, error;
/* Super-user only */
- error = suser(curthread); /* XXX */
+ error = priv_check(curthread, PRIV_NETGRAPH_TTY); /* XXX */
if (error != 0)
return (error);
diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c b/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c
index 6513757..fc951c4 100644
--- a/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c
+++ b/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c
@@ -44,6 +44,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/queue.h>
#include <sys/socket.h>
@@ -916,7 +917,7 @@ ng_btsocket_hci_raw_attach(struct socket *so, int proto, struct thread *td)
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;
/*
diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c
index 1bac6d9..d3d14179 100644
--- a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c
+++ b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c
@@ -43,6 +43,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/queue.h>
#include <sys/socket.h>
@@ -620,7 +621,7 @@ ng_btsocket_l2cap_raw_attach(struct socket *so, int proto, struct thread *td)
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);
diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c
index 028999b..2a03275 100644
--- a/sys/netgraph/ng_socket.c
+++ b/sys/netgraph/ng_socket.c
@@ -57,6 +57,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/queue.h>
#include <sys/socket.h>
@@ -167,9 +168,11 @@ static int
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));
diff --git a/sys/netgraph/ng_tty.c b/sys/netgraph/ng_tty.c
index 7b8eceb..2e8d7aa 100644
--- a/sys/netgraph/ng_tty.c
+++ b/sys/netgraph/ng_tty.c
@@ -66,6 +66,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <sys/tty.h>
@@ -189,7 +190,8 @@ ngt_open(struct cdev *dev, struct tty *tp)
int error;
/* Super-user only */
- if ((error = suser(td)))
+ error = priv_check(td, PRIV_NETGRAPH_TTY);
+ if (error)
return (error);
/* Initialize private struct */
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 64e1ba1..4af8f06 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -37,6 +37,7 @@
#include <sys/systm.h>
#include <sys/sockio.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/socket.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
@@ -232,10 +233,25 @@ in_control(so, cmd, data, ifp, td)
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 @@ in_control(so, cmd, data, ifp, td)
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 @@ in_control(so, cmd, data, ifp, td)
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:
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 60e7bf0..9028712 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -42,6 +42,7 @@
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/jail.h>
#include <sys/kernel.h>
@@ -331,7 +332,8 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
/* 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 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
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 */
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index a9cc499..1aa0e99 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -41,6 +41,7 @@
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/time.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
@@ -1853,7 +1854,8 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
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 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
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));
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index d416b0e..c9c4694 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -48,6 +48,7 @@
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/kernel.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
@@ -420,8 +421,11 @@ div_attach(struct socket *so, int proto, struct thread *td)
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;
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index 9fa652e..a475ee2 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -53,6 +53,7 @@
#include <sys/lock.h>
#include <sys/jail.h>
#include <sys/module.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/rwlock.h>
#include <sys/socket.h>
@@ -3980,7 +3981,7 @@ ipfw_ctl(struct sockopt *sopt)
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);
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index a248b72..6b00d89 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -68,6 +68,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/module.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
@@ -576,7 +577,7 @@ X_mrt_ioctl(int cmd, caddr_t data)
* 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) {
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 6e3833e..4a738a5 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -40,6 +40,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -987,8 +988,20 @@ ip_ctloutput(so, sopt)
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;
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 837933b..e4d65c2 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -40,6 +40,7 @@
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
@@ -387,7 +388,11 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
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 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
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 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
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 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
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 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
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 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
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 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
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 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
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 @@ rip_attach(struct socket *so, int proto, struct thread *td)
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;
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 2b4f9bc..f211eb4 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -48,6 +48,7 @@
#ifdef INET6
#include <sys/domain.h>
#endif
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -1081,7 +1082,8 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
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 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
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));
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 2b4f9bc..f211eb4 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -48,6 +48,7 @@
#ifdef INET6
#include <sys/domain.h>
#endif
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -1081,7 +1082,8 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
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 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
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));
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 28245875..b0ba537 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -44,6 +44,7 @@
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
@@ -687,7 +688,8 @@ udp_getcred(SYSCTL_HANDLER_ARGS)
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));
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 8177313..52b57aa 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -71,6 +71,7 @@
#include <sys/socketvar.h>
#include <sys/sockio.h>
#include <sys/systm.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/kernel.h>
@@ -325,12 +326,8 @@ in6_control(so, cmd, data, ifp, td)
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 @@ in6_control(so, cmd, data, ifp, td)
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 @@ in6_control(so, cmd, data, ifp, td)
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 @@ in6_control(so, cmd, data, ifp, td)
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 @@ in6_control(so, cmd, data, ifp, td)
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 @@ in6_control(so, cmd, data, ifp, td)
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 @@ in6_control(so, cmd, data, ifp, td)
{
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 */
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 9305ed9..5e7da80 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -77,6 +77,7 @@
#include <sys/sockio.h>
#include <sys/errno.h>
#include <sys/time.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/jail.h>
@@ -190,8 +191,12 @@ in6_pcbbind(inp, nam, cred)
/* 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,
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index 233d79b..b9457dc 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -68,6 +68,7 @@
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -772,7 +773,9 @@ in6_pcbsetport(laddr, inp, cred)
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 */
diff --git a/sys/netinet6/ipsec.c b/sys/netinet6/ipsec.c
index 5ce3989..a0b356b 100644
--- a/sys/netinet6/ipsec.c
+++ b/sys/netinet6/ipsec.c
@@ -43,6 +43,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -1221,8 +1222,14 @@ ipsec_init_pcbpolicy(so, pcb_sp)
}
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;
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index cec632c..b91f9b6 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -70,6 +70,7 @@
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
@@ -434,7 +435,8 @@ udp6_getcred(SYSCTL_HANDLER_ARGS)
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);
diff --git a/sys/netipsec/ipsec_osdep.h b/sys/netipsec/ipsec_osdep.h
index 34df84d..e1a3926 100644
--- a/sys/netipsec/ipsec_osdep.h
+++ b/sys/netipsec/ipsec_osdep.h
@@ -215,11 +215,13 @@ if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust)
* 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__
diff --git a/sys/netipx/ipx_pcb.c b/sys/netipx/ipx_pcb.c
index e2d9f5c..1ed2265 100644
--- a/sys/netipx/ipx_pcb.c
+++ b/sys/netipx/ipx_pcb.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -107,11 +108,10 @@ ipx_pcbbind(ipxp, nam, td)
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);
}
diff --git a/sys/netipx/ipx_usrreq.c b/sys/netipx/ipx_usrreq.c
index 84de629..058b0ad 100644
--- a/sys/netipx/ipx_usrreq.c
+++ b/sys/netipx/ipx_usrreq.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
@@ -658,8 +659,13 @@ ripx_attach(so, proto, td)
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
diff --git a/sys/netncp/ncp_conn.c b/sys/netncp/ncp_conn.c
index 1455d6f..370b004 100644
--- a/sys/netncp/ncp_conn.c
+++ b/sys/netncp/ncp_conn.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/sysctl.h>
diff --git a/sys/netncp/ncp_mod.c b/sys/netncp/ncp_mod.c
index b4f919d..955fa31 100644
--- a/sys/netncp/ncp_mod.c
+++ b/sys/netncp/ncp_mod.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/module.h>
diff --git a/sys/netncp/ncp_subr.h b/sys/netncp/ncp_subr.h
index 83f1da2..5c57755 100644
--- a/sys/netncp/ncp_subr.h
+++ b/sys/netncp/ncp_subr.h
@@ -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)
diff --git a/sys/netsmb/smb_conn.c b/sys/netsmb/smb_conn.c
index 038402a..eee6b09 100644
--- a/sys/netsmb/smb_conn.c
+++ b/sys/netsmb/smb_conn.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/sysctl.h>
diff --git a/sys/netsmb/smb_subr.h b/sys/netsmb/smb_subr.h
index 9b38bfa..15e4a7a 100644
--- a/sys/netsmb/smb_subr.h
+++ b/sys/netsmb/smb_subr.h
@@ -68,7 +68,7 @@ void m_dumpm(struct mbuf *m);
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
diff --git a/sys/nfsserver/nfs_syscalls.c b/sys/nfsserver/nfs_syscalls.c
index b74325f..4d6391e 100644
--- a/sys/nfsserver/nfs_syscalls.c
+++ b/sys/nfsserver/nfs_syscalls.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/mount.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/bio.h>
#include <sys/buf.h>
@@ -142,7 +143,7 @@ nfssvc(struct thread *td, struct nfssvc_args *uap)
if (error)
return (error);
#endif
- error = suser(td);
+ error = priv_check(td, PRIV_NFSD);
if (error)
return (error);
NET_LOCK_GIANT();
diff --git a/sys/pc98/cbus/fdc.c b/sys/pc98/cbus/fdc.c
index b8c2827..b653a52 100644
--- a/sys/pc98/cbus/fdc.c
+++ b/sys/pc98/cbus/fdc.c
@@ -68,6 +68,7 @@
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/rman.h>
#include <sys/systm.h>
@@ -2512,7 +2513,7 @@ fdioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
#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 @@ fdioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
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 @@ fdioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
#endif
case FD_CLRERR:
- if (suser(td) != 0)
+ if (priv_check(td, PRIV_DRIVER) != 0)
return (EPERM);
fd->fdc->fdc_errs = 0;
break;
diff --git a/sys/posix4/p1003_1b.c b/sys/posix4/p1003_1b.c
index 189f593..8ed0de5 100644
--- a/sys/posix4/p1003_1b.c
+++ b/sys/posix4/p1003_1b.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
@@ -186,9 +187,10 @@ sched_setscheduler(struct thread *td, struct sched_setscheduler_args *uap)
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)
diff --git a/sys/security/audit/audit.c b/sys/security/audit/audit.c
index bb6f929..c8121a0 100644
--- a/sys/security/audit/audit.c
+++ b/sys/security/audit/audit.c
@@ -42,6 +42,7 @@
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/socket.h>
@@ -509,7 +510,8 @@ audit_syscall_enter(unsigned short code, struct thread *td)
* 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");
}
diff --git a/sys/security/audit/audit_pipe.c b/sys/security/audit/audit_pipe.c
index 6bea514..3cc41ef 100644
--- a/sys/security/audit/audit_pipe.c
+++ b/sys/security/audit/audit_pipe.c
@@ -626,9 +626,9 @@ audit_pipe_clone(void *arg, struct ucred *cred, char *name, int namelen,
}
/*
- * 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)
diff --git a/sys/security/audit/audit_syscalls.c b/sys/security/audit/audit_syscalls.c
index fb55511..65772a8 100644
--- a/sys/security/audit/audit_syscalls.c
+++ b/sys/security/audit/audit_syscalls.c
@@ -32,6 +32,7 @@
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/sysproto.h>
#include <sys/systm.h>
@@ -66,7 +67,7 @@ audit(struct thread *td, struct audit_args *uap)
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 @@ auditon(struct thread *td, struct auditon_args *uap)
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 @@ getauid(struct thread *td, struct getauid_args *uap)
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 @@ setauid(struct thread *td, struct setauid_args *uap)
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 @@ getaudit(struct thread *td, struct getaudit_args *uap)
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 @@ setaudit(struct thread *td, struct setaudit_args *uap)
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 @@ getaudit_addr(struct thread *td, struct getaudit_addr_args *uap)
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 @@ setaudit_addr(struct thread *td, struct setaudit_addr_args *uap)
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 @@ auditctl(struct thread *td, struct auditctl_args *uap)
if (jailed(td->td_ucred))
return (ENOSYS);
- error = suser(td);
+ error = priv_check(td, PRIV_AUDIT_CONTROL);
if (error)
return (error);
diff --git a/sys/security/mac/mac_net.c b/sys/security/mac/mac_net.c
index eb602da..7279dc8 100644
--- a/sys/security/mac/mac_net.c
+++ b/sys/security/mac/mac_net.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/mac.h>
+#include <sys/priv.h>
#include <sys/sbuf.h>
#include <sys/systm.h>
#include <sys/mount.h>
@@ -470,11 +471,11 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
}
/*
- * 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);
diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h
index 7db278c..f7c5670 100644
--- a/sys/security/mac/mac_policy.h
+++ b/sys/security/mac/mac_policy.h
@@ -596,6 +596,8 @@ typedef int (*mpo_check_vnode_write_t)(struct ucred *active_cred,
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 @@ struct mac_policy_ops {
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;
};
/*
diff --git a/sys/security/mac/mac_system.c b/sys/security/mac/mac_system.c
index eef66e6..79108a3 100644
--- a/sys/security/mac/mac_system.c
+++ b/sys/security/mac/mac_system.c
@@ -60,6 +60,12 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW,
&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)
{
diff --git a/sys/security/mac_bsdextended/mac_bsdextended.c b/sys/security/mac_bsdextended/mac_bsdextended.c
index 7dec0d1..c32c514 100644
--- a/sys/security/mac_bsdextended/mac_bsdextended.c
+++ b/sys/security/mac_bsdextended/mac_bsdextended.c
@@ -456,6 +456,9 @@ mac_bsdextended_check(struct ucred *cred, struct vnode *vp, struct vattr *vap,
{
int error, i;
+ /*
+ * XXXRW: More specific privilege selection needed?
+ */
if (suser_cred(cred, 0) == 0)
return (0);
diff --git a/sys/security/mac_lomac/mac_lomac.c b/sys/security/mac_lomac/mac_lomac.c
index 07484d1..7ca6e77 100644
--- a/sys/security/mac_lomac/mac_lomac.c
+++ b/sys/security/mac_lomac/mac_lomac.c
@@ -48,6 +48,7 @@
#include <sys/malloc.h>
#include <sys/mman.h>
#include <sys/mount.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/sbuf.h>
#include <sys/systm.h>
@@ -1697,8 +1698,10 @@ mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
* 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);
diff --git a/sys/security/mac_partition/mac_partition.c b/sys/security/mac_partition/mac_partition.c
index fe3d8e8..5ce8d20 100644
--- a/sys/security/mac_partition/mac_partition.c
+++ b/sys/security/mac_partition/mac_partition.c
@@ -45,6 +45,7 @@
#include <sys/kernel.h>
#include <sys/mac.h>
#include <sys/mount.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/sbuf.h>
#include <sys/systm.h>
@@ -191,7 +192,7 @@ mac_partition_check_cred_relabel(struct ucred *cred, struct label *newlabel)
* 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);
diff --git a/sys/security/mac_portacl/mac_portacl.c b/sys/security/mac_portacl/mac_portacl.c
index 80cd053..5218531 100644
--- a/sys/security/mac_portacl/mac_portacl.c
+++ b/sys/security/mac_portacl/mac_portacl.c
@@ -66,6 +66,7 @@
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/queue.h>
@@ -427,7 +428,8 @@ rules_check(struct ucred *cred, int family, int type, u_int16_t port)
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);
}
diff --git a/sys/security/mac_seeotheruids/mac_seeotheruids.c b/sys/security/mac_seeotheruids/mac_seeotheruids.c
index b15dc00..f8c02d2 100644
--- a/sys/security/mac_seeotheruids/mac_seeotheruids.c
+++ b/sys/security/mac_seeotheruids/mac_seeotheruids.c
@@ -46,6 +46,7 @@
#include <sys/kernel.h>
#include <sys/mac.h>
#include <sys/mount.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
@@ -126,7 +127,7 @@ mac_seeotheruids_check(struct ucred *u1, struct ucred *u2)
return (0);
if (suser_privileged) {
- if (suser_cred(u1, 0) == 0)
+ if (priv_check_cred(u1, PRIV_SEEOTHERUIDS, 0) == 0)
return (0);
}
diff --git a/sys/sun4v/sun4v/hvcons.c b/sys/sun4v/sun4v/hvcons.c
index 2740b84..e0e8468 100644
--- a/sys/sun4v/sun4v/hvcons.c
+++ b/sys/sun4v/sun4v/hvcons.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <sys/cons.h>
#include <sys/consio.h>
+#include <sys/priv.h>
#include <sys/rman.h>
#include <sys/tty.h>
@@ -134,7 +135,8 @@ hvcn_open(struct cdev *dev, int flag, int mode, struct thread *td)
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);
}
diff --git a/sys/sys/mac_policy.h b/sys/sys/mac_policy.h
index 7db278c..f7c5670 100644
--- a/sys/sys/mac_policy.h
+++ b/sys/sys/mac_policy.h
@@ -596,6 +596,8 @@ typedef int (*mpo_check_vnode_write_t)(struct ucred *active_cred,
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 @@ struct mac_policy_ops {
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;
};
/*
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index bc92afe..b7e7fda 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -71,6 +71,7 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <sys/file.h>
#include <sys/filedesc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/mount.h>
@@ -171,7 +172,7 @@ retry:
#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 @@ ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, cred, bpp)
#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;
}
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index b9ccf3a..a2591bc 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
@@ -257,15 +258,16 @@ ffs_mount(struct mount *mp, struct thread *td)
* 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 @@ ffs_mount(struct mount *mp, struct thread *td)
* 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) {
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 4d8d9ef..5ffedd7 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$");
#include <sys/limits.h>
#include <sys/malloc.h>
#include <sys/mount.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
@@ -781,7 +782,8 @@ ffs_write(ap)
* 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 @@ ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *ucred)
* 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;
}
diff --git a/sys/ufs/ufs/ufs_extattr.c b/sys/ufs/ufs/ufs_extattr.c
index e6153f3..f49f988 100644
--- a/sys/ufs/ufs/ufs_extattr.c
+++ b/sys/ufs/ufs/ufs_extattr.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <sys/namei.h>
#include <sys/malloc.h>
#include <sys/fcntl.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/mount.h>
@@ -699,7 +700,8 @@ ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp,
* 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);
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index 81a1d0d..c4a93cd 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/stat.h>
@@ -165,7 +166,8 @@ chkdq(ip, change, cred, flags)
}
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 @@ chkiq(ip, change, cred, flags)
}
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 @@ quotaon(td, mp, type, fname)
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 @@ quotaoff(td, mp, type)
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 @@ getquota(td, mp, id, type, addr)
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 @@ setquota(td, mp, id, type, addr)
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 @@ setuse(td, mp, id, type, addr)
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);
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 4f96449..4fcadd0 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/mount.h>
+#include <sys/priv.h>
#include <sys/refcount.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
@@ -493,8 +494,11 @@ ufs_setattr(ap)
* 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)) {
@@ -585,10 +589,19 @@ ufs_setattr(ap)
* 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;
@@ -654,11 +667,13 @@ ufs_chmod(vp, mode, cred, td)
* 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);
}
@@ -695,19 +710,19 @@ ufs_chown(vp, uid, gid, cred, td)
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;
@@ -778,7 +793,8 @@ good:
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);
}
@@ -2357,7 +2373,8 @@ ufs_makeinode(mode, dvp, vpp, cnp)
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);
}
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 85ea18e..7b7e5d1 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/bio.h>
#include <sys/buf.h>
@@ -1966,11 +1967,11 @@ swapon(struct thread *td, struct swapon_args *uap)
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 @@ swapon(struct thread *td, struct swapon_args *uap)
done:
swdev_syscall_active = 0;
wakeup_one(&swdev_syscall_active);
-done2:
mtx_unlock(&Giant);
return (error);
}
@@ -2105,7 +2105,7 @@ swapoff(struct thread *td, struct swapoff_args *uap)
struct swdevt *sp;
int error;
- error = suser(td);
+ error = priv_check(td, PRIV_SWAPOFF);
if (error)
return (error);
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 933080e..ff1ba18 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/sysproto.h>
#include <sys/filedesc.h>
+#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
@@ -684,7 +685,7 @@ madvise(td, uap)
* "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 @@ mlock(td, uap)
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 @@ mlockall(td, uap)
}
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 @@ munlockall(td, uap)
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 @@ munlock(td, uap)
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;
OpenPOWER on IntegriCloud