From 10d0d9cf473dc5f0ce1bf263ead445ffe7819154 Mon Sep 17 00:00:00 2001 From: rwatson Date: Mon, 6 Nov 2006 13:42:10 +0000 Subject: 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 , Skip Ford , Antoine Brodin --- sys/fs/cd9660/cd9660_vfsops.c | 3 ++- sys/fs/devfs/devfs_rule.c | 11 +++++---- sys/fs/devfs/devfs_vnops.c | 24 +++++++++++++------- sys/fs/hpfs/hpfs_vnops.c | 11 ++++----- sys/fs/msdosfs/msdosfs_vfsops.c | 37 +++++++++++++++--------------- sys/fs/msdosfs/msdosfs_vnops.c | 50 ++++++++++++++++++++++++++--------------- sys/fs/procfs/procfs_ioctl.c | 16 +++++++++++-- sys/fs/smbfs/smbfs_vnops.c | 12 +++++----- sys/fs/udf/udf_vfsops.c | 3 ++- sys/fs/umapfs/umap_vfsops.c | 3 ++- 10 files changed, 107 insertions(+), 63 deletions(-) (limited to 'sys/fs') 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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 -- cgit v1.1