Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 May 2009 13:59:05 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r193092 - in head: share/man/man9 sys/fs/nullfs sys/kern sys/sys
Message-ID:  <200905301359.n4UDx5Zo009796@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Sat May 30 13:59:05 2009
New Revision: 193092
URL: http://svn.freebsd.org/changeset/base/193092

Log:
  Add VOP_ACCESSX, which can be used to query for newly added V*
  permissions, such as VWRITE_ACL.  For a filsystems that don't
  implement it, there is a default implementation, which works
  as a wrapper around VOP_ACCESS.
  
  Reviewed by:	rwatson@

Modified:
  head/share/man/man9/Makefile
  head/share/man/man9/VOP_ACCESS.9
  head/sys/fs/nullfs/null_vnops.c
  head/sys/kern/vfs_default.c
  head/sys/kern/vfs_subr.c
  head/sys/kern/vnode_if.src
  head/sys/sys/vnode.h

Modified: head/share/man/man9/Makefile
==============================================================================
--- head/share/man/man9/Makefile	Sat May 30 12:26:11 2009	(r193091)
+++ head/share/man/man9/Makefile	Sat May 30 13:59:05 2009	(r193092)
@@ -1288,6 +1288,7 @@ MLINKS+=vm_page_io.9 vm_page_io_finish.9
 MLINKS+=vm_page_wakeup.9 vm_page_busy.9 \
 	vm_page_wakeup.9 vm_page_flash.9
 MLINKS+=vm_page_wire.9 vm_page_unwire.9
+MLINKS+=VOP_ACCESS.9 VOP_ACCESSX.9
 MLINKS+=VOP_ATTRIB.9 VOP_GETATTR.9 \
 	VOP_ATTRIB.9 VOP_SETATTR.9
 MLINKS+=VOP_CREATE.9 VOP_MKDIR.9 \

Modified: head/share/man/man9/VOP_ACCESS.9
==============================================================================
--- head/share/man/man9/VOP_ACCESS.9	Sat May 30 12:26:11 2009	(r193091)
+++ head/share/man/man9/VOP_ACCESS.9	Sat May 30 13:59:05 2009	(r193092)
@@ -29,17 +29,20 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 24, 1996
+.Dd May 30, 2009
 .Os
 .Dt VOP_ACCESS 9
 .Sh NAME
-.Nm VOP_ACCESS
+.Nm VOP_ACCESS ,
+.Nm VOP_ACCESSX
 .Nd "check access permissions of a file or Unix domain socket"
 .Sh SYNOPSIS
 .In sys/param.h
 .In sys/vnode.h
 .Ft int
 .Fn VOP_ACCESS "struct vnode *vp" "accmode_t accmode" "struct ucred *cred" "struct thread *td"
+.Ft int
+.Fn VOP_ACCESSX "struct vnode *vp" "accmode_t accmode" "struct ucred *cred" "struct thread *td"
 .Sh DESCRIPTION
 This entry point checks the access permissions of the file against the
 given credentials.
@@ -63,6 +66,20 @@ is a mask which can contain flags descri
 .Dv VWRITE
 or
 .Dv VEXEC .
+For
+.Fn VOP_ACCESS ,
+the only flags that may be set in
+.Fa accmode
+are
+.Dv VEXEC ,
+.Dv VWRITE ,
+.Dv VREAD ,
+.Dv VADMIN
+and
+.Dv VAPPEND .
+To check for other bits, one has to use
+.Fn VOP_ACCESSX
+instead.
 .Sh LOCKS
 The vnode will be locked on entry and should remain locked on return.
 .Sh RETURN VALUES

Modified: head/sys/fs/nullfs/null_vnops.c
==============================================================================
--- head/sys/fs/nullfs/null_vnops.c	Sat May 30 12:26:11 2009	(r193091)
+++ head/sys/fs/nullfs/null_vnops.c	Sat May 30 13:59:05 2009	(r193092)
@@ -472,6 +472,32 @@ null_access(struct vop_access_args *ap)
 	return (null_bypass((struct vop_generic_args *)ap));
 }
 
