New in-kernel privilege API: priv(9)

Pawel Jakub Dawidek pjd at FreeBSD.org
Tue Oct 31 15:30:57 UTC 2006


On Tue, Oct 31, 2006 at 03:04:30PM +0000, Robert Watson wrote:
> 
> On Tue, 31 Oct 2006, Pawel Jakub Dawidek wrote:
> 
> >Here are few nits I found:
> 
> Thanks!  Comments below.
> 
> >>Index: sys/fs/hpfs/hpfs_vnops.c
> >>===================================================================
> >>RCS file: /zoo/cvsup/FreeBSD-CVS/src/sys/fs/hpfs/hpfs_vnops.c,v
> >>retrieving revision 1.68
> >>diff -u -r1.68 hpfs_vnops.c
> >>--- sys/fs/hpfs/hpfs_vnops.c	17 Jan 2006 17:29:01 -0000	1.68
> >>+++ sys/fs/hpfs/hpfs_vnops.c	30 Oct 2006 17:07:55 -0000
> >>@@ -501,11 +501,12 @@
> >> 	if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
> >> 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
> >> 			return (EROFS);
> >>-		if (cred->cr_uid != hp->h_uid &&
> >>-		    (error = suser_cred(cred, SUSER_ALLOWJAIL)) &&
> >>-		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
> >>-		    (error = VOP_ACCESS(vp, VWRITE, cred, td))))
> >>-			return (error);
> >>+		if (vap->va_vaflags & VA_UTIMES_NULL) {
> >>+			error = VOP_ACCESS(vp, VADMIN, cred, td);
> >>+			if (error)
> >>+				error = VOP_ACCESS(vp, VWRITE, cred, td);
> >>+		} else
> >>+			error = VOP_ACCESS(vp, VADMIN, cred, td);
> >
> >Eliminating privilege check here was intentional? Doesn't it change functionality? I found the same check in few other places, so it's probably intentional, but worth 
> >checking still.
> 
> Yeah, it took my quite a while to puzzle through what the security check here is supposed to accomplish, but once I did, the correct structure became more clear.  The key 
> here is that VOP_ACCESS() will also perform a privilege check, so the use of privilege in the existing code appears to be redundant.  The logic here should essentially 
> read:
> 
> - To update the time stamp to the current time (VA_UTIMES_NULL), you must
>   either be the owner or have write access.  The correct error value is
>   EACCES, so we try the write check only if the owner check fails, so that the
>   error from the write check overrides the owner result.
> 
> - To update the time stamp to any other time, you must be the owner.  The
>   error here is EPERM on failure.
> 
> Given this description, do you think the change is right?

Yes, I agree. I really hate complex ifs like the one you replaced:)

> >>+			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);
> >
> >This doesn't seem right to me. If VOP_ACCESS() returns an error if call priv_check(), I think you wanted to call it when it return success, no?
> >
> >I'd change it to:
> >
> >			devvp = pmp->pm_devvp;
> >			vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
> >			error = VOP_ACCESS(devvp, VREAD | VWRITE,
> >			   td->td_ucred, td);
> >			VOP_UNLOCK(devvp, 0, td);
> >			if (!error)
> >				error = priv_check(td, PRIV_VFS_MOUNT_PERM);
> >			if (error)
> >				return (error);
> 
> Again, this is a tricky case in the original code.  I believe the intended logic here, in English, is:
> 
> - In order to mount on a device vnode, you must be able to read and write to
>   it.  This is subject to the normal definition of read and write privilege,
>   so the superuser can override on that basis (as part of VOP_ACCESS).
> 
> - However, if you don't have read and write access, you can also use privilege
>   (PRIV_VFS_MOUNT_PERM) to override that.
> 
> This is expressed in the original code by first checking for privilege, and if that fails, then looking for read/write access.  This doesn't make a lot of sense because the 
> read/write check is also exempted by privilege, but was probably "a little faster" because suser() was cheaper than VOP_ACCESS().
> 
> The reason we call priv_check() in the error case is that we only want to check for privilege if the normal access control check fails, in which case we override the normal 
> access control error check with the result of the privilege check.
> 
> Given this description, does the new code still make sense?

After more thinking I understand and agree with your change, maybe we
can add a comment describing the behaviour as it is not obvious on first
look.

We could still move VOP_UNLOCK() right after VOP_ACCESS(), BTW.

-- 
Pawel Jakub Dawidek                       http://www.wheel.pl
pjd at FreeBSD.org                           http://www.FreeBSD.org
FreeBSD committer                         Am I Evil? Yes, I Am!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-arch/attachments/20061031/c5144fc6/attachment.pgp


More information about the freebsd-arch mailing list