+static int
+null_accessx(struct vop_accessx_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	accmode_t accmode = ap->a_accmode;
+
+	/*
+	 * Disallow write attempts on read-only layers;
+	 * unless the file is a socket, fifo, or a block or
+	 * character device resident on the filesystem.
+	 */
+	if (accmode & VWRITE) {
+		switch (vp->v_type) {
+		case VDIR:
+		case VLNK:
+		case VREG:
+			if (vp->v_mount->mnt_flag & MNT_RDONLY)
+				return (EROFS);
+			break;
+		default:
+			break;
+		}
+	}
+	return (null_bypass((struct vop_generic_args *)ap));
+}
+
 /*
  * We handle this to eliminate null FS to lower FS
  * file moving. Don't know why we don't allow this,
@@ -720,6 +746,7 @@ null_vptofh(struct vop_vptofh_args *ap)
 struct vop_vector null_vnodeops = {
 	.vop_bypass =		null_bypass,
 	.vop_access =		null_access,
+	.vop_accessx =		null_accessx,
 	.vop_bmap =		VOP_EOPNOTSUPP,
 	.vop_getattr =		null_getattr,
 	.vop_getwritemount =	null_getwritemount,

Modified: head/sys/kern/vfs_default.c
==============================================================================
--- head/sys/kern/vfs_default.c	Sat May 30 12:26:11 2009	(r193091)
+++ head/sys/kern/vfs_default.c	Sat May 30 13:59:05 2009	(r193092)
@@ -87,6 +87,7 @@ struct vop_vector default_vnodeops = {
 	.vop_default =		NULL,
 	.vop_bypass =		VOP_EOPNOTSUPP,
 
+	.vop_accessx =		vop_stdaccessx,
 	.vop_advlock =		vop_stdadvlock,
 	.vop_advlockasync =	vop_stdadvlockasync,
 	.vop_bmap =		vop_stdbmap,
@@ -322,6 +323,22 @@ out:
 	return (found);
 }
 
+int
+vop_stdaccessx(struct vop_accessx_args *ap)
+{
+	int error;
+	accmode_t accmode = ap->a_accmode;
+
+	error = vfs_unixify_accmode(&accmode);
+	if (error != 0)
+		return (error);
+
+	if (accmode == 0)
+		return (0);
+
+	return (VOP_ACCESS(ap->a_vp, accmode, ap->a_cred, ap->a_td));
+}
+
 /*
  * Advisory record locking support
  */

Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c	Sat May 30 12:26:11 2009	(r193091)
+++ head/sys/kern/vfs_subr.c	Sat May 30 13:59:05 2009	(r193092)
@@ -4253,3 +4253,50 @@ vfs_mark_atime(struct vnode *vp, struct 
 	if ((vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0)
 		(void)VOP_MARKATIME(vp);
 }
+
+/*
+ * The purpose of this routine is to remove granularity from accmode_t,
+ * reducing it into standard unix access bits - VEXEC, VREAD, VWRITE,
+ * VADMIN and VAPPEND.
+ *
+ * If it returns 0, the caller is supposed to continue with the usual
+ * access checks using 'accmode' as modified by this routine.  If it
+ * returns nonzero value, the caller is supposed to return that value
+ * as errno.
+ *
+ * Note that after this routine runs, accmode may be zero.
+ */
+int
+vfs_unixify_accmode(accmode_t *accmode)
+{
+	/*
+	 * There is no way to specify explicit "deny" rule using
+	 * file mode or POSIX.1e ACLs.
+	 */
+	if (*accmode & VEXPLICIT_DENY) {
+		*accmode = 0;
+		return (0);
+	}
+
+	/*
+	 * None of these can be translated into usual access bits.
+	 * Also, the common case for NFSv4 ACLs is to not contain
+	 * either of these bits. Caller should check for VWRITE
+	 * on the containing directory instead.
+	 */
+	if (*accmode & (VDELETE_CHILD | VDELETE))
+		return (EPERM);
+
+	if (*accmode & VADMIN_PERMS) {
+		*accmode &= ~VADMIN_PERMS;
+		*accmode |= VADMIN;
+	}
+
+	/*
+	 * There is no way to deny VREAD_ATTRIBUTES, VREAD_ACL
+	 * or VSYNCHRONIZE using file mode or POSIX.1e ACL.
+	 */
+	*accmode &= ~(VSTAT_PERMS | VSYNCHRONIZE);
+
+	return (0);
+}

Modified: head/sys/kern/vnode_if.src
==============================================================================
--- head/sys/kern/vnode_if.src	Sat May 30 12:26:11 2009	(r193091)
+++ head/sys/kern/vnode_if.src	Sat May 30 13:59:05 2009	(r193092)
@@ -153,6 +153,16 @@ vop_access {
 };
 
 
+%% accessx	vp	L L L
+
+vop_accessx {
+	IN struct vnode *vp;
+	IN accmode_t accmode;
+	IN struct ucred *cred;
+	IN struct thread *td;
+};
+
+
 %% getattr	vp	L L L
 
 vop_getattr {

Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h	Sat May 30 12:26:11 2009	(r193091)
+++ head/sys/sys/vnode.h	Sat May 30 13:59:05 2009	(r193092)
@@ -676,6 +676,7 @@ int	vop_stdlock(struct vop_lock1_args *)
 int	vop_stdputpages(struct vop_putpages_args *);
 int	vop_stdunlock(struct vop_unlock_args *);
 int	vop_nopoll(struct vop_poll_args *);
+int	vop_stdaccessx(struct vop_accessx_args *ap);
 int	vop_stdadvlock(struct vop_advlock_args *ap);
 int	vop_stdadvlockasync(struct vop_advlockasync_args *ap);
 int	vop_stdpathconf(struct vop_pathconf_args *);
@@ -766,6 +767,8 @@ void vfs_mark_atime(struct vnode *vp, st
 struct dirent;
 int vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off);
 
+int	vfs_unixify_accmode(accmode_t *accmode);
+
 #endif /* _KERNEL */
 
 #endif /* !_SYS_VNODE_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905301359.n4UDx5Zo009796>