All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-05 17:25 Aneesh Kumar K.V
  2011-09-05 17:25 ` [PATCH -V6 01/26] vfs: Indicate that the permission functions take all the MAY_* flags Aneesh Kumar K.V
                   ` (37 more replies)
  0 siblings, 38 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

Hi,

The following set of patches implements VFS and ext4 changes needed to implement
a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
extended by file masks to fit into the standard POSIX file permission model.
They are designed to work seamlessly locally as well as across the NFSv4 and
CIFS/SMB2 network file system protocols.

A user-space utility for displaying and changing richacls is available at [4]
(a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).

[4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master

To test richacl on ext4 use -o richacl mount option. This mount option may later be
dropped in favour of a feature flag.

More details regarding richacl can be found at
http://acl.bestbits.at/richacl/

Changes from v5:
a) rebase to v3.1-rc4-131-g9e79e3e

NOTE: The kernel changes will be pushed to
git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
when kernel.org is back

-aneesh

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



^ permalink raw reply	[flat|nested] 116+ messages in thread

* [PATCH -V6 01/26] vfs: Indicate that the permission functions take all the MAY_* flags
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25 ` [PATCH -V6 02/26] vfs: Add hex format for MAY_* flag values Aneesh Kumar K.V
                   ` (36 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/namei.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 2826db3..9efc638 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -257,7 +257,7 @@ other_perms:
 /**
  * generic_permission -  check for access rights on a Posix-like filesystem
  * @inode:	inode to check access rights for
- * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC, ...)
  *
  * Used to check for read/write/execute permissions on a file.
  * We use "fsuid" for this, letting us set arbitrary permissions
@@ -331,7 +331,7 @@ static inline int do_inode_permission(struct inode *inode, int mask)
 /**
  * inode_permission  -  check for access rights to a given inode
  * @inode:	inode to check permission on
- * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC, ...)
  *
  * Used to check for read/write/execute permissions on an inode.
  * We use "fsuid" for this, letting us set arbitrary permissions
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 02/26] vfs: Add hex format for MAY_* flag values
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
  2011-09-05 17:25 ` [PATCH -V6 01/26] vfs: Indicate that the permission functions take all the MAY_* flags Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25 ` [PATCH -V6 03/26] vfs: Pass all mask flags down to iop->check_acl Aneesh Kumar K.V
                   ` (35 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

We are going to add more flags and having them in hex format
make it simpler

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 include/linux/fs.h |   17 +++++++++--------
 1 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index c2bd68f..45744ae 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -58,14 +58,15 @@ struct inodes_stat_t {
 
 #define NR_FILE  8192	/* this can well be larger on a larger system */
 
-#define MAY_EXEC 1
-#define MAY_WRITE 2
-#define MAY_READ 4
-#define MAY_APPEND 8
-#define MAY_ACCESS 16
-#define MAY_OPEN 32
-#define MAY_CHDIR 64
-#define MAY_NOT_BLOCK 128	/* called from RCU mode, don't block */
+#define MAY_EXEC		0x00000001
+#define MAY_WRITE		0x00000002
+#define MAY_READ		0x00000004
+#define MAY_APPEND		0x00000008
+#define MAY_ACCESS		0x00000010
+#define MAY_OPEN		0x00000020
+#define MAY_CHDIR		0x00000040
+/* called from RCU mode, don't block */
+#define MAY_NOT_BLOCK		0x00000080
 
 /*
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 03/26] vfs: Pass all mask flags down to iop->check_acl
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
  2011-09-05 17:25 ` [PATCH -V6 01/26] vfs: Indicate that the permission functions take all the MAY_* flags Aneesh Kumar K.V
  2011-09-05 17:25 ` [PATCH -V6 02/26] vfs: Add hex format for MAY_* flag values Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25   ` Aneesh Kumar K.V
                   ` (34 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Some file permission models differentiate between writing to a file
(MAY_WRITE) and appending to it (MAY_WRITE | MAY_APPEND).  Pass all the
mask flags down to iop->check_acl so that filesystems can distinguish
between writing and appending.

All users of iop->check_acl pass the mask value back into
posix_acl_permission(); strip off the additional mask flags there.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/namei.c     |    2 --
 fs/posix_acl.c |    2 ++
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 9efc638..f34a4d4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -227,8 +227,6 @@ static int acl_permission_check(struct inode *inode, int mask)
 {
 	unsigned int mode = inode->i_mode;
 
-	mask &= MAY_READ | MAY_WRITE | MAY_EXEC | MAY_NOT_BLOCK;
-
 	if (current_user_ns() != inode_userns(inode))
 		goto other_perms;
 
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 10027b4..cea4623 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -218,6 +218,8 @@ posix_acl_permission(struct inode *inode, const struct posix_acl *acl, int want)
 	const struct posix_acl_entry *pa, *pe, *mask_obj;
 	int found = 0;
 
+	want &= MAY_READ | MAY_WRITE | MAY_EXEC | MAY_NOT_BLOCK;
+
 	FOREACH_ACL_ENTRY(pa, acl, pe) {
                 switch(pa->e_tag) {
                         case ACL_USER_OBJ:
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 04/26] vfs: Add a comment to inode_permission()
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/namei.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index f34a4d4..23bc030 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -221,7 +221,7 @@ static int check_acl(struct inode *inode, int mask)
 }
 
 /*
- * This does basic POSIX ACL permission checking
+ * This does the basic permission checking
  */
 static int acl_permission_check(struct inode *inode, int mask)
 {
@@ -271,7 +271,7 @@ int generic_permission(struct inode *inode, int mask)
 	int ret;
 
 	/*
-	 * Do the basic POSIX ACL permission checks.
+	 * Do the basic permission checks.
 	 */
 	ret = acl_permission_check(inode, mask);
 	if (ret != -EACCES)
@@ -335,6 +335,8 @@ static inline int do_inode_permission(struct inode *inode, int mask)
  * We use "fsuid" for this, letting us set arbitrary permissions
  * for filesystem access without changing the "normal" uids which
  * are used for other things.
+ *
+ * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask.
  */
 int inode_permission(struct inode *inode, int mask)
 {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 04/26] vfs: Add a comment to inode_permission()
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA
  Cc: aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 fs/namei.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index f34a4d4..23bc030 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -221,7 +221,7 @@ static int check_acl(struct inode *inode, int mask)
 }
 
 /*
- * This does basic POSIX ACL permission checking
+ * This does the basic permission checking
  */
 static int acl_permission_check(struct inode *inode, int mask)
 {
@@ -271,7 +271,7 @@ int generic_permission(struct inode *inode, int mask)
 	int ret;
 
 	/*
-	 * Do the basic POSIX ACL permission checks.
+	 * Do the basic permission checks.
 	 */
 	ret = acl_permission_check(inode, mask);
 	if (ret != -EACCES)
@@ -335,6 +335,8 @@ static inline int do_inode_permission(struct inode *inode, int mask)
  * We use "fsuid" for this, letting us set arbitrary permissions
  * for filesystem access without changing the "normal" uids which
  * are used for other things.
+ *
+ * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask.
  */
 int inode_permission(struct inode *inode, int mask)
 {
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 05/26] vfs: Add generic IS_ACL() test for acl support
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

When IS_POSIXACL() is true, the vfs does not apply the umask.  Other acl
models will need the same exception, so introduce a separate IS_ACL()
test.

The IS_POSIX_ACL() test is still needed so that nfsd can determine when
the underlying file system supports POSIX ACLs (as opposed to some other
kind).

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/namei.c         |    6 +++---
 include/linux/fs.h |    8 +++++++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 23bc030..a7a7ac0 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2175,7 +2175,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
 	/* Negative dentry, just create the file */
 	if (!dentry->d_inode) {
 		int mode = op->mode;
-		if (!IS_POSIXACL(dir->d_inode))
+		if (!IS_ACL(dir->d_inode))
 			mode &= ~current_umask();
 		/*
 		 * This write is needed to ensure that a
@@ -2493,7 +2493,7 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode,
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
-	if (!IS_POSIXACL(path.dentry->d_inode))
+	if (!IS_ACL(path.dentry->d_inode))
 		mode &= ~current_umask();
 	error = may_mknod(mode);
 	if (error)
@@ -2562,7 +2562,7 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode)
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
-	if (!IS_POSIXACL(path.dentry->d_inode))
+	if (!IS_ACL(path.dentry->d_inode))
 		mode &= ~current_umask();
 	error = mnt_want_write(path.mnt);
 	if (error)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 45744ae..3e1726e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -203,7 +203,7 @@ struct inodes_stat_t {
 #define MS_VERBOSE	32768	/* War is peace. Verbosity is silence.
 				   MS_VERBOSE is deprecated. */
 #define MS_SILENT	32768
-#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
+#define MS_POSIXACL	(1<<16) /* Supports POSIX ACLs */
 #define MS_UNBINDABLE	(1<<17)	/* change to unbindable */
 #define MS_PRIVATE	(1<<18)	/* change to private */
 #define MS_SLAVE	(1<<19)	/* change to slave */
@@ -281,6 +281,12 @@ struct inodes_stat_t {
 #define IS_AUTOMOUNT(inode)	((inode)->i_flags & S_AUTOMOUNT)
 #define IS_NOSEC(inode)		((inode)->i_flags & S_NOSEC)
 
+/*
+ * IS_ACL() tells the VFS to not apply the umask
+ * and use check_acl for acl permission checks when defined.
+ */
+#define IS_ACL(inode)		__IS_FLG(inode, MS_POSIXACL)
+
 /* the read-only stuff doesn't really belong here, but any other place is
    probably as bad and I don't want to create yet another include file. */
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 05/26] vfs: Add generic IS_ACL() test for acl support
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA
  Cc: aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

When IS_POSIXACL() is true, the vfs does not apply the umask.  Other acl
models will need the same exception, so introduce a separate IS_ACL()
test.

The IS_POSIX_ACL() test is still needed so that nfsd can determine when
the underlying file system supports POSIX ACLs (as opposed to some other
kind).

Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 fs/namei.c         |    6 +++---
 include/linux/fs.h |    8 +++++++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 23bc030..a7a7ac0 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2175,7 +2175,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
 	/* Negative dentry, just create the file */
 	if (!dentry->d_inode) {
 		int mode = op->mode;
-		if (!IS_POSIXACL(dir->d_inode))
+		if (!IS_ACL(dir->d_inode))
 			mode &= ~current_umask();
 		/*
 		 * This write is needed to ensure that a
@@ -2493,7 +2493,7 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode,
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
-	if (!IS_POSIXACL(path.dentry->d_inode))
+	if (!IS_ACL(path.dentry->d_inode))
 		mode &= ~current_umask();
 	error = may_mknod(mode);
 	if (error)
@@ -2562,7 +2562,7 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode)
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
-	if (!IS_POSIXACL(path.dentry->d_inode))
+	if (!IS_ACL(path.dentry->d_inode))
 		mode &= ~current_umask();
 	error = mnt_want_write(path.mnt);
 	if (error)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 45744ae..3e1726e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -203,7 +203,7 @@ struct inodes_stat_t {
 #define MS_VERBOSE	32768	/* War is peace. Verbosity is silence.
 				   MS_VERBOSE is deprecated. */
 #define MS_SILENT	32768
-#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
+#define MS_POSIXACL	(1<<16) /* Supports POSIX ACLs */
 #define MS_UNBINDABLE	(1<<17)	/* change to unbindable */
 #define MS_PRIVATE	(1<<18)	/* change to private */
 #define MS_SLAVE	(1<<19)	/* change to slave */
@@ -281,6 +281,12 @@ struct inodes_stat_t {
 #define IS_AUTOMOUNT(inode)	((inode)->i_flags & S_AUTOMOUNT)
 #define IS_NOSEC(inode)		((inode)->i_flags & S_NOSEC)
 
+/*
+ * IS_ACL() tells the VFS to not apply the umask
+ * and use check_acl for acl permission checks when defined.
+ */
+#define IS_ACL(inode)		__IS_FLG(inode, MS_POSIXACL)
+
 /* the read-only stuff doesn't really belong here, but any other place is
    probably as bad and I don't want to create yet another include file. */
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 06/26] vfs: Add IS_RICHACL() test for richacl support
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Introduce a new MS_RICHACL super-block flag and a new IS_RICHACL() test
which file systems like nfs can use.  IS_ACL() is true if IS_POSIXACL()
or IS_RICHACL() is true.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 include/linux/fs.h |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3e1726e..6eac730 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -212,6 +212,7 @@ struct inodes_stat_t {
 #define MS_KERNMOUNT	(1<<22) /* this is a kern_mount call */
 #define MS_I_VERSION	(1<<23) /* Update inode I_version field */
 #define MS_STRICTATIME	(1<<24) /* Always perform atime updates */
+#define MS_RICHACL	(1<<25) /* Supports richacls */
 #define MS_NOSEC	(1<<28)
 #define MS_BORN		(1<<29)
 #define MS_ACTIVE	(1<<30)
@@ -272,6 +273,7 @@ struct inodes_stat_t {
 #define IS_APPEND(inode)	((inode)->i_flags & S_APPEND)
 #define IS_IMMUTABLE(inode)	((inode)->i_flags & S_IMMUTABLE)
 #define IS_POSIXACL(inode)	__IS_FLG(inode, MS_POSIXACL)
+#define IS_RICHACL(inode)	__IS_FLG(inode, MS_RICHACL)
 
 #define IS_DEADDIR(inode)	((inode)->i_flags & S_DEAD)
 #define IS_NOCMTIME(inode)	((inode)->i_flags & S_NOCMTIME)
@@ -285,7 +287,7 @@ struct inodes_stat_t {
  * IS_ACL() tells the VFS to not apply the umask
  * and use check_acl for acl permission checks when defined.
  */
-#define IS_ACL(inode)		__IS_FLG(inode, MS_POSIXACL)
+#define IS_ACL(inode)		__IS_FLG(inode, MS_POSIXACL | MS_RICHACL)
 
 /* the read-only stuff doesn't really belong here, but any other place is
    probably as bad and I don't want to create yet another include file. */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 06/26] vfs: Add IS_RICHACL() test for richacl support
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA
  Cc: aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Introduce a new MS_RICHACL super-block flag and a new IS_RICHACL() test
which file systems like nfs can use.  IS_ACL() is true if IS_POSIXACL()
or IS_RICHACL() is true.

Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 include/linux/fs.h |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3e1726e..6eac730 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -212,6 +212,7 @@ struct inodes_stat_t {
 #define MS_KERNMOUNT	(1<<22) /* this is a kern_mount call */
 #define MS_I_VERSION	(1<<23) /* Update inode I_version field */
 #define MS_STRICTATIME	(1<<24) /* Always perform atime updates */
+#define MS_RICHACL	(1<<25) /* Supports richacls */
 #define MS_NOSEC	(1<<28)
 #define MS_BORN		(1<<29)
 #define MS_ACTIVE	(1<<30)
@@ -272,6 +273,7 @@ struct inodes_stat_t {
 #define IS_APPEND(inode)	((inode)->i_flags & S_APPEND)
 #define IS_IMMUTABLE(inode)	((inode)->i_flags & S_IMMUTABLE)
 #define IS_POSIXACL(inode)	__IS_FLG(inode, MS_POSIXACL)
+#define IS_RICHACL(inode)	__IS_FLG(inode, MS_RICHACL)
 
 #define IS_DEADDIR(inode)	((inode)->i_flags & S_DEAD)
 #define IS_NOCMTIME(inode)	((inode)->i_flags & S_NOCMTIME)
@@ -285,7 +287,7 @@ struct inodes_stat_t {
  * IS_ACL() tells the VFS to not apply the umask
  * and use check_acl for acl permission checks when defined.
  */
-#define IS_ACL(inode)		__IS_FLG(inode, MS_POSIXACL)
+#define IS_ACL(inode)		__IS_FLG(inode, MS_POSIXACL | MS_RICHACL)
 
 /* the read-only stuff doesn't really belong here, but any other place is
    probably as bad and I don't want to create yet another include file. */
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 07/26] vfs: Optimize out IS_RICHACL() if CONFIG_FS_RICHACL is not defined
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (5 preceding siblings ...)
  2011-09-05 17:25   ` Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25   ` Aneesh Kumar K.V
                   ` (30 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

if CONFIG_FS_RICHACL is not defined optimize out
the ACL check function.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/Kconfig         |    3 +++
 include/linux/fs.h |    5 +++++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/fs/Kconfig b/fs/Kconfig
index 9fe0b34..7939190 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -46,6 +46,9 @@ endif # BLOCK
 config FS_POSIX_ACL
 	def_bool n
 
+config FS_RICHACL
+	def_bool n
+
 config EXPORTFS
 	tristate
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6eac730..1ddec24 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -273,7 +273,12 @@ struct inodes_stat_t {
 #define IS_APPEND(inode)	((inode)->i_flags & S_APPEND)
 #define IS_IMMUTABLE(inode)	((inode)->i_flags & S_IMMUTABLE)
 #define IS_POSIXACL(inode)	__IS_FLG(inode, MS_POSIXACL)
+
+#ifdef CONFIG_FS_RICHACL
 #define IS_RICHACL(inode)	__IS_FLG(inode, MS_RICHACL)
+#else
+#define IS_RICHACL(inode)	0
+#endif
 
 #define IS_DEADDIR(inode)	((inode)->i_flags & S_DEAD)
 #define IS_NOCMTIME(inode)	((inode)->i_flags & S_NOCMTIME)
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 08/26] vfs: Add new file and directory create permission flags
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Some permission models distinguish between the permission to create a
non-directory and a directory.  Pass this information down to
inode_permission() as mask flags

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/namei.c         |   26 +++++++++++++++-----------
 include/linux/fs.h |    2 ++
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index a7a7ac0..d52a4cd 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -336,7 +336,8 @@ static inline int do_inode_permission(struct inode *inode, int mask)
  * for filesystem access without changing the "normal" uids which
  * are used for other things.
  *
- * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask.
+ * When checking for MAY_APPEND, MAY_CREATE_FILE, MAY_CREATE_DIR,
+ * MAY_WRITE must also be set in @mask.
  */
 int inode_permission(struct inode *inode, int mask)
 {
@@ -1923,13 +1924,15 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
  *  3. We should have write and exec permissions on dir
  *  4. We can't do it if dir is immutable (done in permission())
  */
-static inline int may_create(struct inode *dir, struct dentry *child)
+static inline int may_create(struct inode *dir, struct dentry *child, int isdir)
 {
+	int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE;
+
 	if (child->d_inode)
 		return -EEXIST;
 	if (IS_DEADDIR(dir))
 		return -ENOENT;
-	return inode_permission(dir, MAY_WRITE | MAY_EXEC);
+	return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask);
 }
 
 /*
@@ -1977,7 +1980,7 @@ void unlock_rename(struct dentry *p1, struct dentry *p2)
 int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
 		struct nameidata *nd)
 {
-	int error = may_create(dir, dentry);
+	int error = may_create(dir, dentry, 0);
 
 	if (error)
 		return error;
@@ -2436,7 +2439,7 @@ EXPORT_SYMBOL(user_path_create);
 
 int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
 {
-	int error = may_create(dir, dentry);
+	int error = may_create(dir, dentry, 0);
 
 	if (error)
 		return error;
@@ -2533,7 +2536,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, int, mode, unsigned, dev)
 
 int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
-	int error = may_create(dir, dentry);
+	int error = may_create(dir, dentry, 1);
 
 	if (error)
 		return error;
@@ -2813,7 +2816,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname)
 
 int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
 {
-	int error = may_create(dir, dentry);
+	int error = may_create(dir, dentry, 0);
 
 	if (error)
 		return error;
@@ -2879,7 +2882,10 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
 	if (!inode)
 		return -ENOENT;
 
-	error = may_create(dir, new_dentry);
+	if (S_ISDIR(inode->i_mode))
+		return -EPERM;
+
+	error = may_create(dir, new_dentry, 0);
 	if (error)
 		return error;
 
@@ -2893,8 +2899,6 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
 		return -EPERM;
 	if (!dir->i_op->link)
 		return -EPERM;
-	if (S_ISDIR(inode->i_mode))
-		return -EPERM;
 
 	error = security_inode_link(old_dentry, dir, new_dentry);
 	if (error)
@@ -3102,7 +3106,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 		return error;
 
 	if (!new_dentry->d_inode)
-		error = may_create(new_dir, new_dentry);
+		error = may_create(new_dir, new_dentry, is_dir);
 	else
 		error = may_delete(new_dir, new_dentry, is_dir);
 	if (error)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1ddec24..8707f43 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -67,6 +67,8 @@ struct inodes_stat_t {
 #define MAY_CHDIR		0x00000040
 /* called from RCU mode, don't block */
 #define MAY_NOT_BLOCK		0x00000080
+#define MAY_CREATE_FILE		0x00000100
+#define MAY_CREATE_DIR		0x00000200
 
 /*
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 08/26] vfs: Add new file and directory create permission flags
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA
  Cc: aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Some permission models distinguish between the permission to create a
non-directory and a directory.  Pass this information down to
inode_permission() as mask flags

Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 fs/namei.c         |   26 +++++++++++++++-----------
 include/linux/fs.h |    2 ++
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index a7a7ac0..d52a4cd 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -336,7 +336,8 @@ static inline int do_inode_permission(struct inode *inode, int mask)
  * for filesystem access without changing the "normal" uids which
  * are used for other things.
  *
- * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask.
+ * When checking for MAY_APPEND, MAY_CREATE_FILE, MAY_CREATE_DIR,
+ * MAY_WRITE must also be set in @mask.
  */
 int inode_permission(struct inode *inode, int mask)
 {
@@ -1923,13 +1924,15 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
  *  3. We should have write and exec permissions on dir
  *  4. We can't do it if dir is immutable (done in permission())
  */
-static inline int may_create(struct inode *dir, struct dentry *child)
+static inline int may_create(struct inode *dir, struct dentry *child, int isdir)
 {
+	int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE;
+
 	if (child->d_inode)
 		return -EEXIST;
 	if (IS_DEADDIR(dir))
 		return -ENOENT;
-	return inode_permission(dir, MAY_WRITE | MAY_EXEC);
+	return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask);
 }
 
 /*
@@ -1977,7 +1980,7 @@ void unlock_rename(struct dentry *p1, struct dentry *p2)
 int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
 		struct nameidata *nd)
 {
-	int error = may_create(dir, dentry);
+	int error = may_create(dir, dentry, 0);
 
 	if (error)
 		return error;
@@ -2436,7 +2439,7 @@ EXPORT_SYMBOL(user_path_create);
 
 int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
 {
-	int error = may_create(dir, dentry);
+	int error = may_create(dir, dentry, 0);
 
 	if (error)
 		return error;
@@ -2533,7 +2536,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, int, mode, unsigned, dev)
 
 int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
-	int error = may_create(dir, dentry);
+	int error = may_create(dir, dentry, 1);
 
 	if (error)
 		return error;
@@ -2813,7 +2816,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname)
 
 int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
 {
-	int error = may_create(dir, dentry);
+	int error = may_create(dir, dentry, 0);
 
 	if (error)
 		return error;
@@ -2879,7 +2882,10 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
 	if (!inode)
 		return -ENOENT;
 
-	error = may_create(dir, new_dentry);
+	if (S_ISDIR(inode->i_mode))
+		return -EPERM;
+
+	error = may_create(dir, new_dentry, 0);
 	if (error)
 		return error;
 
@@ -2893,8 +2899,6 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
 		return -EPERM;
 	if (!dir->i_op->link)
 		return -EPERM;
-	if (S_ISDIR(inode->i_mode))
-		return -EPERM;
 
 	error = security_inode_link(old_dentry, dir, new_dentry);
 	if (error)
@@ -3102,7 +3106,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 		return error;
 
 	if (!new_dentry->d_inode)
-		error = may_create(new_dir, new_dentry);
+		error = may_create(new_dir, new_dentry, is_dir);
 	else
 		error = may_delete(new_dir, new_dentry, is_dir);
 	if (error)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1ddec24..8707f43 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -67,6 +67,8 @@ struct inodes_stat_t {
 #define MAY_CHDIR		0x00000040
 /* called from RCU mode, don't block */
 #define MAY_NOT_BLOCK		0x00000080
+#define MAY_CREATE_FILE		0x00000100
+#define MAY_CREATE_DIR		0x00000200
 
 /*
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (7 preceding siblings ...)
  2011-09-05 17:25   ` Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-07 20:39     ` J. Bruce Fields
  2011-09-05 17:25 ` [PATCH -V6 10/26] vfs: Make the inode passed to inode_change_ok non-const Aneesh Kumar K.V
                   ` (28 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Normally, deleting a file requires write access to the parent directory.
Some permission models use a different permission on the parent
directory to indicate delete access.  In addition, a process can have
per-file delete access even without delete access on the parent
directory.

Introduce two new inode_permission() mask flags and use them in
may_delete()

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/namei.c         |   41 +++++++++++++++++++++++++++--------------
 include/linux/fs.h |    2 ++
 2 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index d52a4cd..eacb530 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -337,7 +337,7 @@ static inline int do_inode_permission(struct inode *inode, int mask)
  * are used for other things.
  *
  * When checking for MAY_APPEND, MAY_CREATE_FILE, MAY_CREATE_DIR,
- * MAY_WRITE must also be set in @mask.
+ * MAY_DELETE_CHILD, MAY_DELETE_SELF, MAY_WRITE must also be set in @mask.
  */
 int inode_permission(struct inode *inode, int mask)
 {
@@ -1862,7 +1862,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
 		return 0;
 
 other_userns:
-	return !ns_capable(inode_userns(inode), CAP_FOWNER);
+	return 1;
 }
 
 /*
@@ -1884,30 +1884,43 @@ other_userns:
  * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
  *     nfs_async_unlink().
  */
-static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
+static int may_delete(struct inode *dir, struct dentry *victim,
+		      int isdir, int replace)
 {
-	int error;
+	int mask, error, is_sticky;
+	struct inode *inode = victim->d_inode;
 
-	if (!victim->d_inode)
+	if (!inode)
 		return -ENOENT;
 
 	BUG_ON(victim->d_parent->d_inode != dir);
 	audit_inode_child(victim, dir);
 
-	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
+	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
+	if (replace)
+		mask |= S_ISDIR(inode->i_mode) ?
+			MAY_CREATE_DIR : MAY_CREATE_FILE;
+	is_sticky = check_sticky(dir, inode);
+	error = inode_permission(dir, mask);
+	if ((error || is_sticky) && IS_RICHACL(inode) &&
+	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
+	    !inode_permission(inode, MAY_DELETE_SELF))
+		error = 0;
+	else if (!error && is_sticky &&
+		 !ns_capable(inode_userns(inode), CAP_FOWNER))
+		error = -EPERM;
 	if (error)
 		return error;
 	if (IS_APPEND(dir))
 		return -EPERM;
-	if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
-	    IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
+	if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
 		return -EPERM;
 	if (isdir) {
-		if (!S_ISDIR(victim->d_inode->i_mode))
+		if (!S_ISDIR(inode->i_mode))
 			return -ENOTDIR;
 		if (IS_ROOT(victim))
 			return -EBUSY;
-	} else if (S_ISDIR(victim->d_inode->i_mode))
+	} else if (S_ISDIR(inode->i_mode))
 		return -EISDIR;
 	if (IS_DEADDIR(dir))
 		return -ENOENT;
@@ -2614,7 +2627,7 @@ void dentry_unhash(struct dentry *dentry)
 
 int vfs_rmdir(struct inode *dir, struct dentry *dentry)
 {
-	int error = may_delete(dir, dentry, 1);
+	int error = may_delete(dir, dentry, 1, 0);
 
 	if (error)
 		return error;
@@ -2707,7 +2720,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
 
 int vfs_unlink(struct inode *dir, struct dentry *dentry)
 {
-	int error = may_delete(dir, dentry, 0);
+	int error = may_delete(dir, dentry, 0, 0);
 
 	if (error)
 		return error;
@@ -3101,14 +3114,14 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	if (old_dentry->d_inode == new_dentry->d_inode)
  		return 0;
  
-	error = may_delete(old_dir, old_dentry, is_dir);
+	error = may_delete(old_dir, old_dentry, is_dir, 0);
 	if (error)
 		return error;
 
 	if (!new_dentry->d_inode)
 		error = may_create(new_dir, new_dentry, is_dir);
 	else
-		error = may_delete(new_dir, new_dentry, is_dir);
+		error = may_delete(new_dir, new_dentry, is_dir, 1);
 	if (error)
 		return error;
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8707f43..c5c98c5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -69,6 +69,8 @@ struct inodes_stat_t {
 #define MAY_NOT_BLOCK		0x00000080
 #define MAY_CREATE_FILE		0x00000100
 #define MAY_CREATE_DIR		0x00000200
+#define MAY_DELETE_CHILD	0x00000400
+#define MAY_DELETE_SELF		0x00000800
 
 /*
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 10/26] vfs: Make the inode passed to inode_change_ok non-const
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (8 preceding siblings ...)
  2011-09-05 17:25 ` [PATCH -V6 09/26] vfs: Add delete child and delete self " Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-07 20:43   ` J. Bruce Fields
  2011-09-05 17:25   ` Aneesh Kumar K.V
                   ` (27 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

We will need to call iop->permission and iop->get_acl from
inode_change_ok() for additional permission checks, and both take a
non-const inode.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/attr.c          |    2 +-
 include/linux/fs.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index 538e279..f15e9e3 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -26,7 +26,7 @@
  * Should be called as the first thing in ->setattr implementations,
  * possibly after taking additional locks.
  */
-int inode_change_ok(const struct inode *inode, struct iattr *attr)
+int inode_change_ok(struct inode *inode, struct iattr *attr)
 {
 	unsigned int ia_valid = attr->ia_valid;
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index c5c98c5..8afb054 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2568,7 +2568,7 @@ extern int buffer_migrate_page(struct address_space *,
 #define buffer_migrate_page NULL
 #endif
 
-extern int inode_change_ok(const struct inode *, struct iattr *);
+extern int inode_change_ok(struct inode *, struct iattr *);
 extern int inode_newsize_ok(const struct inode *, loff_t offset);
 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 11/26] vfs: Add permission flags for setting file attributes
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Some permission models can allow processes to take ownership of a file,
change the file permissions, and set the file timestamps.  Introduce new
permission mask flags and check for those permissions in
inode_change_ok().

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/attr.c          |   70 +++++++++++++++++++++++++++++++++++++++++++--------
 fs/namei.c         |    2 +-
 include/linux/fs.h |    4 +++
 3 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index f15e9e3..00578b9 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -14,6 +14,55 @@
 #include <linux/fcntl.h>
 #include <linux/security.h>
 
+static int richacl_change_ok(struct inode *inode, int mask)
+{
+	if (!IS_RICHACL(inode))
+		return -EPERM;
+
+	if (inode->i_op->permission)
+		return inode->i_op->permission(inode, mask);
+
+	return check_acl(inode, mask);
+}
+
+static bool inode_uid_change_ok(struct inode *inode, uid_t ia_uid)
+{
+	if (current_fsuid() == inode->i_uid && ia_uid == inode->i_uid)
+		return true;
+	if (current_fsuid() == ia_uid &&
+	    richacl_change_ok(inode, MAY_TAKE_OWNERSHIP) == 0)
+		return true;
+	if (capable(CAP_CHOWN))
+		return true;
+	return false;
+}
+
+static bool inode_gid_change_ok(struct inode *inode, gid_t ia_gid)
+{
+	int in_group = in_group_p(ia_gid);
+	if (current_fsuid() == inode->i_uid &&
+	    (in_group || ia_gid == inode->i_gid))
+		return true;
+	if (in_group && richacl_change_ok(inode, MAY_TAKE_OWNERSHIP) == 0)
+		return true;
+	if (capable(CAP_CHOWN))
+		return true;
+	return false;
+}
+
+static bool inode_owner_permitted_or_capable(struct inode *inode, int mask)
+{
+	struct user_namespace *ns = inode_userns(inode);
+
+	if (current_user_ns() == ns && current_fsuid() == inode->i_uid)
+		return true;
+	if (richacl_change_ok(inode, mask) == 0)
+		return true;
+	if (ns_capable(ns, CAP_FOWNER))
+		return true;
+	return false;
+}
+
 /**
  * inode_change_ok - check if attribute changes to an inode are allowed
  * @inode:	inode to check
@@ -45,21 +94,20 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
 		return 0;
 
 	/* Make sure a caller can chown. */
-	if ((ia_valid & ATTR_UID) &&
-	    (current_fsuid() != inode->i_uid ||
-	     attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
-		return -EPERM;
+	if (ia_valid & ATTR_UID) {
+		if (!inode_uid_change_ok(inode, attr->ia_uid))
+			return -EPERM;
+	}
 
 	/* Make sure caller can chgrp. */
-	if ((ia_valid & ATTR_GID) &&
-	    (current_fsuid() != inode->i_uid ||
-	    (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
-	    !capable(CAP_CHOWN))
-		return -EPERM;
+	if (ia_valid & ATTR_GID) {
+		if (!inode_gid_change_ok(inode, attr->ia_gid))
+			return -EPERM;
+	}
 
 	/* Make sure a caller can chmod. */
 	if (ia_valid & ATTR_MODE) {
-		if (!inode_owner_or_capable(inode))
+		if (!inode_owner_permitted_or_capable(inode, MAY_CHMOD))
 			return -EPERM;
 		/* Also check the setgid bit! */
 		if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
@@ -69,7 +117,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
 
 	/* Check for setting the inode time. */
 	if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
-		if (!inode_owner_or_capable(inode))
+		if (!inode_owner_permitted_or_capable(inode, MAY_SET_TIMES))
 			return -EPERM;
 	}
 
diff --git a/fs/namei.c b/fs/namei.c
index eacb530..a4d61d1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -174,7 +174,7 @@ void putname(const char *name)
 EXPORT_SYMBOL(putname);
 #endif
 
-static int check_acl(struct inode *inode, int mask)
+int check_acl(struct inode *inode, int mask)
 {
 #ifdef CONFIG_FS_POSIX_ACL
 	struct posix_acl *acl;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8afb054..8d5d6e4 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -71,6 +71,9 @@ struct inodes_stat_t {
 #define MAY_CREATE_DIR		0x00000200
 #define MAY_DELETE_CHILD	0x00000400
 #define MAY_DELETE_SELF		0x00000800
+#define MAY_TAKE_OWNERSHIP	0x00001000
+#define MAY_CHMOD		0x00002000
+#define MAY_SET_TIMES		0x00004000
 
 /*
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
@@ -2234,6 +2237,7 @@ extern sector_t bmap(struct inode *, sector_t);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int inode_permission(struct inode *, int);
 extern int generic_permission(struct inode *, int);
+extern int check_acl(struct inode *, int);
 
 static inline bool execute_ok(struct inode *inode)
 {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 11/26] vfs: Add permission flags for setting file attributes
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA
  Cc: aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Some permission models can allow processes to take ownership of a file,
change the file permissions, and set the file timestamps.  Introduce new
permission mask flags and check for those permissions in
inode_change_ok().

Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 fs/attr.c          |   70 +++++++++++++++++++++++++++++++++++++++++++--------
 fs/namei.c         |    2 +-
 include/linux/fs.h |    4 +++
 3 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index f15e9e3..00578b9 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -14,6 +14,55 @@
 #include <linux/fcntl.h>
 #include <linux/security.h>
 
+static int richacl_change_ok(struct inode *inode, int mask)
+{
+	if (!IS_RICHACL(inode))
+		return -EPERM;
+
+	if (inode->i_op->permission)
+		return inode->i_op->permission(inode, mask);
+
+	return check_acl(inode, mask);
+}
+
+static bool inode_uid_change_ok(struct inode *inode, uid_t ia_uid)
+{
+	if (current_fsuid() == inode->i_uid && ia_uid == inode->i_uid)
+		return true;
+	if (current_fsuid() == ia_uid &&
+	    richacl_change_ok(inode, MAY_TAKE_OWNERSHIP) == 0)
+		return true;
+	if (capable(CAP_CHOWN))
+		return true;
+	return false;
+}
+
+static bool inode_gid_change_ok(struct inode *inode, gid_t ia_gid)
+{
+	int in_group = in_group_p(ia_gid);
+	if (current_fsuid() == inode->i_uid &&
+	    (in_group || ia_gid == inode->i_gid))
+		return true;
+	if (in_group && richacl_change_ok(inode, MAY_TAKE_OWNERSHIP) == 0)
+		return true;
+	if (capable(CAP_CHOWN))
+		return true;
+	return false;
+}
+
+static bool inode_owner_permitted_or_capable(struct inode *inode, int mask)
+{
+	struct user_namespace *ns = inode_userns(inode);
+
+	if (current_user_ns() == ns && current_fsuid() == inode->i_uid)
+		return true;
+	if (richacl_change_ok(inode, mask) == 0)
+		return true;
+	if (ns_capable(ns, CAP_FOWNER))
+		return true;
+	return false;
+}
+
 /**
  * inode_change_ok - check if attribute changes to an inode are allowed
  * @inode:	inode to check
@@ -45,21 +94,20 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
 		return 0;
 
 	/* Make sure a caller can chown. */
-	if ((ia_valid & ATTR_UID) &&
-	    (current_fsuid() != inode->i_uid ||
-	     attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
-		return -EPERM;
+	if (ia_valid & ATTR_UID) {
+		if (!inode_uid_change_ok(inode, attr->ia_uid))
+			return -EPERM;
+	}
 
 	/* Make sure caller can chgrp. */
-	if ((ia_valid & ATTR_GID) &&
-	    (current_fsuid() != inode->i_uid ||
-	    (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
-	    !capable(CAP_CHOWN))
-		return -EPERM;
+	if (ia_valid & ATTR_GID) {
+		if (!inode_gid_change_ok(inode, attr->ia_gid))
+			return -EPERM;
+	}
 
 	/* Make sure a caller can chmod. */
 	if (ia_valid & ATTR_MODE) {
-		if (!inode_owner_or_capable(inode))
+		if (!inode_owner_permitted_or_capable(inode, MAY_CHMOD))
 			return -EPERM;
 		/* Also check the setgid bit! */
 		if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
@@ -69,7 +117,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
 
 	/* Check for setting the inode time. */
 	if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
-		if (!inode_owner_or_capable(inode))
+		if (!inode_owner_permitted_or_capable(inode, MAY_SET_TIMES))
 			return -EPERM;
 	}
 
diff --git a/fs/namei.c b/fs/namei.c
index eacb530..a4d61d1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -174,7 +174,7 @@ void putname(const char *name)
 EXPORT_SYMBOL(putname);
 #endif
 
-static int check_acl(struct inode *inode, int mask)
+int check_acl(struct inode *inode, int mask)
 {
 #ifdef CONFIG_FS_POSIX_ACL
 	struct posix_acl *acl;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8afb054..8d5d6e4 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -71,6 +71,9 @@ struct inodes_stat_t {
 #define MAY_CREATE_DIR		0x00000200
 #define MAY_DELETE_CHILD	0x00000400
 #define MAY_DELETE_SELF		0x00000800
+#define MAY_TAKE_OWNERSHIP	0x00001000
+#define MAY_CHMOD		0x00002000
+#define MAY_SET_TIMES		0x00004000
 
 /*
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
@@ -2234,6 +2237,7 @@ extern sector_t bmap(struct inode *, sector_t);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int inode_permission(struct inode *, int);
 extern int generic_permission(struct inode *, int);
+extern int check_acl(struct inode *, int);
 
 static inline bool execute_ok(struct inode *inode)
 {
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 12/26] vfs: Make acl_permission_check() work for richacls
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (10 preceding siblings ...)
  2011-09-05 17:25   ` Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25 ` [PATCH -V6 13/26] richacl: In-memory representation and helper functions Aneesh Kumar K.V
                   ` (25 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/namei.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index a4d61d1..ce67eb1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -230,6 +230,20 @@ static int acl_permission_check(struct inode *inode, int mask)
 	if (current_user_ns() != inode_userns(inode))
 		goto other_perms;
 
+	if (IS_RICHACL(inode)) {
+		int error = check_acl(inode, mask);
+		if (error != -EAGAIN)
+			return error;
+		if (mask & (MAY_DELETE_SELF | MAY_TAKE_OWNERSHIP |
+			    MAY_CHMOD | MAY_SET_TIMES)) {
+			/*
+			 * The file permission bit cannot grant these
+			 * permissions.
+			 */
+			return -EACCES;
+		}
+	}
+
 	if (likely(current_fsuid() == inode->i_uid))
 		mode >>= 6;
 	else {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 13/26] richacl: In-memory representation and helper functions
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (11 preceding siblings ...)
  2011-09-05 17:25 ` [PATCH -V6 12/26] vfs: Make acl_permission_check() work for richacls Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25   ` Aneesh Kumar K.V
                   ` (24 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

A richacl consists of an NFSv4 acl and an owner, group, and other mask.
These three masks correspond to the owner, group, and other file
permission bits, but they contain NFSv4 permissions instead of POSIX
permissions.

Each entry in the NFSv4 acl applies to the file owner (OWNER@), the
owning group (GROUP@), literally everyone (EVERYONE@), or to a specific
uid or gid.

As in the standard POSIX file permission model, each process is the
owner, group, or other file class.  A richacl grants a requested access
only if the NFSv4 acl in the richacl grants the access (according to the
NFSv4 permission check algorithm), and the file mask that applies to the
process includes the requested permissions.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/Makefile             |    2 +
 fs/richacl_base.c       |  109 +++++++++++++++++++++
 include/linux/richacl.h |  245 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 356 insertions(+), 0 deletions(-)
 create mode 100644 fs/richacl_base.c
 create mode 100644 include/linux/richacl.h

diff --git a/fs/Makefile b/fs/Makefile
index afc1096..7612168 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -48,6 +48,8 @@ obj-$(CONFIG_NFS_COMMON)	+= nfs_common/
 obj-$(CONFIG_GENERIC_ACL)	+= generic_acl.o
 
 obj-$(CONFIG_FHANDLE)		+= fhandle.o
+obj-$(CONFIG_FS_RICHACL)	+= richacl.o
+richacl-y			:= richacl_base.o
 
 obj-y				+= quota/
 
diff --git a/fs/richacl_base.c b/fs/richacl_base.c
new file mode 100644
index 0000000..3536626
--- /dev/null
+++ b/fs/richacl_base.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2006, 2010  Novell, Inc.
+ * Written by Andreas Gruenbacher <agruen@kernel.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/richacl.h>
+
+MODULE_LICENSE("GPL");
+
+/*
+ * Special e_who identifiers:  ACEs which have ACE4_SPECIAL_WHO set in
+ * ace->e_flags use these constants in ace->u.e_who.
+ *
+ * For efficiency, we compare pointers instead of comparing strings.
+ */
+const char richace_owner_who[]	  = "OWNER@";
+EXPORT_SYMBOL_GPL(richace_owner_who);
+const char richace_group_who[]	  = "GROUP@";
+EXPORT_SYMBOL_GPL(richace_group_who);
+const char richace_everyone_who[] = "EVERYONE@";
+EXPORT_SYMBOL_GPL(richace_everyone_who);
+
+/**
+ * richacl_alloc  -  allocate a richacl
+ * @count:	number of entries
+ */
+struct richacl *
+richacl_alloc(int count)
+{
+	size_t size = sizeof(struct richacl) + count * sizeof(struct richace);
+	struct richacl *acl = kzalloc(size, GFP_KERNEL);
+
+	if (acl) {
+		atomic_set(&acl->a_refcount, 1);
+		acl->a_count = count;
+	}
+	return acl;
+}
+EXPORT_SYMBOL_GPL(richacl_alloc);
+
+/**
+ * richacl_clone  -  create a copy of a richacl
+ */
+static struct richacl *
+richacl_clone(const struct richacl *acl)
+{
+	int count = acl->a_count;
+	size_t size = sizeof(struct richacl) + count * sizeof(struct richace);
+	struct richacl *dup = kmalloc(size, GFP_KERNEL);
+
+	if (dup) {
+		memcpy(dup, acl, size);
+		atomic_set(&dup->a_refcount, 1);
+	}
+	return dup;
+}
+
+/**
+ * richace_is_same_identifier  -  are both identifiers the same?
+ */
+int
+richace_is_same_identifier(const struct richace *a, const struct richace *b)
+{
+#define WHO_FLAGS (ACE4_SPECIAL_WHO | ACE4_IDENTIFIER_GROUP)
+	if ((a->e_flags & WHO_FLAGS) != (b->e_flags & WHO_FLAGS))
+		return 0;
+	if (a->e_flags & ACE4_SPECIAL_WHO)
+		return a->u.e_who == b->u.e_who;
+	else
+		return a->u.e_id == b->u.e_id;
+#undef WHO_FLAGS
+}
+
+/**
+ * richacl_set_who  -  set a special who value
+ * @ace:	acl entry
+ * @who:	who value to use
+ */
+int
+richace_set_who(struct richace *ace, const char *who)
+{
+	if (!strcmp(who, richace_owner_who))
+		who = richace_owner_who;
+	else if (!strcmp(who, richace_group_who))
+		who = richace_group_who;
+	else if (!strcmp(who, richace_everyone_who))
+		who = richace_everyone_who;
+	else
+		return -EINVAL;
+
+	ace->u.e_who = who;
+	ace->e_flags |= ACE4_SPECIAL_WHO;
+	ace->e_flags &= ~ACE4_IDENTIFIER_GROUP;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(richace_set_who);
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
new file mode 100644
index 0000000..745cfc1
--- /dev/null
+++ b/include/linux/richacl.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2006, 2010  Novell, Inc.
+ * Written by Andreas Gruenbacher <agruen@kernel.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __RICHACL_H
+#define __RICHACL_H
+#include <linux/slab.h>
+
+struct richace {
+	unsigned short	e_type;
+	unsigned short	e_flags;
+	unsigned int	e_mask;
+	union {
+		unsigned int	e_id;
+		const char	*e_who;
+	} u;
+};
+
+struct richacl {
+	atomic_t	a_refcount;
+	unsigned int	a_owner_mask;
+	unsigned int	a_group_mask;
+	unsigned int	a_other_mask;
+	unsigned short	a_count;
+	unsigned short	a_flags;
+	struct richace	a_entries[0];
+};
+
+#define richacl_for_each_entry(_ace, _acl) \
+	for (_ace = _acl->a_entries; \
+	     _ace != _acl->a_entries + _acl->a_count; \
+	     _ace++)
+
+#define richacl_for_each_entry_reverse(_ace, _acl) \
+	for (_ace = _acl->a_entries + _acl->a_count - 1; \
+	     _ace != _acl->a_entries - 1; \
+	     _ace--)
+
+/* Flag values defined by rich-acl */
+#define ACL4_MASKED			0x80
+
+#define ACL4_VALID_FLAGS (			\
+		ACL4_MASKED)
+
+/* e_type values */
+#define ACE4_ACCESS_ALLOWED_ACE_TYPE	0x0000
+#define ACE4_ACCESS_DENIED_ACE_TYPE	0x0001
+/*#define ACE4_SYSTEM_AUDIT_ACE_TYPE	0x0002*/
+/*#define ACE4_SYSTEM_ALARM_ACE_TYPE	0x0003*/
+
+/* e_flags bitflags */
+#define ACE4_FILE_INHERIT_ACE		0x0001
+#define ACE4_DIRECTORY_INHERIT_ACE	0x0002
+#define ACE4_NO_PROPAGATE_INHERIT_ACE	0x0004
+#define ACE4_INHERIT_ONLY_ACE		0x0008
+/*#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG	0x0010*/
+/*#define ACE4_FAILED_ACCESS_ACE_FLAG	0x0020*/
+#define ACE4_IDENTIFIER_GROUP		0x0040
+/* in-memory representation only */
+#define ACE4_SPECIAL_WHO		0x4000
+
+#define ACE4_VALID_FLAGS (			\
+	ACE4_FILE_INHERIT_ACE |			\
+	ACE4_DIRECTORY_INHERIT_ACE |		\
+	ACE4_NO_PROPAGATE_INHERIT_ACE |		\
+	ACE4_INHERIT_ONLY_ACE |			\
+	ACE4_IDENTIFIER_GROUP)
+
+/* e_mask bitflags */
+#define ACE4_READ_DATA			0x00000001
+#define ACE4_LIST_DIRECTORY		0x00000001
+#define ACE4_WRITE_DATA			0x00000002
+#define ACE4_ADD_FILE			0x00000002
+#define ACE4_APPEND_DATA		0x00000004
+#define ACE4_ADD_SUBDIRECTORY		0x00000004
+#define ACE4_READ_NAMED_ATTRS		0x00000008
+#define ACE4_WRITE_NAMED_ATTRS		0x00000010
+#define ACE4_EXECUTE			0x00000020
+#define ACE4_DELETE_CHILD		0x00000040
+#define ACE4_READ_ATTRIBUTES		0x00000080
+#define ACE4_WRITE_ATTRIBUTES		0x00000100
+#define ACE4_WRITE_RETENTION		0x00000200
+#define ACE4_WRITE_RETENTION_HOLD	0x00000400
+#define ACE4_DELETE			0x00010000
+#define ACE4_READ_ACL			0x00020000
+#define ACE4_WRITE_ACL			0x00040000
+#define ACE4_WRITE_OWNER		0x00080000
+#define ACE4_SYNCHRONIZE		0x00100000
+
+/* Valid ACE4_* flags for directories and non-directories */
+#define ACE4_VALID_MASK (				\
+	ACE4_READ_DATA | ACE4_LIST_DIRECTORY |		\
+	ACE4_WRITE_DATA | ACE4_ADD_FILE |		\
+	ACE4_APPEND_DATA | ACE4_ADD_SUBDIRECTORY |	\
+	ACE4_READ_NAMED_ATTRS |				\
+	ACE4_WRITE_NAMED_ATTRS |			\
+	ACE4_EXECUTE |					\
+	ACE4_DELETE_CHILD |				\
+	ACE4_READ_ATTRIBUTES |				\
+	ACE4_WRITE_ATTRIBUTES |				\
+	ACE4_WRITE_RETENTION |				\
+	ACE4_WRITE_RETENTION_HOLD |			\
+	ACE4_DELETE |					\
+	ACE4_READ_ACL |					\
+	ACE4_WRITE_ACL |				\
+	ACE4_WRITE_OWNER |				\
+	ACE4_SYNCHRONIZE)
+
+/**
+ * richacl_get  -  grab another reference to a richacl handle
+ */
+static inline struct richacl *
+richacl_get(struct richacl *acl)
+{
+	if (acl)
+		atomic_inc(&acl->a_refcount);
+	return acl;
+}
+
+/**
+ * richacl_put  -  free a richacl handle
+ */
+static inline void
+richacl_put(struct richacl *acl)
+{
+	if (acl && atomic_dec_and_test(&acl->a_refcount))
+		kfree(acl);
+}
+
+/*
+ * Special e_who identifiers: we use these pointer values in comparisons
+ * instead of doing a strcmp.
+ */
+extern const char richace_owner_who[];
+extern const char richace_group_who[];
+extern const char richace_everyone_who[];
+
+/**
+ * richace_is_owner  -  check if @ace is an OWNER@ entry
+ */
+static inline int
+richace_is_owner(const struct richace *ace)
+{
+	return (ace->e_flags & ACE4_SPECIAL_WHO) &&
+	       ace->u.e_who == richace_owner_who;
+}
+
+/**
+ * richace_is_group  -  check if @ace is a GROUP@ entry
+ */
+static inline int
+richace_is_group(const struct richace *ace)
+{
+	return (ace->e_flags & ACE4_SPECIAL_WHO) &&
+	       ace->u.e_who == richace_group_who;
+}
+
+/**
+ * richace_is_everyone  -  check if @ace is an EVERYONE@ entry
+ */
+static inline int
+richace_is_everyone(const struct richace *ace)
+{
+	return (ace->e_flags & ACE4_SPECIAL_WHO) &&
+	       ace->u.e_who == richace_everyone_who;
+}
+
+/**
+ * richace_is_unix_id  -  check if @ace applies to a specific uid or gid
+ */
+static inline int
+richace_is_unix_id(const struct richace *ace)
+{
+	return !(ace->e_flags & ACE4_SPECIAL_WHO);
+}
+
+/**
+ * richace_is_inherit_only  -  check if @ace is for inheritance only
+ *
+ * ACEs with the %ACE4_INHERIT_ONLY_ACE flag set have no effect during
+ * permission checking.
+ */
+static inline int
+richace_is_inherit_only(const struct richace *ace)
+{
+	return ace->e_flags & ACE4_INHERIT_ONLY_ACE;
+}
+
+/**
+ * richace_is_inheritable  -  check if @ace is inheritable
+ */
+static inline int
+richace_is_inheritable(const struct richace *ace)
+{
+	return ace->e_flags & (ACE4_FILE_INHERIT_ACE |
+			       ACE4_DIRECTORY_INHERIT_ACE);
+}
+
+/**
+ * richace_clear_inheritance_flags  - clear all inheritance flags in @ace
+ */
+static inline void
+richace_clear_inheritance_flags(struct richace *ace)
+{
+	ace->e_flags &= ~(ACE4_FILE_INHERIT_ACE |
+			  ACE4_DIRECTORY_INHERIT_ACE |
+			  ACE4_NO_PROPAGATE_INHERIT_ACE |
+			  ACE4_INHERIT_ONLY_ACE);
+}
+
+/**
+ * richace_is_allow  -  check if @ace is an %ALLOW type entry
+ */
+static inline int
+richace_is_allow(const struct richace *ace)
+{
+	return ace->e_type == ACE4_ACCESS_ALLOWED_ACE_TYPE;
+}
+
+/**
+ * richace_is_deny  -  check if @ace is a %DENY type entry
+ */
+static inline int
+richace_is_deny(const struct richace *ace)
+{
+	return ace->e_type == ACE4_ACCESS_DENIED_ACE_TYPE;
+}
+
+extern struct richacl *richacl_alloc(int);
+extern int richace_is_same_identifier(const struct richace *,
+				      const struct richace *);
+extern int richace_set_who(struct richace *, const char *);
+
+#endif /* __RICHACL_H */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 14/26] richacl: Permission mapping functions
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

We need to map from POSIX permissions to NFSv4 permissions when a
chmod() is done, from NFSv4 permissions to POSIX permissions when an acl
is set (which implicitly sets the file permission bits), and from the
MAY_READ/MAY_WRITE/MAY_EXEC/MAY_APPEND flags to NFSv4 permissions when
doing an access check in a richacl.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/richacl_base.c       |  118 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/richacl.h |   46 ++++++++++++++++++
 2 files changed, 164 insertions(+), 0 deletions(-)

diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index 3536626..d55b436 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -69,6 +69,124 @@ richacl_clone(const struct richacl *acl)
 }
 
 /**
+ * richacl_mask_to_mode  -  compute the file permission bits which correspond to @mask
+ * @mask:	%ACE4_* permission mask
+ *
+ * See richacl_masks_to_mode().
+ */
+static int
+richacl_mask_to_mode(unsigned int mask)
+{
+	int mode = 0;
+
+	if (mask & ACE4_POSIX_MODE_READ)
+		mode |= MAY_READ;
+	if (mask & ACE4_POSIX_MODE_WRITE)
+		mode |= MAY_WRITE;
+	if (mask & ACE4_POSIX_MODE_EXEC)
+		mode |= MAY_EXEC;
+
+	return mode;
+}
+
+/**
+ * richacl_masks_to_mode  -  compute the file permission bits from the file masks
+ *
+ * When setting a richacl, we set the file permission bits to indicate maximum
+ * permissions: for example, we set the Write permission when a mask contains
+ * ACE4_APPEND_DATA even if it does not also contain ACE4_WRITE_DATA.
+ *
+ * Permissions which are not in ACE4_POSIX_MODE_READ, ACE4_POSIX_MODE_WRITE, or
+ * ACE4_POSIX_MODE_EXEC cannot be represented in the file permission bits.
+ * Such permissions can still be effective, but not for new files or after a
+ * chmod(), and only if they were set explicitly, for example, by setting a
+ * richacl.
+ */
+int
+richacl_masks_to_mode(const struct richacl *acl)
+{
+	return richacl_mask_to_mode(acl->a_owner_mask) << 6 |
+	       richacl_mask_to_mode(acl->a_group_mask) << 3 |
+	       richacl_mask_to_mode(acl->a_other_mask);
+}
+EXPORT_SYMBOL_GPL(richacl_masks_to_mode);
+
+/**
+ * richacl_mode_to_mask  - compute a file mask from the lowest three mode bits
+ *
+ * When the file permission bits of a file are set with chmod(), this specifies
+ * the maximum permissions that processes will get.  All permissions beyond
+ * that will be removed from the file masks, and become ineffective.
+ *
+ * We also add in the permissions which are always allowed no matter what the
+ * acl says.
+ */
+unsigned int
+richacl_mode_to_mask(mode_t mode)
+{
+	unsigned int mask = ACE4_POSIX_ALWAYS_ALLOWED;
+
+	if (mode & MAY_READ)
+		mask |= ACE4_POSIX_MODE_READ;
+	if (mode & MAY_WRITE)
+		mask |= ACE4_POSIX_MODE_WRITE;
+	if (mode & MAY_EXEC)
+		mask |= ACE4_POSIX_MODE_EXEC;
+
+	return mask;
+}
+
+/**
+ * richacl_want_to_mask  - convert the iop->permission want argument to a mask
+ * @want:	@want argument of the permission inode operation
+ *
+ * When checking for append, @want is (MAY_WRITE | MAY_APPEND).
+ *
+ * Richacls use the iop->may_create and iop->may_delete hooks which are
+ * used for checking if creating and deleting files is allowed.  These hooks do
+ * not use richacl_want_to_mask(), so we do not have to deal with mapping
+ * MAY_WRITE to ACE4_ADD_FILE, ACE4_ADD_SUBDIRECTORY, and ACE4_DELETE_CHILD
+ * here.
+ */
+unsigned int
+richacl_want_to_mask(int want)
+{
+	unsigned int mask = 0;
+
+	if (want & MAY_READ)
+		mask |= ACE4_READ_DATA;
+	if (want & (MAY_APPEND |
+		    MAY_CREATE_FILE | MAY_CREATE_DIR |
+		    MAY_DELETE_CHILD | MAY_DELETE_SELF |
+		    MAY_TAKE_OWNERSHIP | MAY_CHMOD | MAY_SET_TIMES)) {
+		if (want & MAY_APPEND)
+			mask |= ACE4_APPEND_DATA;
+		else if (want & MAY_DELETE_SELF)
+			mask |= ACE4_DELETE;
+		else if (want & MAY_TAKE_OWNERSHIP)
+			mask |= ACE4_WRITE_OWNER;
+		else if (want & MAY_CHMOD)
+			mask |= ACE4_WRITE_ACL;
+		else if (want & MAY_SET_TIMES)
+			mask |= ACE4_WRITE_ATTRIBUTES;
+		else {
+			if (want & MAY_CREATE_FILE)
+				mask |= ACE4_ADD_FILE;
+			if (want & MAY_CREATE_DIR)
+				mask |= ACE4_ADD_SUBDIRECTORY;
+			if (want & MAY_DELETE_CHILD)
+				mask |= ACE4_DELETE_CHILD;
+		}
+	} else if (want & MAY_WRITE)
+		mask |= ACE4_WRITE_DATA;
+	if (want & MAY_EXEC)
+		mask |= ACE4_EXECUTE;
+
+	return mask;
+}
+EXPORT_SYMBOL_GPL(richacl_want_to_mask);
+
+/**
  * richace_is_same_identifier  -  are both identifiers the same?
  */
 int
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index 745cfc1..7433ba3 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -117,6 +117,49 @@ struct richacl {
 	ACE4_WRITE_OWNER |				\
 	ACE4_SYNCHRONIZE)
 
+/*
+ * The POSIX permissions are supersets of the following NFSv4 permissions:
+ *
+ *  - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type
+ *    of the file system object.
+ *
+ *  - MAY_WRITE maps to WRITE_DATA or ACE4_APPEND_DATA for files, and to
+ *    ADD_FILE, ACE4_ADD_SUBDIRECTORY, or ACE4_DELETE_CHILD for directories.
+ *
+ *  - MAY_EXECUTE maps to ACE4_EXECUTE.
+ *
+ *  (Some of these NFSv4 permissions have the same bit values.)
+ */
+#define ACE4_POSIX_MODE_READ (			\
+		ACE4_READ_DATA |		\
+		ACE4_LIST_DIRECTORY)
+#define ACE4_POSIX_MODE_WRITE (			\
+		ACE4_WRITE_DATA |		\
+		ACE4_ADD_FILE |			\
+		ACE4_APPEND_DATA |		\
+		ACE4_ADD_SUBDIRECTORY |		\
+		ACE4_DELETE_CHILD)
+#define ACE4_POSIX_MODE_EXEC ACE4_EXECUTE
+#define ACE4_POSIX_MODE_ALL (			\
+		ACE4_POSIX_MODE_READ |		\
+		ACE4_POSIX_MODE_WRITE |		\
+		ACE4_POSIX_MODE_EXEC)
+/*
+ * These permissions are always allowed
+ * no matter what the acl says.
+ */
+#define ACE4_POSIX_ALWAYS_ALLOWED (	\
+		ACE4_SYNCHRONIZE |	\
+		ACE4_READ_ATTRIBUTES |	\
+		ACE4_READ_ACL)
+/*
+ * The owner is implicitly granted
+ * these permissions under POSIX.
+ */
+#define ACE4_POSIX_OWNER_ALLOWED (		\
+		ACE4_WRITE_ATTRIBUTES |		\
+		ACE4_WRITE_OWNER |		\
+		ACE4_WRITE_ACL)
 /**
  * richacl_get  -  grab another reference to a richacl handle
  */
@@ -241,5 +284,8 @@ extern struct richacl *richacl_alloc(int);
 extern int richace_is_same_identifier(const struct richace *,
 				      const struct richace *);
 extern int richace_set_who(struct richace *, const char *);
+extern int richacl_masks_to_mode(const struct richacl *);
+extern unsigned int richacl_mode_to_mask(mode_t);
+extern unsigned int richacl_want_to_mask(int);
 
 #endif /* __RICHACL_H */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 14/26] richacl: Permission mapping functions
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA
  Cc: aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

We need to map from POSIX permissions to NFSv4 permissions when a
chmod() is done, from NFSv4 permissions to POSIX permissions when an acl
is set (which implicitly sets the file permission bits), and from the
MAY_READ/MAY_WRITE/MAY_EXEC/MAY_APPEND flags to NFSv4 permissions when
doing an access check in a richacl.

Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 fs/richacl_base.c       |  118 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/richacl.h |   46 ++++++++++++++++++
 2 files changed, 164 insertions(+), 0 deletions(-)

diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index 3536626..d55b436 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -69,6 +69,124 @@ richacl_clone(const struct richacl *acl)
 }
 
 /**
+ * richacl_mask_to_mode  -  compute the file permission bits which correspond to @mask
+ * @mask:	%ACE4_* permission mask
+ *
+ * See richacl_masks_to_mode().
+ */
+static int
+richacl_mask_to_mode(unsigned int mask)
+{
+	int mode = 0;
+
+	if (mask & ACE4_POSIX_MODE_READ)
+		mode |= MAY_READ;
+	if (mask & ACE4_POSIX_MODE_WRITE)
+		mode |= MAY_WRITE;
+	if (mask & ACE4_POSIX_MODE_EXEC)
+		mode |= MAY_EXEC;
+
+	return mode;
+}
+
+/**
+ * richacl_masks_to_mode  -  compute the file permission bits from the file masks
+ *
+ * When setting a richacl, we set the file permission bits to indicate maximum
+ * permissions: for example, we set the Write permission when a mask contains
+ * ACE4_APPEND_DATA even if it does not also contain ACE4_WRITE_DATA.
+ *
+ * Permissions which are not in ACE4_POSIX_MODE_READ, ACE4_POSIX_MODE_WRITE, or
+ * ACE4_POSIX_MODE_EXEC cannot be represented in the file permission bits.
+ * Such permissions can still be effective, but not for new files or after a
+ * chmod(), and only if they were set explicitly, for example, by setting a
+ * richacl.
+ */
+int
+richacl_masks_to_mode(const struct richacl *acl)
+{
+	return richacl_mask_to_mode(acl->a_owner_mask) << 6 |
+	       richacl_mask_to_mode(acl->a_group_mask) << 3 |
+	       richacl_mask_to_mode(acl->a_other_mask);
+}
+EXPORT_SYMBOL_GPL(richacl_masks_to_mode);
+
+/**
+ * richacl_mode_to_mask  - compute a file mask from the lowest three mode bits
+ *
+ * When the file permission bits of a file are set with chmod(), this specifies
+ * the maximum permissions that processes will get.  All permissions beyond
+ * that will be removed from the file masks, and become ineffective.
+ *
+ * We also add in the permissions which are always allowed no matter what the
+ * acl says.
+ */
+unsigned int
+richacl_mode_to_mask(mode_t mode)
+{
+	unsigned int mask = ACE4_POSIX_ALWAYS_ALLOWED;
+
+	if (mode & MAY_READ)
+		mask |= ACE4_POSIX_MODE_READ;
+	if (mode & MAY_WRITE)
+		mask |= ACE4_POSIX_MODE_WRITE;
+	if (mode & MAY_EXEC)
+		mask |= ACE4_POSIX_MODE_EXEC;
+
+	return mask;
+}
+
+/**
+ * richacl_want_to_mask  - convert the iop->permission want argument to a mask
+ * @want:	@want argument of the permission inode operation
+ *
+ * When checking for append, @want is (MAY_WRITE | MAY_APPEND).
+ *
+ * Richacls use the iop->may_create and iop->may_delete hooks which are
+ * used for checking if creating and deleting files is allowed.  These hooks do
+ * not use richacl_want_to_mask(), so we do not have to deal with mapping
+ * MAY_WRITE to ACE4_ADD_FILE, ACE4_ADD_SUBDIRECTORY, and ACE4_DELETE_CHILD
+ * here.
+ */
+unsigned int
+richacl_want_to_mask(int want)
+{
+	unsigned int mask = 0;
+
+	if (want & MAY_READ)
+		mask |= ACE4_READ_DATA;
+	if (want & (MAY_APPEND |
+		    MAY_CREATE_FILE | MAY_CREATE_DIR |
+		    MAY_DELETE_CHILD | MAY_DELETE_SELF |
+		    MAY_TAKE_OWNERSHIP | MAY_CHMOD | MAY_SET_TIMES)) {
+		if (want & MAY_APPEND)
+			mask |= ACE4_APPEND_DATA;
+		else if (want & MAY_DELETE_SELF)
+			mask |= ACE4_DELETE;
+		else if (want & MAY_TAKE_OWNERSHIP)
+			mask |= ACE4_WRITE_OWNER;
+		else if (want & MAY_CHMOD)
+			mask |= ACE4_WRITE_ACL;
+		else if (want & MAY_SET_TIMES)
+			mask |= ACE4_WRITE_ATTRIBUTES;
+		else {
+			if (want & MAY_CREATE_FILE)
+				mask |= ACE4_ADD_FILE;
+			if (want & MAY_CREATE_DIR)
+				mask |= ACE4_ADD_SUBDIRECTORY;
+			if (want & MAY_DELETE_CHILD)
+				mask |= ACE4_DELETE_CHILD;
+		}
+	} else if (want & MAY_WRITE)
+		mask |= ACE4_WRITE_DATA;
+	if (want & MAY_EXEC)
+		mask |= ACE4_EXECUTE;
+
+	return mask;
+}
+EXPORT_SYMBOL_GPL(richacl_want_to_mask);
+
+/**
  * richace_is_same_identifier  -  are both identifiers the same?
  */
 int
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index 745cfc1..7433ba3 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -117,6 +117,49 @@ struct richacl {
 	ACE4_WRITE_OWNER |				\
 	ACE4_SYNCHRONIZE)
 
+/*
+ * The POSIX permissions are supersets of the following NFSv4 permissions:
+ *
+ *  - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type
+ *    of the file system object.
+ *
+ *  - MAY_WRITE maps to WRITE_DATA or ACE4_APPEND_DATA for files, and to
+ *    ADD_FILE, ACE4_ADD_SUBDIRECTORY, or ACE4_DELETE_CHILD for directories.
+ *
+ *  - MAY_EXECUTE maps to ACE4_EXECUTE.
+ *
+ *  (Some of these NFSv4 permissions have the same bit values.)
+ */
+#define ACE4_POSIX_MODE_READ (			\
+		ACE4_READ_DATA |		\
+		ACE4_LIST_DIRECTORY)
+#define ACE4_POSIX_MODE_WRITE (			\
+		ACE4_WRITE_DATA |		\
+		ACE4_ADD_FILE |			\
+		ACE4_APPEND_DATA |		\
+		ACE4_ADD_SUBDIRECTORY |		\
+		ACE4_DELETE_CHILD)
+#define ACE4_POSIX_MODE_EXEC ACE4_EXECUTE
+#define ACE4_POSIX_MODE_ALL (			\
+		ACE4_POSIX_MODE_READ |		\
+		ACE4_POSIX_MODE_WRITE |		\
+		ACE4_POSIX_MODE_EXEC)
+/*
+ * These permissions are always allowed
+ * no matter what the acl says.
+ */
+#define ACE4_POSIX_ALWAYS_ALLOWED (	\
+		ACE4_SYNCHRONIZE |	\
+		ACE4_READ_ATTRIBUTES |	\
+		ACE4_READ_ACL)
+/*
+ * The owner is implicitly granted
+ * these permissions under POSIX.
+ */
+#define ACE4_POSIX_OWNER_ALLOWED (		\
+		ACE4_WRITE_ATTRIBUTES |		\
+		ACE4_WRITE_OWNER |		\
+		ACE4_WRITE_ACL)
 /**
  * richacl_get  -  grab another reference to a richacl handle
  */
@@ -241,5 +284,8 @@ extern struct richacl *richacl_alloc(int);
 extern int richace_is_same_identifier(const struct richace *,
 				      const struct richace *);
 extern int richace_set_who(struct richace *, const char *);
+extern int richacl_masks_to_mode(const struct richacl *);
+extern unsigned int richacl_mode_to_mask(mode_t);
+extern unsigned int richacl_want_to_mask(int);
 
 #endif /* __RICHACL_H */
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 15/26] richacl: Compute maximum file masks from an acl
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Compute upper bound owner, group, and other file masks with as few
permissions as possible without denying any permissions that the NFSv4
acl in a richacl grants.

This algorithm is used when a file inherits an acl at create time and
when an acl is set via a mechanism that does not specify file modes
(such as via nfsd).  When user-space sets an acl, the file masks are
passed in as part of the xattr.

When setting a richacl, the file masks determine what the file
permission bits will be set to; see richacl_masks_to_mode().

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/richacl_base.c       |  128 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/richacl.h |    1 +
 2 files changed, 129 insertions(+), 0 deletions(-)

diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index d55b436..84a5698 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -225,3 +225,131 @@ richace_set_who(struct richace *ace, const char *who)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(richace_set_who);
+
+/**
+ * richacl_allowed_to_who  -  mask flags allowed to a specific who value
+ *
+ * Computes the mask values allowed to a specific who value, taking
+ * EVERYONE@ entries into account.
+ */
+static unsigned int richacl_allowed_to_who(struct richacl *acl,
+					   struct richace *who)
+{
+	struct richace *ace;
+	unsigned int allowed = 0;
+
+	richacl_for_each_entry_reverse(ace, acl) {
+		if (richace_is_inherit_only(ace))
+			continue;
+		if (richace_is_same_identifier(ace, who) ||
+		    richace_is_everyone(ace)) {
+			if (richace_is_allow(ace))
+				allowed |= ace->e_mask;
+			else if (richace_is_deny(ace))
+				allowed &= ~ace->e_mask;
+		}
+	}
+	return allowed;
+}
+
+/**
+ * richacl_group_class_allowed  -  maximum permissions the group class is allowed
+ *
+ * See richacl_compute_max_masks().
+ */
+static unsigned int richacl_group_class_allowed(struct richacl *acl)
+{
+	struct richace *ace;
+	unsigned int everyone_allowed = 0, group_class_allowed = 0;
+	int had_group_ace = 0;
+
+	richacl_for_each_entry_reverse(ace, acl) {
+		if (richace_is_inherit_only(ace) ||
+		    richace_is_owner(ace))
+			continue;
+
+		if (richace_is_everyone(ace)) {
+			if (richace_is_allow(ace))
+				everyone_allowed |= ace->e_mask;
+			else if (richace_is_deny(ace))
+				everyone_allowed &= ~ace->e_mask;
+		} else {
+			group_class_allowed |=
+				richacl_allowed_to_who(acl, ace);
+
+			if (richace_is_group(ace))
+				had_group_ace = 1;
+		}
+	}
+	if (!had_group_ace)
+		group_class_allowed |= everyone_allowed;
+	return group_class_allowed;
+}
+
+/**
+ * richacl_compute_max_masks  -  compute upper bound masks
+ *
+ * Computes upper bound owner, group, and other masks so that none of
+ * the mask flags allowed by the acl are disabled (for any choice of the
+ * file owner or group membership).
+ */
+void richacl_compute_max_masks(struct richacl *acl)
+{
+	unsigned int gmask = ~0;
+	struct richace *ace;
+
+	/*
+	 * @gmask contains all permissions which the group class is ever
+	 * allowed.  We use it to avoid adding permissions to the group mask
+	 * from everyone@ allow aces which the group class is always denied
+	 * through other aces.  For example, the following acl would otherwise
+	 * result in a group mask or rw:
+	 *
+	 *	group@:w::deny
+	 *	everyone@:rw::allow
+	 *
+	 * Avoid computing @gmask for acls which do not include any group class
+	 * deny aces: in such acls, the group class is never denied any
+	 * permissions from everyone@ allow aces.
+	 */
+
+restart:
+	acl->a_owner_mask = 0;
+	acl->a_group_mask = 0;
+	acl->a_other_mask = 0;
+
+	richacl_for_each_entry_reverse(ace, acl) {
+		if (richace_is_inherit_only(ace))
+			continue;
+
+		if (richace_is_owner(ace)) {
+			if (richace_is_allow(ace))
+				acl->a_owner_mask |= ace->e_mask;
+			else if (richace_is_deny(ace))
+				acl->a_owner_mask &= ~ace->e_mask;
+		} else if (richace_is_everyone(ace)) {
+			if (richace_is_allow(ace)) {
+				acl->a_owner_mask |= ace->e_mask;
+				acl->a_group_mask |= ace->e_mask & gmask;
+				acl->a_other_mask |= ace->e_mask;
+			} else if (richace_is_deny(ace)) {
+				acl->a_owner_mask &= ~ace->e_mask;
+				acl->a_group_mask &= ~ace->e_mask;
+				acl->a_other_mask &= ~ace->e_mask;
+			}
+		} else {
+			if (richace_is_allow(ace)) {
+				acl->a_owner_mask |= ace->e_mask & gmask;
+				acl->a_group_mask |= ace->e_mask & gmask;
+			} else if (richace_is_deny(ace) && gmask == ~0) {
+				gmask = richacl_group_class_allowed(acl);
+				if (likely(gmask != ~0))
+					/* should always be true */
+					goto restart;
+			}
+		}
+	}
+
+	acl->a_flags &= ~ACL4_MASKED;
+}
+EXPORT_SYMBOL_GPL(richacl_compute_max_masks);
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index 7433ba3..102a58c 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -287,5 +287,6 @@ extern int richace_set_who(struct richace *, const char *);
 extern int richacl_masks_to_mode(const struct richacl *);
 extern unsigned int richacl_mode_to_mask(mode_t);
 extern unsigned int richacl_want_to_mask(int);
+extern void richacl_compute_max_masks(struct richacl *);
 
 #endif /* __RICHACL_H */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 15/26] richacl: Compute maximum file masks from an acl
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA
  Cc: aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Compute upper bound owner, group, and other file masks with as few
permissions as possible without denying any permissions that the NFSv4
acl in a richacl grants.

This algorithm is used when a file inherits an acl at create time and
when an acl is set via a mechanism that does not specify file modes
(such as via nfsd).  When user-space sets an acl, the file masks are
passed in as part of the xattr.

When setting a richacl, the file masks determine what the file
permission bits will be set to; see richacl_masks_to_mode().

Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 fs/richacl_base.c       |  128 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/richacl.h |    1 +
 2 files changed, 129 insertions(+), 0 deletions(-)

diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index d55b436..84a5698 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -225,3 +225,131 @@ richace_set_who(struct richace *ace, const char *who)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(richace_set_who);
+
+/**
+ * richacl_allowed_to_who  -  mask flags allowed to a specific who value
+ *
+ * Computes the mask values allowed to a specific who value, taking
+ * EVERYONE@ entries into account.
+ */
+static unsigned int richacl_allowed_to_who(struct richacl *acl,
+					   struct richace *who)
+{
+	struct richace *ace;
+	unsigned int allowed = 0;
+
+	richacl_for_each_entry_reverse(ace, acl) {
+		if (richace_is_inherit_only(ace))
+			continue;
+		if (richace_is_same_identifier(ace, who) ||
+		    richace_is_everyone(ace)) {
+			if (richace_is_allow(ace))
+				allowed |= ace->e_mask;
+			else if (richace_is_deny(ace))
+				allowed &= ~ace->e_mask;
+		}
+	}
+	return allowed;
+}
+
+/**
+ * richacl_group_class_allowed  -  maximum permissions the group class is allowed
+ *
+ * See richacl_compute_max_masks().
+ */
+static unsigned int richacl_group_class_allowed(struct richacl *acl)
+{
+	struct richace *ace;
+	unsigned int everyone_allowed = 0, group_class_allowed = 0;
+	int had_group_ace = 0;
+
+	richacl_for_each_entry_reverse(ace, acl) {
+		if (richace_is_inherit_only(ace) ||
+		    richace_is_owner(ace))
+			continue;
+
+		if (richace_is_everyone(ace)) {
+			if (richace_is_allow(ace))
+				everyone_allowed |= ace->e_mask;
+			else if (richace_is_deny(ace))
+				everyone_allowed &= ~ace->e_mask;
+		} else {
+			group_class_allowed |=
+				richacl_allowed_to_who(acl, ace);
+
+			if (richace_is_group(ace))
+				had_group_ace = 1;
+		}
+	}
+	if (!had_group_ace)
+		group_class_allowed |= everyone_allowed;
+	return group_class_allowed;
+}
+
+/**
+ * richacl_compute_max_masks  -  compute upper bound masks
+ *
+ * Computes upper bound owner, group, and other masks so that none of
+ * the mask flags allowed by the acl are disabled (for any choice of the
+ * file owner or group membership).
+ */
+void richacl_compute_max_masks(struct richacl *acl)
+{
+	unsigned int gmask = ~0;
+	struct richace *ace;
+
+	/*
+	 * @gmask contains all permissions which the group class is ever
+	 * allowed.  We use it to avoid adding permissions to the group mask
+	 * from everyone@ allow aces which the group class is always denied
+	 * through other aces.  For example, the following acl would otherwise
+	 * result in a group mask or rw:
+	 *
+	 *	group@:w::deny
+	 *	everyone@:rw::allow
+	 *
+	 * Avoid computing @gmask for acls which do not include any group class
+	 * deny aces: in such acls, the group class is never denied any
+	 * permissions from everyone@ allow aces.
+	 */
+
+restart:
+	acl->a_owner_mask = 0;
+	acl->a_group_mask = 0;
+	acl->a_other_mask = 0;
+
+	richacl_for_each_entry_reverse(ace, acl) {
+		if (richace_is_inherit_only(ace))
+			continue;
+
+		if (richace_is_owner(ace)) {
+			if (richace_is_allow(ace))
+				acl->a_owner_mask |= ace->e_mask;
+			else if (richace_is_deny(ace))
+				acl->a_owner_mask &= ~ace->e_mask;
+		} else if (richace_is_everyone(ace)) {
+			if (richace_is_allow(ace)) {
+				acl->a_owner_mask |= ace->e_mask;
+				acl->a_group_mask |= ace->e_mask & gmask;
+				acl->a_other_mask |= ace->e_mask;
+			} else if (richace_is_deny(ace)) {
+				acl->a_owner_mask &= ~ace->e_mask;
+				acl->a_group_mask &= ~ace->e_mask;
+				acl->a_other_mask &= ~ace->e_mask;
+			}
+		} else {
+			if (richace_is_allow(ace)) {
+				acl->a_owner_mask |= ace->e_mask & gmask;
+				acl->a_group_mask |= ace->e_mask & gmask;
+			} else if (richace_is_deny(ace) && gmask == ~0) {
+				gmask = richacl_group_class_allowed(acl);
+				if (likely(gmask != ~0))
+					/* should always be true */
+					goto restart;
+			}
+		}
+	}
+
+	acl->a_flags &= ~ACL4_MASKED;
+}
+EXPORT_SYMBOL_GPL(richacl_compute_max_masks);
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index 7433ba3..102a58c 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -287,5 +287,6 @@ extern int richace_set_who(struct richace *, const char *);
 extern int richacl_masks_to_mode(const struct richacl *);
 extern unsigned int richacl_mode_to_mask(mode_t);
 extern unsigned int richacl_want_to_mask(int);
+extern void richacl_compute_max_masks(struct richacl *);
 
 #endif /* __RICHACL_H */
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 16/26] richacl: Update the file masks in chmod()
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (14 preceding siblings ...)
  2011-09-05 17:25   ` Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25 ` [PATCH -V6 17/26] richacl: Permission check algorithm Aneesh Kumar K.V
                   ` (21 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Doing a chmod() sets the file mode, which includes the file permission
bits.  When a file has a richacl, the permissions that the richacl
grants need to be limited to what the new file permission bits allow.

This is done by setting the file masks in the richacl to what the file
permission bits map to.  The richacl access check algorithm takes the
file masks into account, which ensures that the richacl cannot grant too
many permissions.

It is possible to explicitly add permissions to the file masks which go
beyond what the file permission bits can grant (like the ACE4_WRITE_ACL
permission).  The POSIX.1 standard calls this an alternate file access
control mechanism.  A subsequent chmod() would ensure that those
permissions are disabled again.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/richacl_base.c       |   40 ++++++++++++++++++++++++++++++++++++++++
 include/linux/richacl.h |    1 +
 2 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index 84a5698..60a65d7 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -353,3 +353,43 @@ restart:
 	acl->a_flags &= ~ACL4_MASKED;
 }
 EXPORT_SYMBOL_GPL(richacl_compute_max_masks);
+
+/**
+ * richacl_chmod  -  update the file masks to reflect the new mode
+ * @mode:	new file permission bits
+ *
+ * Return a copy of @acl where the file masks have been replaced by the file
+ * masks corresponding to the file permission bits in @mode, or returns @acl
+ * itself if the file masks are already up to date.  Takes over a reference
+ * to @acl.
+ */
+struct richacl *
+richacl_chmod(struct richacl *acl, mode_t mode)
+{
+	unsigned int owner_mask, group_mask, other_mask;
+	struct richacl *clone;
+
+	owner_mask = richacl_mode_to_mask(mode >> 6) |
+		     ACE4_POSIX_OWNER_ALLOWED;
+	group_mask = richacl_mode_to_mask(mode >> 3);
+	other_mask = richacl_mode_to_mask(mode);
+
+	if (acl->a_owner_mask == owner_mask &&
+	    acl->a_group_mask == group_mask &&
+	    acl->a_other_mask == other_mask &&
+	    (acl->a_flags & ACL4_MASKED))
+		return acl;
+
+	clone = richacl_clone(acl);
+	richacl_put(acl);
+	if (!clone)
+		return ERR_PTR(-ENOMEM);
+
+	clone->a_flags |= ACL4_MASKED;
+	clone->a_owner_mask = owner_mask;
+	clone->a_group_mask = group_mask;
+	clone->a_other_mask = other_mask;
+
+	return clone;
+}
+EXPORT_SYMBOL_GPL(richacl_chmod);
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index 102a58c..6dd8eb2 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -288,5 +288,6 @@ extern int richacl_masks_to_mode(const struct richacl *);
 extern unsigned int richacl_mode_to_mask(mode_t);
 extern unsigned int richacl_want_to_mask(int);
 extern void richacl_compute_max_masks(struct richacl *);
+extern struct richacl *richacl_chmod(struct richacl *, mode_t);
 
 #endif /* __RICHACL_H */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 17/26] richacl: Permission check algorithm
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (15 preceding siblings ...)
  2011-09-05 17:25 ` [PATCH -V6 16/26] richacl: Update the file masks in chmod() Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-07 21:50     ` J. Bruce Fields
  2011-09-05 17:25 ` [PATCH -V6 18/26] richacl: Create-time inheritance Aneesh Kumar K.V
                   ` (20 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

As in the standard POSIX file permission model, each process is the
owner, group, or other file class.  A process is

  - in the owner file class if it owns the file,
  - in the group file class if it is in the file's owning group or it
    matches any of the user or group entries, and
  - in the other file class otherwise.

Each file class is associated with a file mask.

A richacl grants a requested access if the NFSv4 acl in the richacl
grants the requested permissions (according to the NFSv4 permission
check algorithm) and the file mask that applies to the process includes
the requested permissions.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/richacl_base.c       |   99 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/richacl.h |    2 +
 2 files changed, 101 insertions(+), 0 deletions(-)

diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index 60a65d7..1f885ad 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -393,3 +393,102 @@ richacl_chmod(struct richacl *acl, mode_t mode)
 	return clone;
 }
 EXPORT_SYMBOL_GPL(richacl_chmod);
+
+/**
+ * richacl_permission  -  richacl permission check algorithm
+ * @inode:	inode to check
+ * @acl:	rich acl of the inode
+ * @mask:	requested access (ACE4_* bitmask)
+ *
+ * Checks if the current process is granted @mask flags in @acl.
+ */
+int
+richacl_permission(struct inode *inode, const struct richacl *acl,
+		   unsigned int mask)
+{
+	const struct richace *ace;
+	unsigned int requested = mask, denied = 0;
+	int in_owning_group = in_group_p(inode->i_gid);
+	int in_owner_or_group_class = in_owning_group;
+
+	/*
+	 * We don't need to know which class the process is in when the acl is
+	 * not masked.
+	 */
+	if (!(acl->a_flags & ACL4_MASKED))
+		in_owner_or_group_class = 1;
+
+	/*
+	 * A process is
+	 *   - in the owner file class if it owns the file,
+	 *   - in the group file class if it is in the file's owning group or
+	 *     it matches any of the user or group entries, and
+	 *   - in the other file class otherwise.
+	 */
+
+	/*
+	 * Check if the acl grants the requested access and determine which
+	 * file class the process is in.
+	 */
+	richacl_for_each_entry(ace, acl) {
+		unsigned int ace_mask = ace->e_mask;
+
+		if (richace_is_inherit_only(ace))
+			continue;
+		if (richace_is_owner(ace)) {
+			if (current_fsuid() != inode->i_uid)
+				continue;
+			goto is_owner;
+		} else if (richace_is_group(ace)) {
+			if (!in_owning_group)
+				continue;
+		} else if (richace_is_unix_id(ace)) {
+			if (ace->e_flags & ACE4_IDENTIFIER_GROUP) {
+				if (!in_group_p(ace->u.e_id))
+					continue;
+			} else {
+				if (current_fsuid() != ace->u.e_id)
+					continue;
+			}
+		} else
+			goto is_everyone;
+
+is_owner:
+		/* The process is in the owner or group file class. */
+		in_owner_or_group_class = 1;
+
+is_everyone:
+		/* Check which mask flags the ACE allows or denies. */
+		if (richace_is_deny(ace))
+			denied |= ace_mask & mask;
+		mask &= ~ace_mask;
+
+		/*
+		 * Keep going until we know which file class
+		 * the process is in.
+		 */
+		if (!mask && in_owner_or_group_class)
+			break;
+	}
+	denied |= mask;
+
+	if (acl->a_flags & ACL4_MASKED) {
+		unsigned int file_mask;
+
+		/*
+		 * The file class a process is in determines which file mask
+		 * applies.  Check if that file mask also grants the requested
+		 * access.
+		 */
+		if (current_fsuid() == inode->i_uid)
+			file_mask = acl->a_owner_mask;
+		else if (in_owner_or_group_class)
+			file_mask = acl->a_group_mask;
+		else
+			file_mask = acl->a_other_mask;
+		denied |= requested & ~file_mask;
+	}
+
+	return denied ? -EACCES : 0;
+}
+EXPORT_SYMBOL_GPL(richacl_permission);
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index 6dd8eb2..f46e797 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -289,5 +289,7 @@ extern unsigned int richacl_mode_to_mask(mode_t);
 extern unsigned int richacl_want_to_mask(int);
 extern void richacl_compute_max_masks(struct richacl *);
 extern struct richacl *richacl_chmod(struct richacl *, mode_t);
+extern int richacl_permission(struct inode *, const struct richacl *,
+			      unsigned int);
 
 #endif /* __RICHACL_H */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 18/26] richacl: Create-time inheritance
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (16 preceding siblings ...)
  2011-09-05 17:25 ` [PATCH -V6 17/26] richacl: Permission check algorithm Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25   ` Aneesh Kumar K.V
                   ` (19 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

When a new file is created, it can inherit an acl from its parent
directory; this is similar to how default acls work in POSIX (draft)
ACLs.

As with POSIX ACLs, if a file inherits an acl from its parent directory,
the intersection between the create mode and the permissions granted by
the inherited acl determines the file masks and file permission bits,
and the umask is ignored.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/Makefile             |    2 +-
 fs/richacl_base.c       |   69 +++++++++++++++++++++++++++++++++++++++++++++++
 fs/richacl_inode.c      |   59 ++++++++++++++++++++++++++++++++++++++++
 include/linux/richacl.h |    4 +++
 4 files changed, 133 insertions(+), 1 deletions(-)
 create mode 100644 fs/richacl_inode.c

diff --git a/fs/Makefile b/fs/Makefile
index 7612168..1ecf9f2 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -49,7 +49,7 @@ obj-$(CONFIG_GENERIC_ACL)	+= generic_acl.o
 
 obj-$(CONFIG_FHANDLE)		+= fhandle.o
 obj-$(CONFIG_FS_RICHACL)	+= richacl.o
-richacl-y			:= richacl_base.o
+richacl-y			:= richacl_base.o richacl_inode.o
 
 obj-y				+= quota/
 
diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index 1f885ad..b4af12c 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -492,3 +492,72 @@ is_everyone:
 	return denied ? -EACCES : 0;
 }
 EXPORT_SYMBOL_GPL(richacl_permission);
+
+/**
+ * richacl_inherit  -  compute the inherited acl of a new file
+ * @dir_acl:	acl of the containing direcory
+ * @isdir:	inherit by a directory or non-directory?
+ *
+ * A directory can have acl entries which files and/or directories created
+ * inside the directory will inherit.  This function computes the acl for such
+ * a new file.  If there is no inheritable acl, it will return %NULL.
+ */
+struct richacl *
+richacl_inherit(const struct richacl *dir_acl, int isdir)
+{
+	const struct richace *dir_ace;
+	struct richacl *acl = NULL;
+	struct richace *ace;
+	int count = 0;
+
+	if (isdir) {
+		richacl_for_each_entry(dir_ace, dir_acl) {
+			if (!richace_is_inheritable(dir_ace))
+				continue;
+			count++;
+		}
+		if (!count)
+			return NULL;
+		acl = richacl_alloc(count);
+		if (!acl)
+			return ERR_PTR(-ENOMEM);
+		ace = acl->a_entries;
+		richacl_for_each_entry(dir_ace, dir_acl) {
+			if (!richace_is_inheritable(dir_ace))
+				continue;
+			memcpy(ace, dir_ace, sizeof(struct richace));
+			if (dir_ace->e_flags & ACE4_NO_PROPAGATE_INHERIT_ACE)
+				richace_clear_inheritance_flags(ace);
+			if ((dir_ace->e_flags & ACE4_FILE_INHERIT_ACE) &&
+			    !(dir_ace->e_flags & ACE4_DIRECTORY_INHERIT_ACE))
+				ace->e_flags |= ACE4_INHERIT_ONLY_ACE;
+			ace++;
+		}
+	} else {
+		richacl_for_each_entry(dir_ace, dir_acl) {
+			if (!(dir_ace->e_flags & ACE4_FILE_INHERIT_ACE))
+				continue;
+			count++;
+		}
+		if (!count)
+			return NULL;
+		acl = richacl_alloc(count);
+		if (!acl)
+			return ERR_PTR(-ENOMEM);
+		ace = acl->a_entries;
+		richacl_for_each_entry(dir_ace, dir_acl) {
+			if (!(dir_ace->e_flags & ACE4_FILE_INHERIT_ACE))
+				continue;
+			memcpy(ace, dir_ace, sizeof(struct richace));
+			richace_clear_inheritance_flags(ace);
+			/*
+			 * ACE4_DELETE_CHILD is meaningless for
+			 * non-directories, so clear it.
+			 */
+			ace->e_mask &= ~ACE4_DELETE_CHILD;
+			ace++;
+		}
+	}
+
+	return acl;
+}
diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c
new file mode 100644
index 0000000..a8d2beb
--- /dev/null
+++ b/fs/richacl_inode.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010  Novell, Inc.
+ * Written by Andreas Gruenbacher <agruen@kernel.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/richacl.h>
+
+/**
+ * richacl_inherit_inode  -  compute inherited acl and file mode
+ * @dir_acl:	acl of the containing direcory
+ * @inode:	inode of the new file (create mode in i_mode)
+ *
+ * The file permission bits in inode->i_mode must be set to the create mode.
+ * If there is an inheritable acl, the maximum permissions that the acl grants
+ * will be computed and permissions not granted by the acl will be removed from
+ * inode->i_mode.  If there is no inheritable acl, the umask will be applied
+ * instead.
+ */
+struct richacl *
+richacl_inherit_inode(const struct richacl *dir_acl, struct inode *inode)
+{
+	struct richacl *acl;
+	mode_t mask;
+
+	acl = richacl_inherit(dir_acl, S_ISDIR(inode->i_mode));
+	if (acl) {
+
+		richacl_compute_max_masks(acl);
+
+		/*
+		 * Ensure that the acl will not grant any permissions beyond
+		 * the create mode.
+		 */
+		acl->a_flags |= ACL4_MASKED;
+		acl->a_owner_mask &= richacl_mode_to_mask(inode->i_mode >> 6) |
+				     ACE4_POSIX_OWNER_ALLOWED;
+		acl->a_group_mask &= richacl_mode_to_mask(inode->i_mode >> 3);
+		acl->a_other_mask &= richacl_mode_to_mask(inode->i_mode);
+		mask = ~S_IRWXUGO | richacl_masks_to_mode(acl);
+	} else
+		mask = ~current_umask();
+
+	inode->i_mode &= mask;
+	return acl;
+}
+EXPORT_SYMBOL_GPL(richacl_inherit_inode);
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index f46e797..78c35f6 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -291,5 +291,9 @@ extern void richacl_compute_max_masks(struct richacl *);
 extern struct richacl *richacl_chmod(struct richacl *, mode_t);
 extern int richacl_permission(struct inode *, const struct richacl *,
 			      unsigned int);
+extern struct richacl *richacl_inherit(const struct richacl *, int);
 
+/* richacl_inode.c */
+extern struct richacl *richacl_inherit_inode(const struct richacl *,
+					     struct inode *);
 #endif /* __RICHACL_H */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 19/26] richacl: Check if an acl is equivalent to a file mode
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

This function is used to avoid storing richacls on disk if the acl can
be computed from the file permission bits.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/richacl_base.c       |   54 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/richacl.h |    1 +
 2 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index b4af12c..9d61c34 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -561,3 +561,57 @@ richacl_inherit(const struct richacl *dir_acl, int isdir)
 
 	return acl;
 }
+
+/**
+ * richacl_equiv_mode  -  check if @acl is equivalent to file permission bits
+ * @mode_p:	the file mode (including the file type)
+ *
+ * If @acl can be fully represented by file permission bits, this function
+ * returns 0, and the file permission bits in @mode_p are set to the equivalent
+ * of @acl.
+ *
+ * This function is used to avoid storing richacls on disk if the acl can be
+ * computed from the file permission bits.  It allows user-space to make sure
+ * that a file has no explicit richacl set.
+ */
+int
+richacl_equiv_mode(const struct richacl *acl, mode_t *mode_p)
+{
+	const struct richace *ace = acl->a_entries;
+	unsigned int x;
+	mode_t mode;
+
+	if (acl->a_count != 1 ||
+	    acl->a_flags != ACL4_MASKED ||
+	    !richace_is_everyone(ace) ||
+	    !richace_is_allow(ace) ||
+	    ace->e_flags & ~ACE4_SPECIAL_WHO)
+		return -1;
+
+	/*
+	 * Figure out the permissions we care about: ACE4_DELETE_CHILD is
+	 * meaningless for non-directories, so we ignore it.
+	 */
+	x = ~ACE4_POSIX_ALWAYS_ALLOWED;
+	if (!S_ISDIR(*mode_p))
+		x &= ~ACE4_DELETE_CHILD;
+
+	mode = richacl_masks_to_mode(acl);
+	if ((acl->a_group_mask & x) != (richacl_mode_to_mask(mode >> 3) & x) ||
+	    (acl->a_other_mask & x) != (richacl_mode_to_mask(mode) & x))
+		return -1;
+
+	/*
+	 * Ignore permissions which the owner is always allowed.
+	 */
+	x &= ~ACE4_POSIX_OWNER_ALLOWED;
+	if ((acl->a_owner_mask & x) != (richacl_mode_to_mask(mode >> 6) & x))
+		return -1;
+
+	if ((ace->e_mask & x) != (ACE4_POSIX_MODE_ALL & x))
+		return -1;
+
+	*mode_p = (*mode_p & ~S_IRWXUGO) | mode;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(richacl_equiv_mode);
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index 78c35f6..d18c4a6 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -292,6 +292,7 @@ extern struct richacl *richacl_chmod(struct richacl *, mode_t);
 extern int richacl_permission(struct inode *, const struct richacl *,
 			      unsigned int);
 extern struct richacl *richacl_inherit(const struct richacl *, int);
+extern int richacl_equiv_mode(const struct richacl *, mode_t *);
 
 /* richacl_inode.c */
 extern struct richacl *richacl_inherit_inode(const struct richacl *,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 19/26] richacl: Check if an acl is equivalent to a file mode
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA
  Cc: aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

This function is used to avoid storing richacls on disk if the acl can
be computed from the file permission bits.

Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 fs/richacl_base.c       |   54 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/richacl.h |    1 +
 2 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index b4af12c..9d61c34 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -561,3 +561,57 @@ richacl_inherit(const struct richacl *dir_acl, int isdir)
 
 	return acl;
 }
+
+/**
+ * richacl_equiv_mode  -  check if @acl is equivalent to file permission bits
+ * @mode_p:	the file mode (including the file type)
+ *
+ * If @acl can be fully represented by file permission bits, this function
+ * returns 0, and the file permission bits in @mode_p are set to the equivalent
+ * of @acl.
+ *
+ * This function is used to avoid storing richacls on disk if the acl can be
+ * computed from the file permission bits.  It allows user-space to make sure
+ * that a file has no explicit richacl set.
+ */
+int
+richacl_equiv_mode(const struct richacl *acl, mode_t *mode_p)
+{
+	const struct richace *ace = acl->a_entries;
+	unsigned int x;
+	mode_t mode;
+
+	if (acl->a_count != 1 ||
+	    acl->a_flags != ACL4_MASKED ||
+	    !richace_is_everyone(ace) ||
+	    !richace_is_allow(ace) ||
+	    ace->e_flags & ~ACE4_SPECIAL_WHO)
+		return -1;
+
+	/*
+	 * Figure out the permissions we care about: ACE4_DELETE_CHILD is
+	 * meaningless for non-directories, so we ignore it.
+	 */
+	x = ~ACE4_POSIX_ALWAYS_ALLOWED;
+	if (!S_ISDIR(*mode_p))
+		x &= ~ACE4_DELETE_CHILD;
+
+	mode = richacl_masks_to_mode(acl);
+	if ((acl->a_group_mask & x) != (richacl_mode_to_mask(mode >> 3) & x) ||
+	    (acl->a_other_mask & x) != (richacl_mode_to_mask(mode) & x))
+		return -1;
+
+	/*
+	 * Ignore permissions which the owner is always allowed.
+	 */
+	x &= ~ACE4_POSIX_OWNER_ALLOWED;
+	if ((acl->a_owner_mask & x) != (richacl_mode_to_mask(mode >> 6) & x))
+		return -1;
+
+	if ((ace->e_mask & x) != (ACE4_POSIX_MODE_ALL & x))
+		return -1;
+
+	*mode_p = (*mode_p & ~S_IRWXUGO) | mode;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(richacl_equiv_mode);
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index 78c35f6..d18c4a6 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -292,6 +292,7 @@ extern struct richacl *richacl_chmod(struct richacl *, mode_t);
 extern int richacl_permission(struct inode *, const struct richacl *,
 			      unsigned int);
 extern struct richacl *richacl_inherit(const struct richacl *, int);
+extern int richacl_equiv_mode(const struct richacl *, mode_t *);
 
 /* richacl_inode.c */
 extern struct richacl *richacl_inherit_inode(const struct richacl *,
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 20/26] richacl: Automatic Inheritance
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (18 preceding siblings ...)
  2011-09-05 17:25   ` Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-07 21:56     ` J. Bruce Fields
  2011-09-05 17:25 ` [PATCH -V6 21/26] richacl: xattr mapping functions Aneesh Kumar K.V
                   ` (17 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Automatic Inheritance (AI) allows changes to the acl of a directory to
recursively propagate down to files and directories in the directory.

To implement this, the kernel keeps track of which permissions have been
inherited, and makes sure that permission propagation is turned off when
the file permission bits of a file are changed (upon create or chmod).

The actual permission propagation is implemented in user space.

AI works as follows:

 - When the ACL4_AUTO_INHERIT flag in the acl of a file is cleared, the
   file is not affected by AI.

 - When the ACL4_AUTO_INHERIT flag in the acl of a directory is set and
   a file or subdirectory is created in that directory, files created in
   the directory will have the ACL4_AUTO_INHERIT flag set, and all
   inherited aces will have the ACE4_INHERITED_ACE flag set.  This
   allows user space to distinguish between aces which have been
   inherited, and aces which have been explicitly added.

 - When the ACL4_PROTECTED acl flag in the acl of a file is set, AI will
   not modify the acl of the file.  This does not affect propagation of
   permissions from the file to its children (if the file is a
   directory).

Linux does not have a way of creating files without setting the file
permission bits, so all files created inside a directory with
ACL4_AUTO_INHERIT set will also have the ACL4_PROTECTED flag set.  This
effectively disables AI.

Protocols which support creating files without specifying permissions
can explicitly clear the ACL4_PROTECTED flag after creating a file (and
reset the file masks to "undo" applying the create mode; see
richacl_compute_max_masks()).  This is a workaround; a per-create or
per-process flag indicating to ignore the create mode when AI is in
effect would fix this problem.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/richacl_base.c       |   10 +++++++++-
 fs/richacl_inode.c      |    7 ++++++-
 include/linux/richacl.h |   25 +++++++++++++++++++++++--
 3 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index 9d61c34..2cdc244 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -377,7 +377,8 @@ richacl_chmod(struct richacl *acl, mode_t mode)
 	if (acl->a_owner_mask == owner_mask &&
 	    acl->a_group_mask == group_mask &&
 	    acl->a_other_mask == other_mask &&
-	    (acl->a_flags & ACL4_MASKED))
+	    (acl->a_flags & ACL4_MASKED) &&
+	    (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl)))
 		return acl;
 
 	clone = richacl_clone(acl);
@@ -389,6 +390,8 @@ richacl_chmod(struct richacl *acl, mode_t mode)
 	clone->a_owner_mask = owner_mask;
 	clone->a_group_mask = group_mask;
 	clone->a_other_mask = other_mask;
+	if (richacl_is_auto_inherit(clone))
+		clone->a_flags |= ACL4_PROTECTED;
 
 	return clone;
 }
@@ -558,6 +561,11 @@ richacl_inherit(const struct richacl *dir_acl, int isdir)
 			ace++;
 		}
 	}
+	if (richacl_is_auto_inherit(dir_acl)) {
+		acl->a_flags = ACL4_AUTO_INHERIT;
+		richacl_for_each_entry(ace, acl)
+			ace->e_flags |= ACE4_INHERITED_ACE;
+	}
 
 	return acl;
 }
diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c
index a8d2beb..be6c3eb 100644
--- a/fs/richacl_inode.c
+++ b/fs/richacl_inode.c
@@ -37,9 +37,14 @@ richacl_inherit_inode(const struct richacl *dir_acl, struct inode *inode)
 
 	acl = richacl_inherit(dir_acl, S_ISDIR(inode->i_mode));
 	if (acl) {
+		/*
+		 * We need to set ACL4_PROTECTED because we are
+		 * doing an implicit chmod
+		 */
+		if (richacl_is_auto_inherit(acl))
+			acl->a_flags |= ACL4_PROTECTED;
 
 		richacl_compute_max_masks(acl);
-
 		/*
 		 * Ensure that the acl will not grant any permissions beyond
 		 * the create mode.
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index d18c4a6..ca07209 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -47,10 +47,16 @@ struct richacl {
 	     _ace != _acl->a_entries - 1; \
 	     _ace--)
 
+/* a_flags values */
+#define ACL4_AUTO_INHERIT		0x01
+#define ACL4_PROTECTED			0x02
+/* #define ACL4_DEFAULTED			0x04 */
 /* Flag values defined by rich-acl */
 #define ACL4_MASKED			0x80
 
 #define ACL4_VALID_FLAGS (			\
+		ACL4_AUTO_INHERIT |		\
+		ACL4_PROTECTED |		\
 		ACL4_MASKED)
 
 /* e_type values */
@@ -67,6 +73,7 @@ struct richacl {
 /*#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG	0x0010*/
 /*#define ACE4_FAILED_ACCESS_ACE_FLAG	0x0020*/
 #define ACE4_IDENTIFIER_GROUP		0x0040
+#define ACE4_INHERITED_ACE		0x0080
 /* in-memory representation only */
 #define ACE4_SPECIAL_WHO		0x4000
 
@@ -75,7 +82,8 @@ struct richacl {
 	ACE4_DIRECTORY_INHERIT_ACE |		\
 	ACE4_NO_PROPAGATE_INHERIT_ACE |		\
 	ACE4_INHERIT_ONLY_ACE |			\
-	ACE4_IDENTIFIER_GROUP)
+	ACE4_IDENTIFIER_GROUP |			\
+	ACE4_INHERITED_ACE)
 
 /* e_mask bitflags */
 #define ACE4_READ_DATA			0x00000001
@@ -181,6 +189,18 @@ richacl_put(struct richacl *acl)
 		kfree(acl);
 }
 
+static inline int
+richacl_is_auto_inherit(const struct richacl *acl)
+{
+	return acl->a_flags & ACL4_AUTO_INHERIT;
+}
+
+static inline int
+richacl_is_protected(const struct richacl *acl)
+{
+	return acl->a_flags & ACL4_PROTECTED;
+}
+
 /*
  * Special e_who identifiers: we use these pointer values in comparisons
  * instead of doing a strcmp.
@@ -259,7 +279,8 @@ richace_clear_inheritance_flags(struct richace *ace)
 	ace->e_flags &= ~(ACE4_FILE_INHERIT_ACE |
 			  ACE4_DIRECTORY_INHERIT_ACE |
 			  ACE4_NO_PROPAGATE_INHERIT_ACE |
-			  ACE4_INHERIT_ONLY_ACE);
+			  ACE4_INHERIT_ONLY_ACE |
+			  ACE4_INHERITED_ACE);
 }
 
 /**
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 21/26] richacl: xattr mapping functions
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (19 preceding siblings ...)
  2011-09-05 17:25 ` [PATCH -V6 20/26] richacl: Automatic Inheritance Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25 ` [PATCH -V6 22/26] vfs: Cache richacl in struct inode Aneesh Kumar K.V
                   ` (16 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Map between "system.richacl" xattrs and the in-kernel representation.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/Makefile                   |    2 +-
 fs/richacl_xattr.c            |  156 +++++++++++++++++++++++++++++++++++++++++
 include/linux/richacl_xattr.h |   47 ++++++++++++
 3 files changed, 204 insertions(+), 1 deletions(-)
 create mode 100644 fs/richacl_xattr.c
 create mode 100644 include/linux/richacl_xattr.h

diff --git a/fs/Makefile b/fs/Makefile
index 1ecf9f2..e217c65 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -49,7 +49,7 @@ obj-$(CONFIG_GENERIC_ACL)	+= generic_acl.o
 
 obj-$(CONFIG_FHANDLE)		+= fhandle.o
 obj-$(CONFIG_FS_RICHACL)	+= richacl.o
-richacl-y			:= richacl_base.o richacl_inode.o
+richacl-y			:= richacl_base.o richacl_inode.o richacl_xattr.o
 
 obj-y				+= quota/
 
diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c
new file mode 100644
index 0000000..02a7986
--- /dev/null
+++ b/fs/richacl_xattr.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2006, 2010  Novell, Inc.
+ * Written by Andreas Gruenbacher <agruen@kernel.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/richacl_xattr.h>
+
+MODULE_LICENSE("GPL");
+
+/**
+ * richacl_from_xattr  -  convert a richacl xattr into the in-memory representation
+ */
+struct richacl *
+richacl_from_xattr(const void *value, size_t size)
+{
+	const struct richacl_xattr *xattr_acl = value;
+	const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1);
+	struct richacl *acl;
+	struct richace *ace;
+	int count;
+
+	if (size < sizeof(struct richacl_xattr) ||
+	    xattr_acl->a_version != ACL4_XATTR_VERSION ||
+	    (xattr_acl->a_flags & ~ACL4_VALID_FLAGS))
+		return ERR_PTR(-EINVAL);
+
+	count = le16_to_cpu(xattr_acl->a_count);
+	if (count > ACL4_XATTR_MAX_COUNT)
+		return ERR_PTR(-EINVAL);
+
+	acl = richacl_alloc(count);
+	if (!acl)
+		return ERR_PTR(-ENOMEM);
+
+	acl->a_flags = xattr_acl->a_flags;
+	acl->a_owner_mask = le32_to_cpu(xattr_acl->a_owner_mask);
+	if (acl->a_owner_mask & ~ACE4_VALID_MASK)
+		goto fail_einval;
+	acl->a_group_mask = le32_to_cpu(xattr_acl->a_group_mask);
+	if (acl->a_group_mask & ~ACE4_VALID_MASK)
+		goto fail_einval;
+	acl->a_other_mask = le32_to_cpu(xattr_acl->a_other_mask);
+	if (acl->a_other_mask & ~ACE4_VALID_MASK)
+		goto fail_einval;
+
+	richacl_for_each_entry(ace, acl) {
+		const char *who = (void *)(xattr_ace + 1), *end;
+		ssize_t used = (void *)who - value;
+
+		if (used > size)
+			goto fail_einval;
+		end = memchr(who, 0, size - used);
+		if (!end)
+			goto fail_einval;
+
+		ace->e_type = le16_to_cpu(xattr_ace->e_type);
+		ace->e_flags = le16_to_cpu(xattr_ace->e_flags);
+		ace->e_mask = le32_to_cpu(xattr_ace->e_mask);
+		ace->u.e_id = le32_to_cpu(xattr_ace->e_id);
+
+		if (ace->e_flags & ~ACE4_VALID_FLAGS)
+			goto fail_einval;
+		if (ace->e_type > ACE4_ACCESS_DENIED_ACE_TYPE ||
+		    (ace->e_mask & ~ACE4_VALID_MASK))
+			goto fail_einval;
+
+		if (who == end) {
+			if (ace->u.e_id == -1)
+				goto fail_einval;  /* uid/gid needed */
+		} else if (richace_set_who(ace, who))
+			goto fail_einval;
+
+		xattr_ace = (void *)who + ALIGN(end - who + 1, 4);
+	}
+
+	return acl;
+
+fail_einval:
+	richacl_put(acl);
+	return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(richacl_from_xattr);
+
+/**
+ * richacl_xattr_size  -  compute the size of the xattr representation of @acl
+ */
+size_t
+richacl_xattr_size(const struct richacl *acl)
+{
+	size_t size = sizeof(struct richacl_xattr);
+	const struct richace *ace;
+
+	richacl_for_each_entry(ace, acl) {
+		size += sizeof(struct richace_xattr) +
+			(richace_is_unix_id(ace) ? 4 :
+			 ALIGN(strlen(ace->u.e_who) + 1, 4));
+	}
+	return size;
+}
+EXPORT_SYMBOL_GPL(richacl_xattr_size);
+
+/**
+ * richacl_to_xattr  -  convert @acl into its xattr representation
+ * @acl:	the richacl to convert
+ * @buffer:	buffer of size richacl_xattr_size(@acl) for the result
+ */
+void
+richacl_to_xattr(const struct richacl *acl, void *buffer)
+{
+	struct richacl_xattr *xattr_acl = buffer;
+	struct richace_xattr *xattr_ace;
+	const struct richace *ace;
+
+	xattr_acl->a_version = ACL4_XATTR_VERSION;
+	xattr_acl->a_flags = acl->a_flags;
+	xattr_acl->a_count = cpu_to_le16(acl->a_count);
+
+	xattr_acl->a_owner_mask = cpu_to_le32(acl->a_owner_mask);
+	xattr_acl->a_group_mask = cpu_to_le32(acl->a_group_mask);
+	xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask);
+
+	xattr_ace = (void *)(xattr_acl + 1);
+	richacl_for_each_entry(ace, acl) {
+		xattr_ace->e_type = cpu_to_le16(ace->e_type);
+		xattr_ace->e_flags = cpu_to_le16(ace->e_flags &
+						 ACE4_VALID_FLAGS);
+		xattr_ace->e_mask = cpu_to_le32(ace->e_mask);
+		if (richace_is_unix_id(ace)) {
+			xattr_ace->e_id = cpu_to_le32(ace->u.e_id);
+			memset(xattr_ace->e_who, 0, 4);
+			xattr_ace = (void *)xattr_ace->e_who + 4;
+		} else {
+			int sz = ALIGN(strlen(ace->u.e_who) + 1, 4);
+
+			xattr_ace->e_id = cpu_to_le32(-1);
+			memset(xattr_ace->e_who + sz - 4, 0, 4);
+			strcpy(xattr_ace->e_who, ace->u.e_who);
+			xattr_ace = (void *)xattr_ace->e_who + sz;
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(richacl_to_xattr);
diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h
new file mode 100644
index 0000000..f79ec12
--- /dev/null
+++ b/include/linux/richacl_xattr.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006, 2010  Novell, Inc.
+ * Written by Andreas Gruenbacher <agruen@kernel.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __RICHACL_XATTR_H
+#define __RICHACL_XATTR_H
+
+#include <linux/richacl.h>
+
+#define RICHACL_XATTR "system.richacl"
+
+struct richace_xattr {
+	__le16		e_type;
+	__le16		e_flags;
+	__le32		e_mask;
+	__le32		e_id;
+	char		e_who[0];
+};
+
+struct richacl_xattr {
+	unsigned char	a_version;
+	unsigned char	a_flags;
+	__le16		a_count;
+	__le32		a_owner_mask;
+	__le32		a_group_mask;
+	__le32		a_other_mask;
+};
+
+#define ACL4_XATTR_VERSION	0
+#define ACL4_XATTR_MAX_COUNT	1024
+
+extern struct richacl *richacl_from_xattr(const void *, size_t);
+extern size_t richacl_xattr_size(const struct richacl *acl);
+extern void richacl_to_xattr(const struct richacl *, void *);
+
+#endif /* __RICHACL_XATTR_H */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 22/26] vfs: Cache richacl in struct inode
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (20 preceding siblings ...)
  2011-09-05 17:25 ` [PATCH -V6 21/26] richacl: xattr mapping functions Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25   ` Aneesh Kumar K.V
                   ` (15 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

From: Andreas Gruenbacher <agruen@kernel.org>

Cache richacls in struct inode so that this doesn't have to be done
individually in each filesystem.

Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/inode.c              |   25 +++++++++++++++++----
 include/linux/fs.h      |   12 ++++++++-
 include/linux/richacl.h |   53 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+), 7 deletions(-)

diff --git a/fs/inode.c b/fs/inode.c
index ec79246..1b442cf 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -26,6 +26,7 @@
 #include <linux/ima.h>
 #include <linux/cred.h>
 #include <linux/buffer_head.h> /* for inode_has_buffers */
+#include <linux/richacl.h>
 #include "internal.h"
 
 /*
@@ -192,7 +193,12 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
 	inode->i_private = NULL;
 	inode->i_mapping = mapping;
 #ifdef CONFIG_FS_POSIX_ACL
-	inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
+	if (IS_POSIXACL(inode))
+		inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
+#endif
+#ifdef CONFIG_FS_RICHACL
+	if (IS_RICHACL(inode))
+		inode->i_richacl = ACL_NOT_CACHED;
 #endif
 
 #ifdef CONFIG_FSNOTIFY
@@ -242,10 +248,19 @@ void __destroy_inode(struct inode *inode)
 	security_inode_free(inode);
 	fsnotify_inode_delete(inode);
 #ifdef CONFIG_FS_POSIX_ACL
-	if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED)
-		posix_acl_release(inode->i_acl);
-	if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED)
-		posix_acl_release(inode->i_default_acl);
+	if (IS_POSIXACL(inode)) {
+		if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED)
+			posix_acl_release(inode->i_acl);
+		if (inode->i_default_acl &&
+		    inode->i_default_acl != ACL_NOT_CACHED)
+			posix_acl_release(inode->i_default_acl);
+	}
+#endif
+#ifdef CONFIG_FS_RICHACL
+	if (IS_RICHACL(inode)) {
+		if (inode->i_richacl && inode->i_richacl != ACL_NOT_CACHED)
+			richacl_put(inode->i_richacl);
+	}
 #endif
 	this_cpu_dec(nr_inodes);
 }
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8d5d6e4..cfbe763 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -757,6 +757,7 @@ static inline int mapping_writably_mapped(struct address_space *mapping)
 #endif
 
 struct posix_acl;
+struct richacl;
 #define ACL_NOT_CACHED ((void *)(-1))
 
 #define IOP_FASTPERM	0x0001
@@ -775,10 +776,17 @@ struct inode {
 	gid_t			i_gid;
 	unsigned int		i_flags;
 
+	union {
 #ifdef CONFIG_FS_POSIX_ACL
-	struct posix_acl	*i_acl;
-	struct posix_acl	*i_default_acl;
+		struct {
+			struct posix_acl *i_acl;
+			struct posix_acl *i_default_acl;
+		};
 #endif
+#ifdef CONFIG_FS_RICHACL
+		struct richacl	*i_richacl;
+#endif
+	};
 
 	const struct inode_operations	*i_op;
 	struct super_block	*i_sb;
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index ca07209..a00a9a6 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -189,6 +189,59 @@ richacl_put(struct richacl *acl)
 		kfree(acl);
 }
 
+#ifdef CONFIG_FS_RICHACL
+static inline struct richacl *get_cached_richacl(struct inode *inode)
+{
+	struct richacl **p, *acl;
+
+	p = &inode->i_richacl;
+	acl = ACCESS_ONCE(*p);
+	if (acl) {
+		spin_lock(&inode->i_lock);
+		acl = *p;
+		if (acl != ACL_NOT_CACHED)
+			acl = richacl_get(acl);
+		spin_unlock(&inode->i_lock);
+	}
+	return acl;
+}
+
+static inline void set_cached_richacl(struct inode *inode,
+				      struct richacl *acl)
+{
+	struct richacl *old = NULL;
+	spin_lock(&inode->i_lock);
+	old = inode->i_richacl;
+	inode->i_richacl = richacl_get(acl);
+	spin_unlock(&inode->i_lock);
+	if (old != ACL_NOT_CACHED)
+		richacl_put(old);
+}
+
+static inline void forget_cached_richacl(struct inode *inode)
+{
+	struct richacl *old = NULL;
+	spin_lock(&inode->i_lock);
+	old = inode->i_richacl;
+	inode->i_richacl = ACL_NOT_CACHED;
+	spin_unlock(&inode->i_lock);
+	if (old != ACL_NOT_CACHED)
+		richacl_put(old);
+}
+
+static inline int negative_cached_richacl(struct inode *inode)
+{
+	struct richacl **p, *acl;
+
+	p = &inode->i_richacl;
+	acl = ACCESS_ONCE(*p);
+	if (acl)
+		return 0;
+	return 1;
+}
+
+#endif
+
 static inline int
 richacl_is_auto_inherit(const struct richacl *acl)
 {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 23/26] vfs: Add richacl permission check
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/attr.c               |    6 +++-
 fs/namei.c              |   13 ++++++++++-
 fs/richacl_base.c       |   54 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fs.h      |    2 +-
 include/linux/richacl.h |    2 +
 5 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index 00578b9..2b445ba 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -13,6 +13,7 @@
 #include <linux/fsnotify.h>
 #include <linux/fcntl.h>
 #include <linux/security.h>
+#include <linux/richacl.h>
 
 static int richacl_change_ok(struct inode *inode, int mask)
 {
@@ -21,8 +22,9 @@ static int richacl_change_ok(struct inode *inode, int mask)
 
 	if (inode->i_op->permission)
 		return inode->i_op->permission(inode, mask);
-
-	return check_acl(inode, mask);
+	if (inode->i_op->get_richacl)
+		return check_richacl(inode, mask);
+	return -EPERM;
 }
 
 static bool inode_uid_change_ok(struct inode *inode, uid_t ia_uid)
diff --git a/fs/namei.c b/fs/namei.c
index ce67eb1..1054bc3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -33,6 +33,7 @@
 #include <linux/device_cgroup.h>
 #include <linux/fs_struct.h>
 #include <linux/posix_acl.h>
+#include <linux/richacl.h>
 #include <asm/uaccess.h>
 
 #include "internal.h"
@@ -174,7 +175,7 @@ void putname(const char *name)
 EXPORT_SYMBOL(putname);
 #endif
 
-int check_acl(struct inode *inode, int mask)
+static int check_posix_acl(struct inode *inode, int mask)
 {
 #ifdef CONFIG_FS_POSIX_ACL
 	struct posix_acl *acl;
@@ -220,6 +221,16 @@ int check_acl(struct inode *inode, int mask)
 	return -EAGAIN;
 }
 
+static int check_acl(struct inode *inode, int mask)
+{
+	if (IS_POSIXACL(inode))
+		return check_posix_acl(inode, mask);
+	else if (IS_RICHACL(inode))
+		return check_richacl(inode, mask);
+	else
+		return -EAGAIN;
+}
+
 /*
  * This does the basic permission checking
  */
diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index 2cdc244..b5b3227 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -623,3 +623,57 @@ richacl_equiv_mode(const struct richacl *acl, mode_t *mode_p)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(richacl_equiv_mode);
+
+int check_richacl(struct inode *inode, int want)
+{
+#ifdef CONFIG_FS_RICHACL
+	struct richacl *acl;
+	int richacl_mask = richacl_want_to_mask(want);
+
+	if (want & MAY_NOT_BLOCK) {
+		acl = rcu_dereference(inode->i_richacl);
+		if (!acl)
+			return -EAGAIN;
+		/* no ->get_acl() calls in RCU mode... */
+		if (acl == ACL_NOT_CACHED)
+			return -ECHILD;
+		return richacl_permission(inode, acl, richacl_mask);
+	}
+	return richacl_check_acl(inode, richacl_mask);
+#endif
+	return -EAGAIN;
+}
+
+int richacl_check_acl(struct inode *inode, int richacl_mask)
+{
+
+#ifdef CONFIG_FS_RICHACL
+	struct richacl *acl;
+	acl = get_cached_richacl(inode);
+	/*
+	 * A filesystem can force a ACL callback by just never filling the
+	 * ACL cache. But normally you'd fill the cache either at inode
+	 * instantiation time, or on the first ->get_acl call.
+	 *
+	 * If the filesystem doesn't have a get_acl() function at all, we'll
+	 * just create the negative cache entry.
+	 */
+	if (acl == ACL_NOT_CACHED) {
+		if (inode->i_op->get_acl) {
+			acl = inode->i_op->get_richacl(inode);
+			if (IS_ERR(acl))
+				return PTR_ERR(acl);
+		} else {
+			set_cached_richacl(inode, NULL);
+			return -EAGAIN;
+		}
+	}
+	if (acl) {
+		int error = richacl_permission(inode, acl, richacl_mask);
+		richacl_put(acl);
+		return error;
+	}
+#endif
+	return -EAGAIN;
+}
+EXPORT_SYMBOL_GPL(richacl_check_acl);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index cfbe763..38ad50a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1626,6 +1626,7 @@ struct inode_operations {
 	void * (*follow_link) (struct dentry *, struct nameidata *);
 	int (*permission) (struct inode *, int);
 	struct posix_acl * (*get_acl)(struct inode *, int);
+	struct richacl * (*get_richacl)(struct inode *);
 
 	int (*readlink) (struct dentry *, char __user *,int);
 	void (*put_link) (struct dentry *, struct nameidata *, void *);
@@ -2245,7 +2246,6 @@ extern sector_t bmap(struct inode *, sector_t);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int inode_permission(struct inode *, int);
 extern int generic_permission(struct inode *, int);
-extern int check_acl(struct inode *, int);
 
 static inline bool execute_ok(struct inode *inode)
 {
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index a00a9a6..00d52a4 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -367,6 +367,8 @@ extern int richacl_permission(struct inode *, const struct richacl *,
 			      unsigned int);
 extern struct richacl *richacl_inherit(const struct richacl *, int);
 extern int richacl_equiv_mode(const struct richacl *, mode_t *);
+extern int check_richacl(struct inode *, int);
+extern int richacl_check_acl(struct inode *, int);
 
 /* richacl_inode.c */
 extern struct richacl *richacl_inherit_inode(const struct richacl *,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 23/26] vfs: Add richacl permission check
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA
  Cc: aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 fs/attr.c               |    6 +++-
 fs/namei.c              |   13 ++++++++++-
 fs/richacl_base.c       |   54 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fs.h      |    2 +-
 include/linux/richacl.h |    2 +
 5 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index 00578b9..2b445ba 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -13,6 +13,7 @@
 #include <linux/fsnotify.h>
 #include <linux/fcntl.h>
 #include <linux/security.h>
+#include <linux/richacl.h>
 
 static int richacl_change_ok(struct inode *inode, int mask)
 {
@@ -21,8 +22,9 @@ static int richacl_change_ok(struct inode *inode, int mask)
 
 	if (inode->i_op->permission)
 		return inode->i_op->permission(inode, mask);
-
-	return check_acl(inode, mask);
+	if (inode->i_op->get_richacl)
+		return check_richacl(inode, mask);
+	return -EPERM;
 }
 
 static bool inode_uid_change_ok(struct inode *inode, uid_t ia_uid)
diff --git a/fs/namei.c b/fs/namei.c
index ce67eb1..1054bc3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -33,6 +33,7 @@
 #include <linux/device_cgroup.h>
 #include <linux/fs_struct.h>
 #include <linux/posix_acl.h>
+#include <linux/richacl.h>
 #include <asm/uaccess.h>
 
 #include "internal.h"
@@ -174,7 +175,7 @@ void putname(const char *name)
 EXPORT_SYMBOL(putname);
 #endif
 
-int check_acl(struct inode *inode, int mask)
+static int check_posix_acl(struct inode *inode, int mask)
 {
 #ifdef CONFIG_FS_POSIX_ACL
 	struct posix_acl *acl;
@@ -220,6 +221,16 @@ int check_acl(struct inode *inode, int mask)
 	return -EAGAIN;
 }
 
+static int check_acl(struct inode *inode, int mask)
+{
+	if (IS_POSIXACL(inode))
+		return check_posix_acl(inode, mask);
+	else if (IS_RICHACL(inode))
+		return check_richacl(inode, mask);
+	else
+		return -EAGAIN;
+}
+
 /*
  * This does the basic permission checking
  */
diff --git a/fs/richacl_base.c b/fs/richacl_base.c
index 2cdc244..b5b3227 100644
--- a/fs/richacl_base.c
+++ b/fs/richacl_base.c
@@ -623,3 +623,57 @@ richacl_equiv_mode(const struct richacl *acl, mode_t *mode_p)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(richacl_equiv_mode);
+
+int check_richacl(struct inode *inode, int want)
+{
+#ifdef CONFIG_FS_RICHACL
+	struct richacl *acl;
+	int richacl_mask = richacl_want_to_mask(want);
+
+	if (want & MAY_NOT_BLOCK) {
+		acl = rcu_dereference(inode->i_richacl);
+		if (!acl)
+			return -EAGAIN;
+		/* no ->get_acl() calls in RCU mode... */
+		if (acl == ACL_NOT_CACHED)
+			return -ECHILD;
+		return richacl_permission(inode, acl, richacl_mask);
+	}
+	return richacl_check_acl(inode, richacl_mask);
+#endif
+	return -EAGAIN;
+}
+
+int richacl_check_acl(struct inode *inode, int richacl_mask)
+{
+
+#ifdef CONFIG_FS_RICHACL
+	struct richacl *acl;
+	acl = get_cached_richacl(inode);
+	/*
+	 * A filesystem can force a ACL callback by just never filling the
+	 * ACL cache. But normally you'd fill the cache either at inode
+	 * instantiation time, or on the first ->get_acl call.
+	 *
+	 * If the filesystem doesn't have a get_acl() function at all, we'll
+	 * just create the negative cache entry.
+	 */
+	if (acl == ACL_NOT_CACHED) {
+		if (inode->i_op->get_acl) {
+			acl = inode->i_op->get_richacl(inode);
+			if (IS_ERR(acl))
+				return PTR_ERR(acl);
+		} else {
+			set_cached_richacl(inode, NULL);
+			return -EAGAIN;
+		}
+	}
+	if (acl) {
+		int error = richacl_permission(inode, acl, richacl_mask);
+		richacl_put(acl);
+		return error;
+	}
+#endif
+	return -EAGAIN;
+}
+EXPORT_SYMBOL_GPL(richacl_check_acl);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index cfbe763..38ad50a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1626,6 +1626,7 @@ struct inode_operations {
 	void * (*follow_link) (struct dentry *, struct nameidata *);
 	int (*permission) (struct inode *, int);
 	struct posix_acl * (*get_acl)(struct inode *, int);
+	struct richacl * (*get_richacl)(struct inode *);
 
 	int (*readlink) (struct dentry *, char __user *,int);
 	void (*put_link) (struct dentry *, struct nameidata *, void *);
@@ -2245,7 +2246,6 @@ extern sector_t bmap(struct inode *, sector_t);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int inode_permission(struct inode *, int);
 extern int generic_permission(struct inode *, int);
-extern int check_acl(struct inode *, int);
 
 static inline bool execute_ok(struct inode *inode)
 {
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index a00a9a6..00d52a4 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -367,6 +367,8 @@ extern int richacl_permission(struct inode *, const struct richacl *,
 			      unsigned int);
 extern struct richacl *richacl_inherit(const struct richacl *, int);
 extern int richacl_equiv_mode(const struct richacl *, mode_t *);
+extern int check_richacl(struct inode *, int);
+extern int richacl_check_acl(struct inode *, int);
 
 /* richacl_inode.c */
 extern struct richacl *richacl_inherit_inode(const struct richacl *,
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 24/26] ext4: Use IS_POSIXACL() to check for POSIX ACL support
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (22 preceding siblings ...)
  2011-09-05 17:25   ` Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25 ` [PATCH -V6 25/26] ext4: Implement rich acl for ext4 Aneesh Kumar K.V
                   ` (13 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

Use IS_POSIXACL() instead of a file system specific mount flag since we
have IS_POSIXACL() in the vfs already, anyway.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
---
 fs/ext4/acl.c   |   16 ++++++++--------
 fs/ext4/ext4.h  |    1 -
 fs/ext4/super.c |   16 +++++-----------
 3 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index a5c29bb..525bbc3 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -139,7 +139,7 @@ ext4_get_acl(struct inode *inode, int type)
 	struct posix_acl *acl;
 	int retval;
 
-	if (!test_opt(inode->i_sb, POSIX_ACL))
+	if (!IS_POSIXACL(inode))
 		return NULL;
 
 	acl = get_cached_acl(inode, type);
@@ -248,7 +248,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
 	int error = 0;
 
 	if (!S_ISLNK(inode->i_mode)) {
-		if (test_opt(dir->i_sb, POSIX_ACL)) {
+		if (IS_POSIXACL(inode)) {
 			acl = ext4_get_acl(dir, ACL_TYPE_DEFAULT);
 			if (IS_ERR(acl))
 				return PTR_ERR(acl);
@@ -256,7 +256,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
 		if (!acl)
 			inode->i_mode &= ~current_umask();
 	}
-	if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
+	if (IS_POSIXACL(inode) && acl) {
 		if (S_ISDIR(inode->i_mode)) {
 			error = ext4_set_acl(handle, inode,
 					     ACL_TYPE_DEFAULT, acl);
@@ -302,7 +302,7 @@ ext4_acl_chmod(struct inode *inode)
 
 	if (S_ISLNK(inode->i_mode))
 		return -EOPNOTSUPP;
-	if (!test_opt(inode->i_sb, POSIX_ACL))
+	if (!IS_POSIXACL(inode))
 		return 0;
 	acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
 	if (IS_ERR(acl) || !acl)
@@ -337,7 +337,7 @@ ext4_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_len,
 {
 	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
 
-	if (!test_opt(dentry->d_sb, POSIX_ACL))
+	if (!IS_POSIXACL(dentry->d_inode))
 		return 0;
 	if (list && size <= list_len)
 		memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
@@ -350,7 +350,7 @@ ext4_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_len,
 {
 	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
 
-	if (!test_opt(dentry->d_sb, POSIX_ACL))
+	if (!IS_POSIXACL(dentry->d_inode))
 		return 0;
 	if (list && size <= list_len)
 		memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
@@ -366,7 +366,7 @@ ext4_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
 
 	if (strcmp(name, "") != 0)
 		return -EINVAL;
-	if (!test_opt(dentry->d_sb, POSIX_ACL))
+	if (!IS_POSIXACL(dentry->d_inode))
 		return -EOPNOTSUPP;
 
 	acl = ext4_get_acl(dentry->d_inode, type);
@@ -391,7 +391,7 @@ ext4_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
 
 	if (strcmp(name, "") != 0)
 		return -EINVAL;
-	if (!test_opt(inode->i_sb, POSIX_ACL))
+	if (!IS_POSIXACL(dentry->d_inode))
 		return -EOPNOTSUPP;
 	if (!inode_owner_or_capable(inode))
 		return -EPERM;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index e717dfd..be229ac 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -900,7 +900,6 @@ struct ext4_inode_info {
 #define EXT4_MOUNT_UPDATE_JOURNAL	0x01000	/* Update the journal format */
 #define EXT4_MOUNT_NO_UID32		0x02000  /* Disable 32-bit UIDs */
 #define EXT4_MOUNT_XATTR_USER		0x04000	/* Extended user attributes */
-#define EXT4_MOUNT_POSIX_ACL		0x08000	/* POSIX Access Control Lists */
 #define EXT4_MOUNT_NO_AUTO_DA_ALLOC	0x10000	/* No auto delalloc mapping */
 #define EXT4_MOUNT_BARRIER		0x20000 /* Use block barriers */
 #define EXT4_MOUNT_QUOTA		0x80000 /* Some quota option set */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 44d0c8d..99d72cf 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1066,9 +1066,9 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
 		seq_puts(seq, ",nouser_xattr");
 #endif
 #ifdef CONFIG_EXT4_FS_POSIX_ACL
-	if (test_opt(sb, POSIX_ACL) && !(def_mount_opts & EXT4_DEFM_ACL))
+	if ((sb->s_flags & MS_POSIXACL) && !(def_mount_opts & EXT4_DEFM_ACL))
 		seq_puts(seq, ",acl");
-	if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL))
+	if (!(sb->s_flags & MS_POSIXACL) && (def_mount_opts & EXT4_DEFM_ACL))
 		seq_puts(seq, ",noacl");
 #endif
 	if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
@@ -1587,10 +1587,10 @@ static int parse_options(char *options, struct super_block *sb,
 #endif
 #ifdef CONFIG_EXT4_FS_POSIX_ACL
 		case Opt_acl:
-			set_opt(sb, POSIX_ACL);
+			sb->s_flags |= MS_POSIXACL;
 			break;
 		case Opt_noacl:
-			clear_opt(sb, POSIX_ACL);
+			sb->s_flags &= ~MS_POSIXACL;
 			break;
 #else
 		case Opt_acl:
@@ -3170,7 +3170,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	set_opt(sb, XATTR_USER);
 #endif
 #ifdef CONFIG_EXT4_FS_POSIX_ACL
-	set_opt(sb, POSIX_ACL);
+	sb->s_flags |= MS_POSIXACL;
 #endif
 	set_opt(sb, MBLK_IO_SUBMIT);
 	if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA)
@@ -3224,9 +3224,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 			   &journal_ioprio, NULL, 0))
 		goto failed_mount;
 
-	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
-		(test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
-
 	if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV &&
 	    (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) ||
 	     EXT4_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
@@ -4351,9 +4348,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 	if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
 		ext4_abort(sb, "Abort forced by user");
 
-	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
-		(test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
-
 	es = sbi->s_es;
 
 	if (sbi->s_journal) {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 25/26] ext4: Implement rich acl for ext4
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (23 preceding siblings ...)
  2011-09-05 17:25 ` [PATCH -V6 24/26] ext4: Use IS_POSIXACL() to check for POSIX ACL support Aneesh Kumar K.V
@ 2011-09-05 17:25 ` Aneesh Kumar K.V
  2011-09-05 17:25   ` Aneesh Kumar K.V
                   ` (12 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

Support the richacl permission model in ext4.  The richacls are stored
in "system.richacl" xattrs.This need to be enabled by tune2fs or during
mkfs.ext4

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
---
 fs/ext4/Kconfig   |   15 ++++
 fs/ext4/Makefile  |    1 +
 fs/ext4/acl.c     |    9 +-
 fs/ext4/acl.h     |    4 +-
 fs/ext4/file.c    |    4 +-
 fs/ext4/ialloc.c  |    7 ++-
 fs/ext4/inode.c   |   10 ++-
 fs/ext4/namei.c   |    7 +-
 fs/ext4/richacl.c |  228 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ext4/richacl.h |   46 +++++++++++
 fs/ext4/xattr.c   |    6 ++
 fs/ext4/xattr.h   |    2 +
 12 files changed, 325 insertions(+), 14 deletions(-)
 create mode 100644 fs/ext4/richacl.c
 create mode 100644 fs/ext4/richacl.h

diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index 9ed1bb1..a22b8f1d 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -83,3 +83,18 @@ config EXT4_DEBUG
 
 	  If you select Y here, then you will be able to turn on debugging
 	  with a command such as "echo 1 > /sys/kernel/debug/ext4/mballoc-debug"
+
+config EXT4_FS_RICHACL
+      bool "Ext4 Rich Access Control Lists (EXPERIMENTAL)"
+      depends on EXT4_FS_XATTR && EXPERIMENTAL
+      select FS_RICHACL
+      help
+	Rich ACLs are an implementation of NFSv4 ACLs, extended by file masks
+	to fit into the standard POSIX file permission model.  They are
+	designed to work seamlessly locally as well as across the NFSv4 and
+	CIFS/SMB2 network file system protocols.
+
+	To learn more about Rich ACL, visit
+	http://acl.bestbits.at/richacl/
+
+	If you don't know what Rich ACLs are, say N
diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
index 56fd8f86..9cd271a 100644
--- a/fs/ext4/Makefile
+++ b/fs/ext4/Makefile
@@ -12,3 +12,4 @@ ext4-y	:= balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o page-io.o \
 ext4-$(CONFIG_EXT4_FS_XATTR)		+= xattr.o xattr_user.o xattr_trusted.o
 ext4-$(CONFIG_EXT4_FS_POSIX_ACL)	+= acl.o
 ext4-$(CONFIG_EXT4_FS_SECURITY)		+= xattr_security.o
+ext4-$(CONFIG_EXT4_FS_RICHACL) 		+= richacl.o
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 525bbc3..00e54b8 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -131,8 +131,7 @@ fail:
  *
  * inode->i_mutex: don't care
  */
-struct posix_acl *
-ext4_get_acl(struct inode *inode, int type)
+struct posix_acl *ext4_get_posix_acl(struct inode *inode, int type)
 {
 	int name_index;
 	char *value = NULL;
@@ -249,7 +248,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
 
 	if (!S_ISLNK(inode->i_mode)) {
 		if (IS_POSIXACL(inode)) {
-			acl = ext4_get_acl(dir, ACL_TYPE_DEFAULT);
+			acl = ext4_get_posix_acl(dir, ACL_TYPE_DEFAULT);
 			if (IS_ERR(acl))
 				return PTR_ERR(acl);
 		}
@@ -304,7 +303,7 @@ ext4_acl_chmod(struct inode *inode)
 		return -EOPNOTSUPP;
 	if (!IS_POSIXACL(inode))
 		return 0;
-	acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
+	acl = ext4_get_posix_acl(inode, ACL_TYPE_ACCESS);
 	if (IS_ERR(acl) || !acl)
 		return PTR_ERR(acl);
 	error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
@@ -369,7 +368,7 @@ ext4_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
 	if (!IS_POSIXACL(dentry->d_inode))
 		return -EOPNOTSUPP;
 
-	acl = ext4_get_acl(dentry->d_inode, type);
+	acl = ext4_get_posix_acl(dentry->d_inode, type);
 	if (IS_ERR(acl))
 		return PTR_ERR(acl);
 	if (acl == NULL)
diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h
index 18cb39e..ac2bad2 100644
--- a/fs/ext4/acl.h
+++ b/fs/ext4/acl.h
@@ -54,13 +54,13 @@ static inline int ext4_acl_count(size_t size)
 #ifdef CONFIG_EXT4_FS_POSIX_ACL
 
 /* acl.c */
-struct posix_acl *ext4_get_acl(struct inode *inode, int type);
+struct posix_acl *ext4_get_posix_acl(struct inode *inode, int type);
 extern int ext4_acl_chmod(struct inode *);
 extern int ext4_init_acl(handle_t *, struct inode *, struct inode *);
 
 #else  /* CONFIG_EXT4_FS_POSIX_ACL */
 #include <linux/sched.h>
-#define ext4_get_acl NULL
+#define ext4_get_posix_acl NULL
 
 static inline int
 ext4_acl_chmod(struct inode *inode)
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index e4095e9..2f515a2 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -28,6 +28,7 @@
 #include "ext4_jbd2.h"
 #include "xattr.h"
 #include "acl.h"
+#include "richacl.h"
 
 /*
  * Called when an inode is released. Note that this is different
@@ -301,7 +302,8 @@ const struct inode_operations ext4_file_inode_operations = {
 	.listxattr	= ext4_listxattr,
 	.removexattr	= generic_removexattr,
 #endif
-	.get_acl	= ext4_get_acl,
+	.get_acl	= ext4_get_posix_acl,
+	.get_richacl	= ext4_get_richacl,
 	.fiemap		= ext4_fiemap,
 };
 
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 9c63f27..77ea40b 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -28,6 +28,7 @@
 #include "ext4_jbd2.h"
 #include "xattr.h"
 #include "acl.h"
+#include "richacl.h"
 
 #include <trace/events/ext4.h>
 
@@ -1039,7 +1040,11 @@ got:
 	if (err)
 		goto fail_drop;
 
-	err = ext4_init_acl(handle, inode, dir);
+	if (EXT4_IS_RICHACL(dir))
+		err = ext4_init_richacl(handle, inode, dir);
+	else
+		err = ext4_init_acl(handle, inode, dir);
+
 	if (err)
 		goto fail_free_drop;
 
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c4da98a..f711fbf 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -44,6 +44,7 @@
 #include "acl.h"
 #include "ext4_extents.h"
 #include "truncate.h"
+#include "richacl.h"
 
 #include <trace/events/ext4.h>
 
@@ -3948,9 +3949,12 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
 	if (orphan && inode->i_nlink)
 		ext4_orphan_del(NULL, inode);
 
-	if (!rc && (ia_valid & ATTR_MODE))
-		rc = ext4_acl_chmod(inode);
-
+	if (!rc && (ia_valid & ATTR_MODE)) {
+		if (EXT4_IS_RICHACL(inode))
+			rc = ext4_richacl_chmod(inode);
+		else
+			rc = ext4_acl_chmod(inode);
+	}
 err_out:
 	ext4_std_error(inode->i_sb, error);
 	if (!error)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index f8068c7..7287d52 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -39,6 +39,7 @@
 
 #include "xattr.h"
 #include "acl.h"
+#include "richacl.h"
 
 #include <trace/events/ext4.h>
 /*
@@ -2585,7 +2586,8 @@ const struct inode_operations ext4_dir_inode_operations = {
 	.listxattr	= ext4_listxattr,
 	.removexattr	= generic_removexattr,
 #endif
-	.get_acl	= ext4_get_acl,
+	.get_acl	= ext4_get_posix_acl,
+	.get_richacl	= ext4_get_richacl,
 	.fiemap         = ext4_fiemap,
 };
 
@@ -2597,5 +2599,6 @@ const struct inode_operations ext4_special_inode_operations = {
 	.listxattr	= ext4_listxattr,
 	.removexattr	= generic_removexattr,
 #endif
-	.get_acl	= ext4_get_acl,
+	.get_acl	= ext4_get_posix_acl,
+	.get_richacl	= ext4_get_richacl,
 };
diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c
new file mode 100644
index 0000000..b04e939
--- /dev/null
+++ b/fs/ext4/richacl.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright IBM Corporation, 2010
+ * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/richacl_xattr.h>
+
+#include "ext4.h"
+#include "ext4_jbd2.h"
+#include "xattr.h"
+#include "acl.h"
+#include "richacl.h"
+
+struct richacl *
+ext4_get_richacl(struct inode *inode)
+{
+	const int name_index = EXT4_XATTR_INDEX_RICHACL;
+	void *value = NULL;
+	struct richacl *acl;
+	int retval;
+
+	if (!IS_RICHACL(inode))
+		return ERR_PTR(-EOPNOTSUPP);
+	acl = get_cached_richacl(inode);
+	if (acl != ACL_NOT_CACHED)
+		return acl;
+	retval = ext4_xattr_get(inode, name_index, "", NULL, 0);
+	if (retval > 0) {
+		value = kmalloc(retval, GFP_KERNEL);
+		if (!value)
+			return ERR_PTR(-ENOMEM);
+		retval = ext4_xattr_get(inode, name_index, "", value, retval);
+	}
+	if (retval > 0) {
+		acl = richacl_from_xattr(value, retval);
+		if (acl == ERR_PTR(-EINVAL))
+			acl = ERR_PTR(-EIO);
+	} else if (retval == -ENODATA || retval == -ENOSYS)
+		acl = NULL;
+	else
+		acl = ERR_PTR(retval);
+	kfree(value);
+
+	if (!IS_ERR_OR_NULL(acl))
+		set_cached_richacl(inode, acl);
+
+	return acl;
+}
+
+static int
+ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl)
+{
+	const int name_index = EXT4_XATTR_INDEX_RICHACL;
+	size_t size = 0;
+	void *value = NULL;
+	int retval;
+
+	if (acl) {
+		mode_t mode = inode->i_mode;
+		if (richacl_equiv_mode(acl, &mode) == 0) {
+			inode->i_mode = mode;
+			ext4_mark_inode_dirty(handle, inode);
+			acl = NULL;
+		}
+	}
+	if (acl) {
+		size = richacl_xattr_size(acl);
+		value = kmalloc(size, GFP_KERNEL);
+		if (!value)
+			return -ENOMEM;
+		richacl_to_xattr(acl, value);
+	}
+	if (handle)
+		retval = ext4_xattr_set_handle(handle, inode, name_index, "",
+					       value, size, 0);
+	else
+		retval = ext4_xattr_set(inode, name_index, "", value, size, 0);
+	kfree(value);
+	if (!retval)
+		set_cached_richacl(inode, acl);
+
+	return retval;
+}
+
+int
+ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir)
+{
+	struct richacl *dir_acl = NULL;
+
+	if (!S_ISLNK(inode->i_mode)) {
+		dir_acl = ext4_get_richacl(dir);
+		if (IS_ERR(dir_acl))
+			return PTR_ERR(dir_acl);
+	}
+	if (dir_acl) {
+		struct richacl *acl;
+		int retval;
+
+		acl = richacl_inherit_inode(dir_acl, inode);
+		richacl_put(dir_acl);
+
+		retval = PTR_ERR(acl);
+		if (acl && !IS_ERR(acl)) {
+			retval = ext4_set_richacl(handle, inode, acl);
+			richacl_put(acl);
+		}
+		return retval;
+	} else {
+		inode->i_mode &= ~current_umask();
+		return 0;
+	}
+}
+
+int
+ext4_richacl_chmod(struct inode *inode)
+{
+	struct richacl *acl;
+	int retval;
+
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+	acl = ext4_get_richacl(inode);
+	if (IS_ERR_OR_NULL(acl))
+		return PTR_ERR(acl);
+	acl = richacl_chmod(acl, inode->i_mode);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	retval = ext4_set_richacl(NULL, inode, acl);
+	richacl_put(acl);
+
+	return retval;
+}
+
+static size_t
+ext4_xattr_list_richacl(struct dentry *dentry, char *list, size_t list_len,
+			const char *name, size_t name_len, int type)
+{
+	const size_t size = sizeof(RICHACL_XATTR);
+	if (!IS_RICHACL(dentry->d_inode))
+		return 0;
+	if (list && size <= list_len)
+		memcpy(list, RICHACL_XATTR, size);
+	return size;
+}
+
+static int
+ext4_xattr_get_richacl(struct dentry *dentry, const char *name, void *buffer,
+		size_t buffer_size, int type)
+{
+	struct richacl *acl;
+	size_t size;
+
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	acl = ext4_get_richacl(dentry->d_inode);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	if (acl == NULL)
+		return -ENODATA;
+	size = richacl_xattr_size(acl);
+	if (buffer) {
+		if (size > buffer_size)
+			return -ERANGE;
+		richacl_to_xattr(acl, buffer);
+	}
+	richacl_put(acl);
+
+	return size;
+}
+
+static int
+ext4_xattr_set_richacl(struct dentry *dentry, const char *name,
+		const void *value, size_t size, int flags, int type)
+{
+	handle_t *handle;
+	struct richacl *acl = NULL;
+	int retval, retries = 0;
+	struct inode *inode = dentry->d_inode;
+
+	if (!IS_RICHACL(dentry->d_inode))
+		return -EOPNOTSUPP;
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	if (current_fsuid() != inode->i_uid &&
+	    richacl_check_acl(inode, ACE4_WRITE_ACL) &&
+	    !capable(CAP_FOWNER))
+		return -EPERM;
+	if (value) {
+		acl = richacl_from_xattr(value, size);
+		if (IS_ERR(acl))
+			return PTR_ERR(acl);
+
+		inode->i_mode &= ~S_IRWXUGO;
+		inode->i_mode |= richacl_masks_to_mode(acl);
+	}
+
+retry:
+	handle = ext4_journal_start(inode, EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	ext4_mark_inode_dirty(handle, inode);
+	retval = ext4_set_richacl(handle, inode, acl);
+	ext4_journal_stop(handle);
+	if (retval == ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+		goto retry;
+	richacl_put(acl);
+	return retval;
+}
+
+const struct xattr_handler ext4_richacl_xattr_handler = {
+	.prefix	= RICHACL_XATTR,
+	.list	= ext4_xattr_list_richacl,
+	.get	= ext4_xattr_get_richacl,
+	.set	= ext4_xattr_set_richacl,
+};
diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h
new file mode 100644
index 0000000..2577c34
--- /dev/null
+++ b/fs/ext4/richacl.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright IBM Corporation, 2010
+ * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __FS_EXT4_RICHACL_H
+#define __FS_EXT4_RICHACL_H
+
+#include <linux/richacl.h>
+
+#ifdef CONFIG_EXT4_FS_RICHACL
+
+#define EXT4_IS_RICHACL(inode) IS_RICHACL(inode)
+
+extern struct richacl *ext4_get_richacl(struct inode *);
+extern int ext4_init_richacl(handle_t *, struct inode *, struct inode *);
+extern int ext4_richacl_chmod(struct inode *);
+
+#else  /* CONFIG_FS_EXT4_RICHACL */
+
+#define EXT4_IS_RICHACL(inode) (0)
+#define ext4_get_richacl   NULL
+
+static inline int
+ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir)
+{
+	return 0;
+}
+
+static inline int
+ext4_richacl_chmod(struct inode *inode)
+{
+	return 0;
+}
+
+#endif  /* CONFIG_FS_EXT4_RICHACL */
+#endif  /* __FS_EXT4_RICHACL_H */
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index c757adc..9a00772 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -107,6 +107,9 @@ static const struct xattr_handler *ext4_xattr_handler_map[] = {
 #ifdef CONFIG_EXT4_FS_SECURITY
 	[EXT4_XATTR_INDEX_SECURITY]	     = &ext4_xattr_security_handler,
 #endif
+#ifdef CONFIG_EXT4_FS_RICHACL
+	[EXT4_XATTR_INDEX_RICHACL]           = &ext4_richacl_xattr_handler,
+#endif
 };
 
 const struct xattr_handler *ext4_xattr_handlers[] = {
@@ -119,6 +122,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = {
 #ifdef CONFIG_EXT4_FS_SECURITY
 	&ext4_xattr_security_handler,
 #endif
+#ifdef CONFIG_EXT4_FS_RICHACL
+	&ext4_richacl_xattr_handler,
+#endif
 	NULL
 };
 
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index 25b7387..d5ad729 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -21,6 +21,7 @@
 #define EXT4_XATTR_INDEX_TRUSTED		4
 #define	EXT4_XATTR_INDEX_LUSTRE			5
 #define EXT4_XATTR_INDEX_SECURITY	        6
+#define EXT4_XATTR_INDEX_RICHACL		7
 
 struct ext4_xattr_header {
 	__le32	h_magic;	/* magic number for identification */
@@ -70,6 +71,7 @@ extern const struct xattr_handler ext4_xattr_trusted_handler;
 extern const struct xattr_handler ext4_xattr_acl_access_handler;
 extern const struct xattr_handler ext4_xattr_acl_default_handler;
 extern const struct xattr_handler ext4_xattr_security_handler;
+extern const struct xattr_handler ext4_richacl_xattr_handler;
 
 extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 26/26] ext4: Add temporary richacl mount option for ext4
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells
  Cc: aneesh.kumar, linux-fsdevel, linux-nfs, linux-kernel

This helps in easy testing of the patchset. The mount
option will be later removed in favour of a feature flag.

***Should be folded before merging***

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/ext4/super.c |   51 +++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 99d72cf..71241b0 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1071,6 +1071,10 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
 	if (!(sb->s_flags & MS_POSIXACL) && (def_mount_opts & EXT4_DEFM_ACL))
 		seq_puts(seq, ",noacl");
 #endif
+#ifdef CONFIG_EXT4_FS_RICHACL
+	if (sb->s_flags & MS_RICHACL)
+		seq_puts(seq, ",richacl");
+#endif
 	if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
 		seq_printf(seq, ",commit=%u",
 			   (unsigned) (sbi->s_commit_interval / HZ));
@@ -1320,6 +1324,7 @@ enum {
 	Opt_dioread_nolock, Opt_dioread_lock,
 	Opt_discard, Opt_nodiscard,
 	Opt_init_inode_table, Opt_noinit_inode_table,
+	Opt_richacl,
 };
 
 static const match_table_t tokens = {
@@ -1395,6 +1400,7 @@ static const match_table_t tokens = {
 	{Opt_init_inode_table, "init_itable=%u"},
 	{Opt_init_inode_table, "init_itable"},
 	{Opt_noinit_inode_table, "noinit_itable"},
+	{Opt_richacl, "richacl"},
 	{Opt_err, NULL},
 };
 
@@ -1421,6 +1427,36 @@ static ext4_fsblk_t get_sb_block(void **data)
 	return sb_block;
 }
 
+static void enable_acl(struct super_block *sb)
+{
+#if !defined(CONFIG_EXT4_FS_POSIX_ACL)
+	ext4_msg(sb, KERN_ERR, "acl options not supported");
+	return;
+#endif
+	sb->s_flags |= MS_POSIXACL;
+}
+
+static void disable_acl(struct super_block *sb)
+{
+#if !defined(CONFIG_EXT4_FS_POSIX_ACL)
+	ext4_msg(sb, KERN_ERR, "acl options not supported");
+	return;
+#endif
+	sb->s_flags &= ~MS_POSIXACL;
+	return;
+}
+
+static void enable_richacl(struct super_block *sb)
+{
+#if !defined(CONFIG_EXT4_FS_RICHACL)
+	ext4_msg(sb, KERN_ERR, "richacl options not supported");
+	return;
+#endif
+	sb->s_flags |= MS_RICHACL;
+	sb->s_flags &= ~MS_POSIXACL;
+	return;
+}
+
 #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3))
 static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n"
 	"Contact linux-ext4@vger.kernel.org if you think we should keep it.\n";
@@ -1585,19 +1621,12 @@ static int parse_options(char *options, struct super_block *sb,
 			ext4_msg(sb, KERN_ERR, "(no)user_xattr options not supported");
 			break;
 #endif
-#ifdef CONFIG_EXT4_FS_POSIX_ACL
 		case Opt_acl:
-			sb->s_flags |= MS_POSIXACL;
+			enable_acl(sb);
 			break;
 		case Opt_noacl:
-			sb->s_flags &= ~MS_POSIXACL;
+			disable_acl(sb);
 			break;
-#else
-		case Opt_acl:
-		case Opt_noacl:
-			ext4_msg(sb, KERN_ERR, "(no)acl options not supported");
-			break;
-#endif
 		case Opt_journal_update:
 			/* @@@ FIXME */
 			/* Eventually we will want to be able to create
@@ -1884,6 +1913,8 @@ set_qf_format:
 			break;
 		case Opt_noinit_inode_table:
 			clear_opt(sb, INIT_INODE_TABLE);
+		case Opt_richacl:
+			enable_richacl(sb);
 			break;
 		default:
 			ext4_msg(sb, KERN_ERR,
@@ -3170,7 +3201,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	set_opt(sb, XATTR_USER);
 #endif
 #ifdef CONFIG_EXT4_FS_POSIX_ACL
-	sb->s_flags |= MS_POSIXACL;
+	enable_acl(sb);
 #endif
 	set_opt(sb, MBLK_IO_SUBMIT);
 	if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA)
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH -V6 26/26] ext4: Add temporary richacl mount option for ext4
@ 2011-09-05 17:25   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-05 17:25 UTC (permalink / raw)
  To: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA
  Cc: aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

This helps in easy testing of the patchset. The mount
option will be later removed in favour of a feature flag.

***Should be folded before merging***

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 fs/ext4/super.c |   51 +++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 99d72cf..71241b0 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1071,6 +1071,10 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
 	if (!(sb->s_flags & MS_POSIXACL) && (def_mount_opts & EXT4_DEFM_ACL))
 		seq_puts(seq, ",noacl");
 #endif
+#ifdef CONFIG_EXT4_FS_RICHACL
+	if (sb->s_flags & MS_RICHACL)
+		seq_puts(seq, ",richacl");
+#endif
 	if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
 		seq_printf(seq, ",commit=%u",
 			   (unsigned) (sbi->s_commit_interval / HZ));
@@ -1320,6 +1324,7 @@ enum {
 	Opt_dioread_nolock, Opt_dioread_lock,
 	Opt_discard, Opt_nodiscard,
 	Opt_init_inode_table, Opt_noinit_inode_table,
+	Opt_richacl,
 };
 
 static const match_table_t tokens = {
@@ -1395,6 +1400,7 @@ static const match_table_t tokens = {
 	{Opt_init_inode_table, "init_itable=%u"},
 	{Opt_init_inode_table, "init_itable"},
 	{Opt_noinit_inode_table, "noinit_itable"},
+	{Opt_richacl, "richacl"},
 	{Opt_err, NULL},
 };
 
@@ -1421,6 +1427,36 @@ static ext4_fsblk_t get_sb_block(void **data)
 	return sb_block;
 }
 
+static void enable_acl(struct super_block *sb)
+{
+#if !defined(CONFIG_EXT4_FS_POSIX_ACL)
+	ext4_msg(sb, KERN_ERR, "acl options not supported");
+	return;
+#endif
+	sb->s_flags |= MS_POSIXACL;
+}
+
+static void disable_acl(struct super_block *sb)
+{
+#if !defined(CONFIG_EXT4_FS_POSIX_ACL)
+	ext4_msg(sb, KERN_ERR, "acl options not supported");
+	return;
+#endif
+	sb->s_flags &= ~MS_POSIXACL;
+	return;
+}
+
+static void enable_richacl(struct super_block *sb)
+{
+#if !defined(CONFIG_EXT4_FS_RICHACL)
+	ext4_msg(sb, KERN_ERR, "richacl options not supported");
+	return;
+#endif
+	sb->s_flags |= MS_RICHACL;
+	sb->s_flags &= ~MS_POSIXACL;
+	return;
+}
+
 #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3))
 static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n"
 	"Contact linux-ext4-u79uwXL29TY76Z2rM5mHXA@public.gmane.org if you think we should keep it.\n";
@@ -1585,19 +1621,12 @@ static int parse_options(char *options, struct super_block *sb,
 			ext4_msg(sb, KERN_ERR, "(no)user_xattr options not supported");
 			break;
 #endif
-#ifdef CONFIG_EXT4_FS_POSIX_ACL
 		case Opt_acl:
-			sb->s_flags |= MS_POSIXACL;
+			enable_acl(sb);
 			break;
 		case Opt_noacl:
-			sb->s_flags &= ~MS_POSIXACL;
+			disable_acl(sb);
 			break;
-#else
-		case Opt_acl:
-		case Opt_noacl:
-			ext4_msg(sb, KERN_ERR, "(no)acl options not supported");
-			break;
-#endif
 		case Opt_journal_update:
 			/* @@@ FIXME */
 			/* Eventually we will want to be able to create
@@ -1884,6 +1913,8 @@ set_qf_format:
 			break;
 		case Opt_noinit_inode_table:
 			clear_opt(sb, INIT_INODE_TABLE);
+		case Opt_richacl:
+			enable_richacl(sb);
 			break;
 		default:
 			ext4_msg(sb, KERN_ERR,
@@ -3170,7 +3201,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	set_opt(sb, XATTR_USER);
 #endif
 #ifdef CONFIG_EXT4_FS_POSIX_ACL
-	sb->s_flags |= MS_POSIXACL;
+	enable_acl(sb);
 #endif
 	set_opt(sb, MBLK_IO_SUBMIT);
 	if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA)
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-05 22:42   ` Casey Schaufler
  0 siblings, 0 replies; 116+ messages in thread
From: Casey Schaufler @ 2011-09-05 22:42 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, bfields, akpm, dhowells, linux-fsdevel, linux-nfs,
	linux-kernel, LSM, Casey Schaufler

On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
> Hi,
>
> The following set of patches implements VFS and ext4 changes needed to implement
> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> extended by file masks to fit into the standard POSIX file permission model.
> They are designed to work seamlessly locally as well as across the NFSv4 and
> CIFS/SMB2 network file system protocols.

POSIX ACLs predate the LSM and can't be done as an LSM due to
the interactions between mode bits and ACLs as defined by the
POSIX DRAFT specification. Is there a reason that "rich" ACLs
can not be done as an LSM?

>
> A user-space utility for displaying and changing richacls is available at [4]
> (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
>
> [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
>
> To test richacl on ext4 use -o richacl mount option. This mount option may later be
> dropped in favour of a feature flag.
>
> More details regarding richacl can be found at
> http://acl.bestbits.at/richacl/
>
> Changes from v5:
> a) rebase to v3.1-rc4-131-g9e79e3e
>
> NOTE: The kernel changes will be pushed to
> git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> when kernel.org is back
>
> -aneesh
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-05 22:42   ` Casey Schaufler
  0 siblings, 0 replies; 116+ messages in thread
From: Casey Schaufler @ 2011-09-05 22:42 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, LSM, Casey Schaufler

On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
> Hi,
>
> The following set of patches implements VFS and ext4 changes needed to implement
> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> extended by file masks to fit into the standard POSIX file permission model.
> They are designed to work seamlessly locally as well as across the NFSv4 and
> CIFS/SMB2 network file system protocols.

POSIX ACLs predate the LSM and can't be done as an LSM due to
the interactions between mode bits and ACLs as defined by the
POSIX DRAFT specification. Is there a reason that "rich" ACLs
can not be done as an LSM?

>
> A user-space utility for displaying and changing richacls is available at [4]
> (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
>
> [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
>
> To test richacl on ext4 use -o richacl mount option. This mount option may later be
> dropped in favour of a feature flag.
>
> More details regarding richacl can be found at
> http://acl.bestbits.at/richacl/
>
> Changes from v5:
> a) rebase to v3.1-rc4-131-g9e79e3e
>
> NOTE: The kernel changes will be pushed to
> git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> when kernel.org is back
>
> -aneesh
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (26 preceding siblings ...)
  2011-09-05 22:42   ` Casey Schaufler
@ 2011-09-06  9:41 ` Steven Whitehouse
  2011-09-06 13:58     ` Aneesh Kumar K.V
  2011-09-07 23:44 ` J. Bruce Fields
                   ` (9 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: Steven Whitehouse @ 2011-09-06  9:41 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, bfields, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

Hi,

On Mon, 2011-09-05 at 22:55 +0530, Aneesh Kumar K.V wrote:
> Hi,
> 
> The following set of patches implements VFS and ext4 changes needed to implement
> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> extended by file masks to fit into the standard POSIX file permission model.
> They are designed to work seamlessly locally as well as across the NFSv4 and
> CIFS/SMB2 network file system protocols.
> 
> A user-space utility for displaying and changing richacls is available at [4]
> (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> 
> [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> 
> To test richacl on ext4 use -o richacl mount option. This mount option may later be
> dropped in favour of a feature flag.
> 
> More details regarding richacl can be found at
> http://acl.bestbits.at/richacl/
> 
> Changes from v5:
> a) rebase to v3.1-rc4-131-g9e79e3e
> 
> NOTE: The kernel changes will be pushed to
> git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> when kernel.org is back
> 
> -aneesh
> 

This looks like a really nice patch set. One question though is whether
there are any test suites which can be used to gain confidence in the
implementation? Obviously there is a fair amount of change here which
has security implications, so it would be good to have some test results
to go along with the patches,

Steve.



^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
  2011-09-06  9:41 ` Steven Whitehouse
@ 2011-09-06 13:58     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-06 13:58 UTC (permalink / raw)
  To: Steven Whitehouse
  Cc: agruen, bfields, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Tue, 06 Sep 2011 10:41:06 +0100, Steven Whitehouse <swhiteho@redhat.com> wrote:
> Hi,
> 
> On Mon, 2011-09-05 at 22:55 +0530, Aneesh Kumar K.V wrote:
> > Hi,
> > 
> > The following set of patches implements VFS and ext4 changes needed to implement
> > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > extended by file masks to fit into the standard POSIX file permission model.
> > They are designed to work seamlessly locally as well as across the NFSv4 and
> > CIFS/SMB2 network file system protocols.
> > 
> > A user-space utility for displaying and changing richacls is available at [4]
> > (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> > 
> > [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> > 
> > To test richacl on ext4 use -o richacl mount option. This mount option may later be
> > dropped in favour of a feature flag.
> > 
> > More details regarding richacl can be found at
> > http://acl.bestbits.at/richacl/
> > 
> > Changes from v5:
> > a) rebase to v3.1-rc4-131-g9e79e3e
> > 
> > NOTE: The kernel changes will be pushed to
> > git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> > when kernel.org is back
> > 
> > -aneesh
> > 
> 
> This looks like a really nice patch set. One question though is whether
> there are any test suites which can be used to gain confidence in the
> implementation? Obviously there is a fair amount of change here which
> has security implications, so it would be good to have some test results
> to go along with the patches,

You can find the tests at 

http://git.kernel.org/?p=fs/acl/kvaneesh/richacl.git;a=tree;f=test;h=3bedf00ac69c79ae7a433996e729d4afb366b229;hb=HEAD

-aneesh

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-06 13:58     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-06 13:58 UTC (permalink / raw)
  To: Steven Whitehouse
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A, bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tue, 06 Sep 2011 10:41:06 +0100, Steven Whitehouse <swhiteho-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> Hi,
> 
> On Mon, 2011-09-05 at 22:55 +0530, Aneesh Kumar K.V wrote:
> > Hi,
> > 
> > The following set of patches implements VFS and ext4 changes needed to implement
> > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > extended by file masks to fit into the standard POSIX file permission model.
> > They are designed to work seamlessly locally as well as across the NFSv4 and
> > CIFS/SMB2 network file system protocols.
> > 
> > A user-space utility for displaying and changing richacls is available at [4]
> > (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> > 
> > [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> > 
> > To test richacl on ext4 use -o richacl mount option. This mount option may later be
> > dropped in favour of a feature flag.
> > 
> > More details regarding richacl can be found at
> > http://acl.bestbits.at/richacl/
> > 
> > Changes from v5:
> > a) rebase to v3.1-rc4-131-g9e79e3e
> > 
> > NOTE: The kernel changes will be pushed to
> > git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> > when kernel.org is back
> > 
> > -aneesh
> > 
> 
> This looks like a really nice patch set. One question though is whether
> there are any test suites which can be used to gain confidence in the
> implementation? Obviously there is a fair amount of change here which
> has security implications, so it would be good to have some test results
> to go along with the patches,

You can find the tests at 

http://git.kernel.org/?p=fs/acl/kvaneesh/richacl.git;a=tree;f=test;h=3bedf00ac69c79ae7a433996e729d4afb366b229;hb=HEAD

-aneesh
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
  2011-09-06 13:58     ` Aneesh Kumar K.V
  (?)
@ 2011-09-07 20:18     ` J. Bruce Fields
  -1 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 20:18 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: Steven Whitehouse, agruen, akpm, dhowells, linux-fsdevel,
	linux-nfs, linux-kernel

On Tue, Sep 06, 2011 at 07:28:51PM +0530, Aneesh Kumar K.V wrote:
> On Tue, 06 Sep 2011 10:41:06 +0100, Steven Whitehouse <swhiteho@redhat.com> wrote:
> > Hi,
> > 
> > On Mon, 2011-09-05 at 22:55 +0530, Aneesh Kumar K.V wrote:
> > > Hi,
> > > 
> > > The following set of patches implements VFS and ext4 changes needed to implement
> > > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > > extended by file masks to fit into the standard POSIX file permission model.
> > > They are designed to work seamlessly locally as well as across the NFSv4 and
> > > CIFS/SMB2 network file system protocols.
> > > 
> > > A user-space utility for displaying and changing richacls is available at [4]
> > > (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> > > 
> > > [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> > > 
> > > To test richacl on ext4 use -o richacl mount option. This mount option may later be
> > > dropped in favour of a feature flag.
> > > 
> > > More details regarding richacl can be found at
> > > http://acl.bestbits.at/richacl/
> > > 
> > > Changes from v5:
> > > a) rebase to v3.1-rc4-131-g9e79e3e
> > > 
> > > NOTE: The kernel changes will be pushed to
> > > git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> > > when kernel.org is back
> > > 
> > > -aneesh
> > > 
> > 
> > This looks like a really nice patch set. One question though is whether
> > there are any test suites which can be used to gain confidence in the
> > implementation? Obviously there is a fair amount of change here which
> > has security implications, so it would be good to have some test results
> > to go along with the patches,
> 
> You can find the tests at 
> 
> http://git.kernel.org/?p=fs/acl/kvaneesh/richacl.git;a=tree;f=test;h=3bedf00ac69c79ae7a433996e729d4afb366b229;hb=HEAD

Do you have a copy of that anywhere else?  gitweb on kernel.org seems to
be out at the moment.

--b.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
@ 2011-09-07 20:39     ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 20:39 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> From: Andreas Gruenbacher <agruen@kernel.org>
> 
> Normally, deleting a file requires write access to the parent directory.
> Some permission models use a different permission on the parent
> directory to indicate delete access.  In addition, a process can have
> per-file delete access even without delete access on the parent
> directory.
> 
> Introduce two new inode_permission() mask flags and use them in
> may_delete()
> 
> Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
>  fs/namei.c         |   41 +++++++++++++++++++++++++++--------------
>  include/linux/fs.h |    2 ++
>  2 files changed, 29 insertions(+), 14 deletions(-)
> 
> diff --git a/fs/namei.c b/fs/namei.c
> index d52a4cd..eacb530 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -337,7 +337,7 @@ static inline int do_inode_permission(struct inode *inode, int mask)
>   * are used for other things.
>   *
>   * When checking for MAY_APPEND, MAY_CREATE_FILE, MAY_CREATE_DIR,
> - * MAY_WRITE must also be set in @mask.
> + * MAY_DELETE_CHILD, MAY_DELETE_SELF, MAY_WRITE must also be set in @mask.
>   */
>  int inode_permission(struct inode *inode, int mask)
>  {
> @@ -1862,7 +1862,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
>  		return 0;
>  
>  other_userns:
> -	return !ns_capable(inode_userns(inode), CAP_FOWNER);
> +	return 1;
>  }
>  
>  /*
> @@ -1884,30 +1884,43 @@ other_userns:
>   * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
>   *     nfs_async_unlink().
>   */
> -static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
> +static int may_delete(struct inode *dir, struct dentry *victim,
> +		      int isdir, int replace)
>  {
> -	int error;
> +	int mask, error, is_sticky;
> +	struct inode *inode = victim->d_inode;
>  
> -	if (!victim->d_inode)
> +	if (!inode)
>  		return -ENOENT;
>  
>  	BUG_ON(victim->d_parent->d_inode != dir);
>  	audit_inode_child(victim, dir);
>  
> -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> +	if (replace)
> +		mask |= S_ISDIR(inode->i_mode) ?
> +			MAY_CREATE_DIR : MAY_CREATE_FILE;

I'm having trouble understanding this next bit:

> +	is_sticky = check_sticky(dir, inode);
> +	error = inode_permission(dir, mask);
> +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> +	    !inode_permission(inode, MAY_DELETE_SELF))
> +		error = 0;

OK, so we can ignore the lack of write or delete permissions on the
parent if we have delete_self permissions on the child.  I guess that's
right.

Why the "|| is_sticky" above?

Is there some less complicated why to write this?

--b.

> +	else if (!error && is_sticky &&
> +		 !ns_capable(inode_userns(inode), CAP_FOWNER))
> +		error = -EPERM;
>  	if (error)
>  		return error;
>  	if (IS_APPEND(dir))
>  		return -EPERM;
> -	if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
> -	    IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
> +	if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
>  		return -EPERM;
>  	if (isdir) {
> -		if (!S_ISDIR(victim->d_inode->i_mode))
> +		if (!S_ISDIR(inode->i_mode))
>  			return -ENOTDIR;
>  		if (IS_ROOT(victim))
>  			return -EBUSY;
> -	} else if (S_ISDIR(victim->d_inode->i_mode))
> +	} else if (S_ISDIR(inode->i_mode))
>  		return -EISDIR;
>  	if (IS_DEADDIR(dir))
>  		return -ENOENT;
> @@ -2614,7 +2627,7 @@ void dentry_unhash(struct dentry *dentry)
>  
>  int vfs_rmdir(struct inode *dir, struct dentry *dentry)
>  {
> -	int error = may_delete(dir, dentry, 1);
> +	int error = may_delete(dir, dentry, 1, 0);
>  
>  	if (error)
>  		return error;
> @@ -2707,7 +2720,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
>  
>  int vfs_unlink(struct inode *dir, struct dentry *dentry)
>  {
> -	int error = may_delete(dir, dentry, 0);
> +	int error = may_delete(dir, dentry, 0, 0);
>  
>  	if (error)
>  		return error;
> @@ -3101,14 +3114,14 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
>  	if (old_dentry->d_inode == new_dentry->d_inode)
>   		return 0;
>   
> -	error = may_delete(old_dir, old_dentry, is_dir);
> +	error = may_delete(old_dir, old_dentry, is_dir, 0);
>  	if (error)
>  		return error;
>  
>  	if (!new_dentry->d_inode)
>  		error = may_create(new_dir, new_dentry, is_dir);
>  	else
> -		error = may_delete(new_dir, new_dentry, is_dir);
> +		error = may_delete(new_dir, new_dentry, is_dir, 1);
>  	if (error)
>  		return error;
>  
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 8707f43..c5c98c5 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -69,6 +69,8 @@ struct inodes_stat_t {
>  #define MAY_NOT_BLOCK		0x00000080
>  #define MAY_CREATE_FILE		0x00000100
>  #define MAY_CREATE_DIR		0x00000200
> +#define MAY_DELETE_CHILD	0x00000400
> +#define MAY_DELETE_SELF		0x00000800
>  
>  /*
>   * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
> -- 
> 1.7.4.1
> 

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
@ 2011-09-07 20:39     ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 20:39 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> 
> Normally, deleting a file requires write access to the parent directory.
> Some permission models use a different permission on the parent
> directory to indicate delete access.  In addition, a process can have
> per-file delete access even without delete access on the parent
> directory.
> 
> Introduce two new inode_permission() mask flags and use them in
> may_delete()
> 
> Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
>  fs/namei.c         |   41 +++++++++++++++++++++++++++--------------
>  include/linux/fs.h |    2 ++
>  2 files changed, 29 insertions(+), 14 deletions(-)
> 
> diff --git a/fs/namei.c b/fs/namei.c
> index d52a4cd..eacb530 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -337,7 +337,7 @@ static inline int do_inode_permission(struct inode *inode, int mask)
>   * are used for other things.
>   *
>   * When checking for MAY_APPEND, MAY_CREATE_FILE, MAY_CREATE_DIR,
> - * MAY_WRITE must also be set in @mask.
> + * MAY_DELETE_CHILD, MAY_DELETE_SELF, MAY_WRITE must also be set in @mask.
>   */
>  int inode_permission(struct inode *inode, int mask)
>  {
> @@ -1862,7 +1862,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
>  		return 0;
>  
>  other_userns:
> -	return !ns_capable(inode_userns(inode), CAP_FOWNER);
> +	return 1;
>  }
>  
>  /*
> @@ -1884,30 +1884,43 @@ other_userns:
>   * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
>   *     nfs_async_unlink().
>   */
> -static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
> +static int may_delete(struct inode *dir, struct dentry *victim,
> +		      int isdir, int replace)
>  {
> -	int error;
> +	int mask, error, is_sticky;
> +	struct inode *inode = victim->d_inode;
>  
> -	if (!victim->d_inode)
> +	if (!inode)
>  		return -ENOENT;
>  
>  	BUG_ON(victim->d_parent->d_inode != dir);
>  	audit_inode_child(victim, dir);
>  
> -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> +	if (replace)
> +		mask |= S_ISDIR(inode->i_mode) ?
> +			MAY_CREATE_DIR : MAY_CREATE_FILE;

I'm having trouble understanding this next bit:

> +	is_sticky = check_sticky(dir, inode);
> +	error = inode_permission(dir, mask);
> +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> +	    !inode_permission(inode, MAY_DELETE_SELF))
> +		error = 0;

OK, so we can ignore the lack of write or delete permissions on the
parent if we have delete_self permissions on the child.  I guess that's
right.

Why the "|| is_sticky" above?

Is there some less complicated why to write this?

--b.

> +	else if (!error && is_sticky &&
> +		 !ns_capable(inode_userns(inode), CAP_FOWNER))
> +		error = -EPERM;
>  	if (error)
>  		return error;
>  	if (IS_APPEND(dir))
>  		return -EPERM;
> -	if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
> -	    IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
> +	if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
>  		return -EPERM;
>  	if (isdir) {
> -		if (!S_ISDIR(victim->d_inode->i_mode))
> +		if (!S_ISDIR(inode->i_mode))
>  			return -ENOTDIR;
>  		if (IS_ROOT(victim))
>  			return -EBUSY;
> -	} else if (S_ISDIR(victim->d_inode->i_mode))
> +	} else if (S_ISDIR(inode->i_mode))
>  		return -EISDIR;
>  	if (IS_DEADDIR(dir))
>  		return -ENOENT;
> @@ -2614,7 +2627,7 @@ void dentry_unhash(struct dentry *dentry)
>  
>  int vfs_rmdir(struct inode *dir, struct dentry *dentry)
>  {
> -	int error = may_delete(dir, dentry, 1);
> +	int error = may_delete(dir, dentry, 1, 0);
>  
>  	if (error)
>  		return error;
> @@ -2707,7 +2720,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
>  
>  int vfs_unlink(struct inode *dir, struct dentry *dentry)
>  {
> -	int error = may_delete(dir, dentry, 0);
> +	int error = may_delete(dir, dentry, 0, 0);
>  
>  	if (error)
>  		return error;
> @@ -3101,14 +3114,14 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
>  	if (old_dentry->d_inode == new_dentry->d_inode)
>   		return 0;
>   
> -	error = may_delete(old_dir, old_dentry, is_dir);
> +	error = may_delete(old_dir, old_dentry, is_dir, 0);
>  	if (error)
>  		return error;
>  
>  	if (!new_dentry->d_inode)
>  		error = may_create(new_dir, new_dentry, is_dir);
>  	else
> -		error = may_delete(new_dir, new_dentry, is_dir);
> +		error = may_delete(new_dir, new_dentry, is_dir, 1);
>  	if (error)
>  		return error;
>  
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 8707f43..c5c98c5 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -69,6 +69,8 @@ struct inodes_stat_t {
>  #define MAY_NOT_BLOCK		0x00000080
>  #define MAY_CREATE_FILE		0x00000100
>  #define MAY_CREATE_DIR		0x00000200
> +#define MAY_DELETE_CHILD	0x00000400
> +#define MAY_DELETE_SELF		0x00000800
>  
>  /*
>   * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
> -- 
> 1.7.4.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 10/26] vfs: Make the inode passed to inode_change_ok non-const
  2011-09-05 17:25 ` [PATCH -V6 10/26] vfs: Make the inode passed to inode_change_ok non-const Aneesh Kumar K.V
@ 2011-09-07 20:43   ` J. Bruce Fields
  2011-09-08  9:32       ` Aneesh Kumar K.V
  0 siblings, 1 reply; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 20:43 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Mon, Sep 05, 2011 at 10:55:32PM +0530, Aneesh Kumar K.V wrote:
> From: Andreas Gruenbacher <agruen@kernel.org>
> 
> We will need to call iop->permission and iop->get_acl from
> inode_change_ok() for additional permission checks, and both take a
> non-const inode.

OK, the essential difference being that richacls have a say in whether
we can change attributes or not, which posix acls (for example) don't?

--b.

> 
> Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
>  fs/attr.c          |    2 +-
>  include/linux/fs.h |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/attr.c b/fs/attr.c
> index 538e279..f15e9e3 100644
> --- a/fs/attr.c
> +++ b/fs/attr.c
> @@ -26,7 +26,7 @@
>   * Should be called as the first thing in ->setattr implementations,
>   * possibly after taking additional locks.
>   */
> -int inode_change_ok(const struct inode *inode, struct iattr *attr)
> +int inode_change_ok(struct inode *inode, struct iattr *attr)
>  {
>  	unsigned int ia_valid = attr->ia_valid;
>  
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index c5c98c5..8afb054 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2568,7 +2568,7 @@ extern int buffer_migrate_page(struct address_space *,
>  #define buffer_migrate_page NULL
>  #endif
>  
> -extern int inode_change_ok(const struct inode *, struct iattr *);
> +extern int inode_change_ok(struct inode *, struct iattr *);
>  extern int inode_newsize_ok(const struct inode *, loff_t offset);
>  extern void setattr_copy(struct inode *inode, const struct iattr *attr);
>  
> -- 
> 1.7.4.1
> 

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 11/26] vfs: Add permission flags for setting file attributes
  2011-09-05 17:25   ` Aneesh Kumar K.V
  (?)
@ 2011-09-07 20:55   ` J. Bruce Fields
  2011-09-08  9:36     ` Aneesh Kumar K.V
  -1 siblings, 1 reply; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 20:55 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Mon, Sep 05, 2011 at 10:55:33PM +0530, Aneesh Kumar K.V wrote:
> From: Andreas Gruenbacher <agruen@kernel.org>
> 
> Some permission models can allow processes to take ownership of a file,
> change the file permissions, and set the file timestamps.  Introduce new
> permission mask flags and check for those permissions in
> inode_change_ok().

These little helper functions seem like they might be reasonable cleanup
even without the richacl_change_ok() piece; wonder if it'd be worth
splitting out the cleanup and applying it now?

Not that it's necessary--seems like a straightforward enough patch as
is.

--b.

> 
> Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
>  fs/attr.c          |   70 +++++++++++++++++++++++++++++++++++++++++++--------
>  fs/namei.c         |    2 +-
>  include/linux/fs.h |    4 +++
>  3 files changed, 64 insertions(+), 12 deletions(-)
> 
> diff --git a/fs/attr.c b/fs/attr.c
> index f15e9e3..00578b9 100644
> --- a/fs/attr.c
> +++ b/fs/attr.c
> @@ -14,6 +14,55 @@
>  #include <linux/fcntl.h>
>  #include <linux/security.h>
>  
> +static int richacl_change_ok(struct inode *inode, int mask)
> +{
> +	if (!IS_RICHACL(inode))
> +		return -EPERM;
> +
> +	if (inode->i_op->permission)
> +		return inode->i_op->permission(inode, mask);
> +
> +	return check_acl(inode, mask);
> +}
> +
> +static bool inode_uid_change_ok(struct inode *inode, uid_t ia_uid)
> +{
> +	if (current_fsuid() == inode->i_uid && ia_uid == inode->i_uid)
> +		return true;
> +	if (current_fsuid() == ia_uid &&
> +	    richacl_change_ok(inode, MAY_TAKE_OWNERSHIP) == 0)
> +		return true;
> +	if (capable(CAP_CHOWN))
> +		return true;
> +	return false;
> +}
> +
> +static bool inode_gid_change_ok(struct inode *inode, gid_t ia_gid)
> +{
> +	int in_group = in_group_p(ia_gid);
> +	if (current_fsuid() == inode->i_uid &&
> +	    (in_group || ia_gid == inode->i_gid))
> +		return true;
> +	if (in_group && richacl_change_ok(inode, MAY_TAKE_OWNERSHIP) == 0)
> +		return true;
> +	if (capable(CAP_CHOWN))
> +		return true;
> +	return false;
> +}
> +
> +static bool inode_owner_permitted_or_capable(struct inode *inode, int mask)
> +{
> +	struct user_namespace *ns = inode_userns(inode);
> +
> +	if (current_user_ns() == ns && current_fsuid() == inode->i_uid)
> +		return true;
> +	if (richacl_change_ok(inode, mask) == 0)
> +		return true;
> +	if (ns_capable(ns, CAP_FOWNER))
> +		return true;
> +	return false;
> +}
> +
>  /**
>   * inode_change_ok - check if attribute changes to an inode are allowed
>   * @inode:	inode to check
> @@ -45,21 +94,20 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
>  		return 0;
>  
>  	/* Make sure a caller can chown. */
> -	if ((ia_valid & ATTR_UID) &&
> -	    (current_fsuid() != inode->i_uid ||
> -	     attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
> -		return -EPERM;
> +	if (ia_valid & ATTR_UID) {
> +		if (!inode_uid_change_ok(inode, attr->ia_uid))
> +			return -EPERM;
> +	}
>  
>  	/* Make sure caller can chgrp. */
> -	if ((ia_valid & ATTR_GID) &&
> -	    (current_fsuid() != inode->i_uid ||
> -	    (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
> -	    !capable(CAP_CHOWN))
> -		return -EPERM;
> +	if (ia_valid & ATTR_GID) {
> +		if (!inode_gid_change_ok(inode, attr->ia_gid))
> +			return -EPERM;
> +	}
>  
>  	/* Make sure a caller can chmod. */
>  	if (ia_valid & ATTR_MODE) {
> -		if (!inode_owner_or_capable(inode))
> +		if (!inode_owner_permitted_or_capable(inode, MAY_CHMOD))
>  			return -EPERM;
>  		/* Also check the setgid bit! */
>  		if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
> @@ -69,7 +117,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
>  
>  	/* Check for setting the inode time. */
>  	if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
> -		if (!inode_owner_or_capable(inode))
> +		if (!inode_owner_permitted_or_capable(inode, MAY_SET_TIMES))
>  			return -EPERM;
>  	}
>  
> diff --git a/fs/namei.c b/fs/namei.c
> index eacb530..a4d61d1 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -174,7 +174,7 @@ void putname(const char *name)
>  EXPORT_SYMBOL(putname);
>  #endif
>  
> -static int check_acl(struct inode *inode, int mask)
> +int check_acl(struct inode *inode, int mask)
>  {
>  #ifdef CONFIG_FS_POSIX_ACL
>  	struct posix_acl *acl;
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 8afb054..8d5d6e4 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -71,6 +71,9 @@ struct inodes_stat_t {
>  #define MAY_CREATE_DIR		0x00000200
>  #define MAY_DELETE_CHILD	0x00000400
>  #define MAY_DELETE_SELF		0x00000800
> +#define MAY_TAKE_OWNERSHIP	0x00001000
> +#define MAY_CHMOD		0x00002000
> +#define MAY_SET_TIMES		0x00004000
>  
>  /*
>   * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
> @@ -2234,6 +2237,7 @@ extern sector_t bmap(struct inode *, sector_t);
>  extern int notify_change(struct dentry *, struct iattr *);
>  extern int inode_permission(struct inode *, int);
>  extern int generic_permission(struct inode *, int);
> +extern int check_acl(struct inode *, int);
>  
>  static inline bool execute_ok(struct inode *inode)
>  {
> -- 
> 1.7.4.1
> 

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 14/26] richacl: Permission mapping functions
  2011-09-05 17:25   ` Aneesh Kumar K.V
  (?)
@ 2011-09-07 21:24   ` J. Bruce Fields
  2011-09-08 10:27     ` Aneesh Kumar K.V
  -1 siblings, 1 reply; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 21:24 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Mon, Sep 05, 2011 at 10:55:36PM +0530, Aneesh Kumar K.V wrote:
> From: Andreas Gruenbacher <agruen@kernel.org>
> 
> We need to map from POSIX permissions to NFSv4 permissions when a
> chmod() is done, from NFSv4 permissions to POSIX permissions when an acl
> is set (which implicitly sets the file permission bits), and from the
> MAY_READ/MAY_WRITE/MAY_EXEC/MAY_APPEND flags to NFSv4 permissions when
> doing an access check in a richacl.
> 
> Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
>  fs/richacl_base.c       |  118 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/richacl.h |   46 ++++++++++++++++++
>  2 files changed, 164 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/richacl_base.c b/fs/richacl_base.c
> index 3536626..d55b436 100644
> --- a/fs/richacl_base.c
> +++ b/fs/richacl_base.c
> @@ -69,6 +69,124 @@ richacl_clone(const struct richacl *acl)
>  }
>  
>  /**
> + * richacl_mask_to_mode  -  compute the file permission bits which correspond to @mask
> + * @mask:	%ACE4_* permission mask
> + *
> + * See richacl_masks_to_mode().
> + */
> +static int
> +richacl_mask_to_mode(unsigned int mask)
> +{
> +	int mode = 0;
> +
> +	if (mask & ACE4_POSIX_MODE_READ)
> +		mode |= MAY_READ;
> +	if (mask & ACE4_POSIX_MODE_WRITE)
> +		mode |= MAY_WRITE;
> +	if (mask & ACE4_POSIX_MODE_EXEC)
> +		mode |= MAY_EXEC;
> +
> +	return mode;
> +}
> +
> +/**
> + * richacl_masks_to_mode  -  compute the file permission bits from the file masks
> + *
> + * When setting a richacl, we set the file permission bits to indicate maximum
> + * permissions: for example, we set the Write permission when a mask contains
> + * ACE4_APPEND_DATA even if it does not also contain ACE4_WRITE_DATA.
> + *
> + * Permissions which are not in ACE4_POSIX_MODE_READ, ACE4_POSIX_MODE_WRITE, or
> + * ACE4_POSIX_MODE_EXEC cannot be represented in the file permission bits.
> + * Such permissions can still be effective, but not for new files or after a
> + * chmod(), and only if they were set explicitly, for example, by setting a
> + * richacl.
> + */
> +int
> +richacl_masks_to_mode(const struct richacl *acl)
> +{
> +	return richacl_mask_to_mode(acl->a_owner_mask) << 6 |
> +	       richacl_mask_to_mode(acl->a_group_mask) << 3 |
> +	       richacl_mask_to_mode(acl->a_other_mask);
> +}
> +EXPORT_SYMBOL_GPL(richacl_masks_to_mode);
> +
> +/**
> + * richacl_mode_to_mask  - compute a file mask from the lowest three mode bits
> + *
> + * When the file permission bits of a file are set with chmod(), this specifies
> + * the maximum permissions that processes will get.  All permissions beyond
> + * that will be removed from the file masks, and become ineffective.
> + *
> + * We also add in the permissions which are always allowed no matter what the
> + * acl says.
> + */
> +unsigned int
> +richacl_mode_to_mask(mode_t mode)
> +{
> +	unsigned int mask = ACE4_POSIX_ALWAYS_ALLOWED;
> +
> +	if (mode & MAY_READ)
> +		mask |= ACE4_POSIX_MODE_READ;
> +	if (mode & MAY_WRITE)
> +		mask |= ACE4_POSIX_MODE_WRITE;
> +	if (mode & MAY_EXEC)
> +		mask |= ACE4_POSIX_MODE_EXEC;
> +
> +	return mask;
> +}
> +
> +/**
> + * richacl_want_to_mask  - convert the iop->permission want argument to a mask
> + * @want:	@want argument of the permission inode operation
> + *
> + * When checking for append, @want is (MAY_WRITE | MAY_APPEND).
> + *
> + * Richacls use the iop->may_create and iop->may_delete hooks which are
> + * used for checking if creating and deleting files is allowed.  These hooks do
> + * not use richacl_want_to_mask(), so we do not have to deal with mapping
> + * MAY_WRITE to ACE4_ADD_FILE, ACE4_ADD_SUBDIRECTORY, and ACE4_DELETE_CHILD
> + * here.
> + */
> +unsigned int
> +richacl_want_to_mask(int want)
> +{
> +	unsigned int mask = 0;
> +
> +	if (want & MAY_READ)
> +		mask |= ACE4_READ_DATA;
> +	if (want & (MAY_APPEND |
> +		    MAY_CREATE_FILE | MAY_CREATE_DIR |
> +		    MAY_DELETE_CHILD | MAY_DELETE_SELF |
> +		    MAY_TAKE_OWNERSHIP | MAY_CHMOD | MAY_SET_TIMES)) {
> +		if (want & MAY_APPEND)
> +			mask |= ACE4_APPEND_DATA;
> +		else if (want & MAY_DELETE_SELF)
> +			mask |= ACE4_DELETE;
> +		else if (want & MAY_TAKE_OWNERSHIP)
> +			mask |= ACE4_WRITE_OWNER;
> +		else if (want & MAY_CHMOD)
> +			mask |= ACE4_WRITE_ACL;
> +		else if (want & MAY_SET_TIMES)
> +			mask |= ACE4_WRITE_ATTRIBUTES;
> +		else {
> +			if (want & MAY_CREATE_FILE)
> +				mask |= ACE4_ADD_FILE;
> +			if (want & MAY_CREATE_DIR)
> +				mask |= ACE4_ADD_SUBDIRECTORY;
> +			if (want & MAY_DELETE_CHILD)
> +				mask |= ACE4_DELETE_CHILD;
> +		}

Possibly dumb question: why isn't this whole function a simple series of
if's, one for each MAY_ bit?

I guess you're using knowledge about the callers to know that, for
example, no one will ask for MAY_APPEND and MAY_TAKE_OWNERSHIP at the
same time?

And adding that big "if (want & (MAY_APPEND | .. | MAY_SET_TIMES))" to
let you skip over a bunch of checks in the common case?

Does this help measurably?  It seems complicated and, to the extent it
makes assumptions about the callers, possibly fragile with respect to
future changes.

--b.

> +	} else if (want & MAY_WRITE)
> +		mask |= ACE4_WRITE_DATA;
> +	if (want & MAY_EXEC)
> +		mask |= ACE4_EXECUTE;
> +
> +	return mask;
> +}
> +EXPORT_SYMBOL_GPL(richacl_want_to_mask);
> +
> +/**
>   * richace_is_same_identifier  -  are both identifiers the same?
>   */
>  int
> diff --git a/include/linux/richacl.h b/include/linux/richacl.h
> index 745cfc1..7433ba3 100644
> --- a/include/linux/richacl.h
> +++ b/include/linux/richacl.h
> @@ -117,6 +117,49 @@ struct richacl {
>  	ACE4_WRITE_OWNER |				\
>  	ACE4_SYNCHRONIZE)
>  
> +/*
> + * The POSIX permissions are supersets of the following NFSv4 permissions:
> + *
> + *  - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type
> + *    of the file system object.
> + *
> + *  - MAY_WRITE maps to WRITE_DATA or ACE4_APPEND_DATA for files, and to
> + *    ADD_FILE, ACE4_ADD_SUBDIRECTORY, or ACE4_DELETE_CHILD for directories.
> + *
> + *  - MAY_EXECUTE maps to ACE4_EXECUTE.
> + *
> + *  (Some of these NFSv4 permissions have the same bit values.)
> + */
> +#define ACE4_POSIX_MODE_READ (			\
> +		ACE4_READ_DATA |		\
> +		ACE4_LIST_DIRECTORY)
> +#define ACE4_POSIX_MODE_WRITE (			\
> +		ACE4_WRITE_DATA |		\
> +		ACE4_ADD_FILE |			\
> +		ACE4_APPEND_DATA |		\
> +		ACE4_ADD_SUBDIRECTORY |		\
> +		ACE4_DELETE_CHILD)
> +#define ACE4_POSIX_MODE_EXEC ACE4_EXECUTE
> +#define ACE4_POSIX_MODE_ALL (			\
> +		ACE4_POSIX_MODE_READ |		\
> +		ACE4_POSIX_MODE_WRITE |		\
> +		ACE4_POSIX_MODE_EXEC)
> +/*
> + * These permissions are always allowed
> + * no matter what the acl says.
> + */
> +#define ACE4_POSIX_ALWAYS_ALLOWED (	\
> +		ACE4_SYNCHRONIZE |	\
> +		ACE4_READ_ATTRIBUTES |	\
> +		ACE4_READ_ACL)
> +/*
> + * The owner is implicitly granted
> + * these permissions under POSIX.
> + */
> +#define ACE4_POSIX_OWNER_ALLOWED (		\
> +		ACE4_WRITE_ATTRIBUTES |		\
> +		ACE4_WRITE_OWNER |		\
> +		ACE4_WRITE_ACL)
>  /**
>   * richacl_get  -  grab another reference to a richacl handle
>   */
> @@ -241,5 +284,8 @@ extern struct richacl *richacl_alloc(int);
>  extern int richace_is_same_identifier(const struct richace *,
>  				      const struct richace *);
>  extern int richace_set_who(struct richace *, const char *);
> +extern int richacl_masks_to_mode(const struct richacl *);
> +extern unsigned int richacl_mode_to_mask(mode_t);
> +extern unsigned int richacl_want_to_mask(int);
>  
>  #endif /* __RICHACL_H */
> -- 
> 1.7.4.1
> 

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 17/26] richacl: Permission check algorithm
@ 2011-09-07 21:50     ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 21:50 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Mon, Sep 05, 2011 at 10:55:39PM +0530, Aneesh Kumar K.V wrote:
> From: Andreas Gruenbacher <agruen@kernel.org>
> 
> As in the standard POSIX file permission model, each process is the
> owner, group, or other file class.  A process is
> 
>   - in the owner file class if it owns the file,
>   - in the group file class if it is in the file's owning group or it
>     matches any of the user or group entries, and
>   - in the other file class otherwise.
> 
> Each file class is associated with a file mask.
> 
> A richacl grants a requested access if the NFSv4 acl in the richacl
> grants the requested permissions (according to the NFSv4 permission
> check algorithm) and the file mask that applies to the process includes
> the requested permissions.

I assume that by default any ui normally recalculates an upper-bound
mask automatically when you add an ace, as the posix setfacl does, so
the user doesn't have to think about masks too much?

Patch looks right.

--b.

> 
> Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
>  fs/richacl_base.c       |   99 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/richacl.h |    2 +
>  2 files changed, 101 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/richacl_base.c b/fs/richacl_base.c
> index 60a65d7..1f885ad 100644
> --- a/fs/richacl_base.c
> +++ b/fs/richacl_base.c
> @@ -393,3 +393,102 @@ richacl_chmod(struct richacl *acl, mode_t mode)
>  	return clone;
>  }
>  EXPORT_SYMBOL_GPL(richacl_chmod);
> +
> +/**
> + * richacl_permission  -  richacl permission check algorithm
> + * @inode:	inode to check
> + * @acl:	rich acl of the inode
> + * @mask:	requested access (ACE4_* bitmask)
> + *
> + * Checks if the current process is granted @mask flags in @acl.
> + */
> +int
> +richacl_permission(struct inode *inode, const struct richacl *acl,
> +		   unsigned int mask)
> +{
> +	const struct richace *ace;
> +	unsigned int requested = mask, denied = 0;
> +	int in_owning_group = in_group_p(inode->i_gid);
> +	int in_owner_or_group_class = in_owning_group;
> +
> +	/*
> +	 * We don't need to know which class the process is in when the acl is
> +	 * not masked.
> +	 */
> +	if (!(acl->a_flags & ACL4_MASKED))
> +		in_owner_or_group_class = 1;
> +
> +	/*
> +	 * A process is
> +	 *   - in the owner file class if it owns the file,
> +	 *   - in the group file class if it is in the file's owning group or
> +	 *     it matches any of the user or group entries, and
> +	 *   - in the other file class otherwise.
> +	 */
> +
> +	/*
> +	 * Check if the acl grants the requested access and determine which
> +	 * file class the process is in.
> +	 */
> +	richacl_for_each_entry(ace, acl) {
> +		unsigned int ace_mask = ace->e_mask;
> +
> +		if (richace_is_inherit_only(ace))
> +			continue;
> +		if (richace_is_owner(ace)) {
> +			if (current_fsuid() != inode->i_uid)
> +				continue;
> +			goto is_owner;
> +		} else if (richace_is_group(ace)) {
> +			if (!in_owning_group)
> +				continue;
> +		} else if (richace_is_unix_id(ace)) {
> +			if (ace->e_flags & ACE4_IDENTIFIER_GROUP) {
> +				if (!in_group_p(ace->u.e_id))
> +					continue;
> +			} else {
> +				if (current_fsuid() != ace->u.e_id)
> +					continue;
> +			}
> +		} else
> +			goto is_everyone;
> +
> +is_owner:
> +		/* The process is in the owner or group file class. */
> +		in_owner_or_group_class = 1;
> +
> +is_everyone:
> +		/* Check which mask flags the ACE allows or denies. */
> +		if (richace_is_deny(ace))
> +			denied |= ace_mask & mask;
> +		mask &= ~ace_mask;
> +
> +		/*
> +		 * Keep going until we know which file class
> +		 * the process is in.
> +		 */
> +		if (!mask && in_owner_or_group_class)
> +			break;
> +	}
> +	denied |= mask;
> +
> +	if (acl->a_flags & ACL4_MASKED) {
> +		unsigned int file_mask;
> +
> +		/*
> +		 * The file class a process is in determines which file mask
> +		 * applies.  Check if that file mask also grants the requested
> +		 * access.
> +		 */
> +		if (current_fsuid() == inode->i_uid)
> +			file_mask = acl->a_owner_mask;
> +		else if (in_owner_or_group_class)
> +			file_mask = acl->a_group_mask;
> +		else
> +			file_mask = acl->a_other_mask;
> +		denied |= requested & ~file_mask;
> +	}
> +
> +	return denied ? -EACCES : 0;
> +}
> +EXPORT_SYMBOL_GPL(richacl_permission);
> diff --git a/include/linux/richacl.h b/include/linux/richacl.h
> index 6dd8eb2..f46e797 100644
> --- a/include/linux/richacl.h
> +++ b/include/linux/richacl.h
> @@ -289,5 +289,7 @@ extern unsigned int richacl_mode_to_mask(mode_t);
>  extern unsigned int richacl_want_to_mask(int);
>  extern void richacl_compute_max_masks(struct richacl *);
>  extern struct richacl *richacl_chmod(struct richacl *, mode_t);
> +extern int richacl_permission(struct inode *, const struct richacl *,
> +			      unsigned int);
>  
>  #endif /* __RICHACL_H */
> -- 
> 1.7.4.1
> 

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 17/26] richacl: Permission check algorithm
@ 2011-09-07 21:50     ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 21:50 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Mon, Sep 05, 2011 at 10:55:39PM +0530, Aneesh Kumar K.V wrote:
> From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> 
> As in the standard POSIX file permission model, each process is the
> owner, group, or other file class.  A process is
> 
>   - in the owner file class if it owns the file,
>   - in the group file class if it is in the file's owning group or it
>     matches any of the user or group entries, and
>   - in the other file class otherwise.
> 
> Each file class is associated with a file mask.
> 
> A richacl grants a requested access if the NFSv4 acl in the richacl
> grants the requested permissions (according to the NFSv4 permission
> check algorithm) and the file mask that applies to the process includes
> the requested permissions.

I assume that by default any ui normally recalculates an upper-bound
mask automatically when you add an ace, as the posix setfacl does, so
the user doesn't have to think about masks too much?

Patch looks right.

--b.

> 
> Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
>  fs/richacl_base.c       |   99 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/richacl.h |    2 +
>  2 files changed, 101 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/richacl_base.c b/fs/richacl_base.c
> index 60a65d7..1f885ad 100644
> --- a/fs/richacl_base.c
> +++ b/fs/richacl_base.c
> @@ -393,3 +393,102 @@ richacl_chmod(struct richacl *acl, mode_t mode)
>  	return clone;
>  }
>  EXPORT_SYMBOL_GPL(richacl_chmod);
> +
> +/**
> + * richacl_permission  -  richacl permission check algorithm
> + * @inode:	inode to check
> + * @acl:	rich acl of the inode
> + * @mask:	requested access (ACE4_* bitmask)
> + *
> + * Checks if the current process is granted @mask flags in @acl.
> + */
> +int
> +richacl_permission(struct inode *inode, const struct richacl *acl,
> +		   unsigned int mask)
> +{
> +	const struct richace *ace;
> +	unsigned int requested = mask, denied = 0;
> +	int in_owning_group = in_group_p(inode->i_gid);
> +	int in_owner_or_group_class = in_owning_group;
> +
> +	/*
> +	 * We don't need to know which class the process is in when the acl is
> +	 * not masked.
> +	 */
> +	if (!(acl->a_flags & ACL4_MASKED))
> +		in_owner_or_group_class = 1;
> +
> +	/*
> +	 * A process is
> +	 *   - in the owner file class if it owns the file,
> +	 *   - in the group file class if it is in the file's owning group or
> +	 *     it matches any of the user or group entries, and
> +	 *   - in the other file class otherwise.
> +	 */
> +
> +	/*
> +	 * Check if the acl grants the requested access and determine which
> +	 * file class the process is in.
> +	 */
> +	richacl_for_each_entry(ace, acl) {
> +		unsigned int ace_mask = ace->e_mask;
> +
> +		if (richace_is_inherit_only(ace))
> +			continue;
> +		if (richace_is_owner(ace)) {
> +			if (current_fsuid() != inode->i_uid)
> +				continue;
> +			goto is_owner;
> +		} else if (richace_is_group(ace)) {
> +			if (!in_owning_group)
> +				continue;
> +		} else if (richace_is_unix_id(ace)) {
> +			if (ace->e_flags & ACE4_IDENTIFIER_GROUP) {
> +				if (!in_group_p(ace->u.e_id))
> +					continue;
> +			} else {
> +				if (current_fsuid() != ace->u.e_id)
> +					continue;
> +			}
> +		} else
> +			goto is_everyone;
> +
> +is_owner:
> +		/* The process is in the owner or group file class. */
> +		in_owner_or_group_class = 1;
> +
> +is_everyone:
> +		/* Check which mask flags the ACE allows or denies. */
> +		if (richace_is_deny(ace))
> +			denied |= ace_mask & mask;
> +		mask &= ~ace_mask;
> +
> +		/*
> +		 * Keep going until we know which file class
> +		 * the process is in.
> +		 */
> +		if (!mask && in_owner_or_group_class)
> +			break;
> +	}
> +	denied |= mask;
> +
> +	if (acl->a_flags & ACL4_MASKED) {
> +		unsigned int file_mask;
> +
> +		/*
> +		 * The file class a process is in determines which file mask
> +		 * applies.  Check if that file mask also grants the requested
> +		 * access.
> +		 */
> +		if (current_fsuid() == inode->i_uid)
> +			file_mask = acl->a_owner_mask;
> +		else if (in_owner_or_group_class)
> +			file_mask = acl->a_group_mask;
> +		else
> +			file_mask = acl->a_other_mask;
> +		denied |= requested & ~file_mask;
> +	}
> +
> +	return denied ? -EACCES : 0;
> +}
> +EXPORT_SYMBOL_GPL(richacl_permission);
> diff --git a/include/linux/richacl.h b/include/linux/richacl.h
> index 6dd8eb2..f46e797 100644
> --- a/include/linux/richacl.h
> +++ b/include/linux/richacl.h
> @@ -289,5 +289,7 @@ extern unsigned int richacl_mode_to_mask(mode_t);
>  extern unsigned int richacl_want_to_mask(int);
>  extern void richacl_compute_max_masks(struct richacl *);
>  extern struct richacl *richacl_chmod(struct richacl *, mode_t);
> +extern int richacl_permission(struct inode *, const struct richacl *,
> +			      unsigned int);
>  
>  #endif /* __RICHACL_H */
> -- 
> 1.7.4.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 20/26] richacl: Automatic Inheritance
@ 2011-09-07 21:56     ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 21:56 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Mon, Sep 05, 2011 at 10:55:42PM +0530, Aneesh Kumar K.V wrote:
> From: Andreas Gruenbacher <agruen@kernel.org>
> 
> Automatic Inheritance (AI) allows changes to the acl of a directory to
> recursively propagate down to files and directories in the directory.
> 
> To implement this, the kernel keeps track of which permissions have been
> inherited, and makes sure that permission propagation is turned off when
> the file permission bits of a file are changed (upon create or chmod).
> 
> The actual permission propagation is implemented in user space.
> 
> AI works as follows:
> 
>  - When the ACL4_AUTO_INHERIT flag in the acl of a file is cleared, the
>    file is not affected by AI.
> 
>  - When the ACL4_AUTO_INHERIT flag in the acl of a directory is set and
>    a file or subdirectory is created in that directory, files created in
>    the directory will have the ACL4_AUTO_INHERIT flag set, and all
>    inherited aces will have the ACE4_INHERITED_ACE flag set.  This
>    allows user space to distinguish between aces which have been
>    inherited, and aces which have been explicitly added.
> 
>  - When the ACL4_PROTECTED acl flag in the acl of a file is set, AI will
>    not modify the acl of the file.  This does not affect propagation of
>    permissions from the file to its children (if the file is a
>    directory).
> 
> Linux does not have a way of creating files without setting the file
> permission bits, so all files created inside a directory with
> ACL4_AUTO_INHERIT set will also have the ACL4_PROTECTED flag set.  This
> effectively disables AI.
> 
> Protocols which support creating files without specifying permissions
> can explicitly clear the ACL4_PROTECTED flag after creating a file (and
> reset the file masks to "undo" applying the create mode; see
> richacl_compute_max_masks()).  This is a workaround;

and sort of racy, I guess.

> a per-create or
> per-process flag indicating to ignore the create mode when AI is in
> effect would fix this problem.

Hm.  OK.

--b.

> 
> Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
>  fs/richacl_base.c       |   10 +++++++++-
>  fs/richacl_inode.c      |    7 ++++++-
>  include/linux/richacl.h |   25 +++++++++++++++++++++++--
>  3 files changed, 38 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/richacl_base.c b/fs/richacl_base.c
> index 9d61c34..2cdc244 100644
> --- a/fs/richacl_base.c
> +++ b/fs/richacl_base.c
> @@ -377,7 +377,8 @@ richacl_chmod(struct richacl *acl, mode_t mode)
>  	if (acl->a_owner_mask == owner_mask &&
>  	    acl->a_group_mask == group_mask &&
>  	    acl->a_other_mask == other_mask &&
> -	    (acl->a_flags & ACL4_MASKED))
> +	    (acl->a_flags & ACL4_MASKED) &&
> +	    (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl)))
>  		return acl;
>  
>  	clone = richacl_clone(acl);
> @@ -389,6 +390,8 @@ richacl_chmod(struct richacl *acl, mode_t mode)
>  	clone->a_owner_mask = owner_mask;
>  	clone->a_group_mask = group_mask;
>  	clone->a_other_mask = other_mask;
> +	if (richacl_is_auto_inherit(clone))
> +		clone->a_flags |= ACL4_PROTECTED;
>  
>  	return clone;
>  }
> @@ -558,6 +561,11 @@ richacl_inherit(const struct richacl *dir_acl, int isdir)
>  			ace++;
>  		}
>  	}
> +	if (richacl_is_auto_inherit(dir_acl)) {
> +		acl->a_flags = ACL4_AUTO_INHERIT;
> +		richacl_for_each_entry(ace, acl)
> +			ace->e_flags |= ACE4_INHERITED_ACE;
> +	}
>  
>  	return acl;
>  }
> diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c
> index a8d2beb..be6c3eb 100644
> --- a/fs/richacl_inode.c
> +++ b/fs/richacl_inode.c
> @@ -37,9 +37,14 @@ richacl_inherit_inode(const struct richacl *dir_acl, struct inode *inode)
>  
>  	acl = richacl_inherit(dir_acl, S_ISDIR(inode->i_mode));
>  	if (acl) {
> +		/*
> +		 * We need to set ACL4_PROTECTED because we are
> +		 * doing an implicit chmod
> +		 */
> +		if (richacl_is_auto_inherit(acl))
> +			acl->a_flags |= ACL4_PROTECTED;
>  
>  		richacl_compute_max_masks(acl);
> -
>  		/*
>  		 * Ensure that the acl will not grant any permissions beyond
>  		 * the create mode.
> diff --git a/include/linux/richacl.h b/include/linux/richacl.h
> index d18c4a6..ca07209 100644
> --- a/include/linux/richacl.h
> +++ b/include/linux/richacl.h
> @@ -47,10 +47,16 @@ struct richacl {
>  	     _ace != _acl->a_entries - 1; \
>  	     _ace--)
>  
> +/* a_flags values */
> +#define ACL4_AUTO_INHERIT		0x01
> +#define ACL4_PROTECTED			0x02
> +/* #define ACL4_DEFAULTED			0x04 */
>  /* Flag values defined by rich-acl */
>  #define ACL4_MASKED			0x80
>  
>  #define ACL4_VALID_FLAGS (			\
> +		ACL4_AUTO_INHERIT |		\
> +		ACL4_PROTECTED |		\
>  		ACL4_MASKED)
>  
>  /* e_type values */
> @@ -67,6 +73,7 @@ struct richacl {
>  /*#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG	0x0010*/
>  /*#define ACE4_FAILED_ACCESS_ACE_FLAG	0x0020*/
>  #define ACE4_IDENTIFIER_GROUP		0x0040
> +#define ACE4_INHERITED_ACE		0x0080
>  /* in-memory representation only */
>  #define ACE4_SPECIAL_WHO		0x4000
>  
> @@ -75,7 +82,8 @@ struct richacl {
>  	ACE4_DIRECTORY_INHERIT_ACE |		\
>  	ACE4_NO_PROPAGATE_INHERIT_ACE |		\
>  	ACE4_INHERIT_ONLY_ACE |			\
> -	ACE4_IDENTIFIER_GROUP)
> +	ACE4_IDENTIFIER_GROUP |			\
> +	ACE4_INHERITED_ACE)
>  
>  /* e_mask bitflags */
>  #define ACE4_READ_DATA			0x00000001
> @@ -181,6 +189,18 @@ richacl_put(struct richacl *acl)
>  		kfree(acl);
>  }
>  
> +static inline int
> +richacl_is_auto_inherit(const struct richacl *acl)
> +{
> +	return acl->a_flags & ACL4_AUTO_INHERIT;
> +}
> +
> +static inline int
> +richacl_is_protected(const struct richacl *acl)
> +{
> +	return acl->a_flags & ACL4_PROTECTED;
> +}
> +
>  /*
>   * Special e_who identifiers: we use these pointer values in comparisons
>   * instead of doing a strcmp.
> @@ -259,7 +279,8 @@ richace_clear_inheritance_flags(struct richace *ace)
>  	ace->e_flags &= ~(ACE4_FILE_INHERIT_ACE |
>  			  ACE4_DIRECTORY_INHERIT_ACE |
>  			  ACE4_NO_PROPAGATE_INHERIT_ACE |
> -			  ACE4_INHERIT_ONLY_ACE);
> +			  ACE4_INHERIT_ONLY_ACE |
> +			  ACE4_INHERITED_ACE);
>  }
>  
>  /**
> -- 
> 1.7.4.1
> 

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 20/26] richacl: Automatic Inheritance
@ 2011-09-07 21:56     ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 21:56 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Mon, Sep 05, 2011 at 10:55:42PM +0530, Aneesh Kumar K.V wrote:
> From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> 
> Automatic Inheritance (AI) allows changes to the acl of a directory to
> recursively propagate down to files and directories in the directory.
> 
> To implement this, the kernel keeps track of which permissions have been
> inherited, and makes sure that permission propagation is turned off when
> the file permission bits of a file are changed (upon create or chmod).
> 
> The actual permission propagation is implemented in user space.
> 
> AI works as follows:
> 
>  - When the ACL4_AUTO_INHERIT flag in the acl of a file is cleared, the
>    file is not affected by AI.
> 
>  - When the ACL4_AUTO_INHERIT flag in the acl of a directory is set and
>    a file or subdirectory is created in that directory, files created in
>    the directory will have the ACL4_AUTO_INHERIT flag set, and all
>    inherited aces will have the ACE4_INHERITED_ACE flag set.  This
>    allows user space to distinguish between aces which have been
>    inherited, and aces which have been explicitly added.
> 
>  - When the ACL4_PROTECTED acl flag in the acl of a file is set, AI will
>    not modify the acl of the file.  This does not affect propagation of
>    permissions from the file to its children (if the file is a
>    directory).
> 
> Linux does not have a way of creating files without setting the file
> permission bits, so all files created inside a directory with
> ACL4_AUTO_INHERIT set will also have the ACL4_PROTECTED flag set.  This
> effectively disables AI.
> 
> Protocols which support creating files without specifying permissions
> can explicitly clear the ACL4_PROTECTED flag after creating a file (and
> reset the file masks to "undo" applying the create mode; see
> richacl_compute_max_masks()).  This is a workaround;

and sort of racy, I guess.

> a per-create or
> per-process flag indicating to ignore the create mode when AI is in
> effect would fix this problem.

Hm.  OK.

--b.

> 
> Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
>  fs/richacl_base.c       |   10 +++++++++-
>  fs/richacl_inode.c      |    7 ++++++-
>  include/linux/richacl.h |   25 +++++++++++++++++++++++--
>  3 files changed, 38 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/richacl_base.c b/fs/richacl_base.c
> index 9d61c34..2cdc244 100644
> --- a/fs/richacl_base.c
> +++ b/fs/richacl_base.c
> @@ -377,7 +377,8 @@ richacl_chmod(struct richacl *acl, mode_t mode)
>  	if (acl->a_owner_mask == owner_mask &&
>  	    acl->a_group_mask == group_mask &&
>  	    acl->a_other_mask == other_mask &&
> -	    (acl->a_flags & ACL4_MASKED))
> +	    (acl->a_flags & ACL4_MASKED) &&
> +	    (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl)))
>  		return acl;
>  
>  	clone = richacl_clone(acl);
> @@ -389,6 +390,8 @@ richacl_chmod(struct richacl *acl, mode_t mode)
>  	clone->a_owner_mask = owner_mask;
>  	clone->a_group_mask = group_mask;
>  	clone->a_other_mask = other_mask;
> +	if (richacl_is_auto_inherit(clone))
> +		clone->a_flags |= ACL4_PROTECTED;
>  
>  	return clone;
>  }
> @@ -558,6 +561,11 @@ richacl_inherit(const struct richacl *dir_acl, int isdir)
>  			ace++;
>  		}
>  	}
> +	if (richacl_is_auto_inherit(dir_acl)) {
> +		acl->a_flags = ACL4_AUTO_INHERIT;
> +		richacl_for_each_entry(ace, acl)
> +			ace->e_flags |= ACE4_INHERITED_ACE;
> +	}
>  
>  	return acl;
>  }
> diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c
> index a8d2beb..be6c3eb 100644
> --- a/fs/richacl_inode.c
> +++ b/fs/richacl_inode.c
> @@ -37,9 +37,14 @@ richacl_inherit_inode(const struct richacl *dir_acl, struct inode *inode)
>  
>  	acl = richacl_inherit(dir_acl, S_ISDIR(inode->i_mode));
>  	if (acl) {
> +		/*
> +		 * We need to set ACL4_PROTECTED because we are
> +		 * doing an implicit chmod
> +		 */
> +		if (richacl_is_auto_inherit(acl))
> +			acl->a_flags |= ACL4_PROTECTED;
>  
>  		richacl_compute_max_masks(acl);
> -
>  		/*
>  		 * Ensure that the acl will not grant any permissions beyond
>  		 * the create mode.
> diff --git a/include/linux/richacl.h b/include/linux/richacl.h
> index d18c4a6..ca07209 100644
> --- a/include/linux/richacl.h
> +++ b/include/linux/richacl.h
> @@ -47,10 +47,16 @@ struct richacl {
>  	     _ace != _acl->a_entries - 1; \
>  	     _ace--)
>  
> +/* a_flags values */
> +#define ACL4_AUTO_INHERIT		0x01
> +#define ACL4_PROTECTED			0x02
> +/* #define ACL4_DEFAULTED			0x04 */
>  /* Flag values defined by rich-acl */
>  #define ACL4_MASKED			0x80
>  
>  #define ACL4_VALID_FLAGS (			\
> +		ACL4_AUTO_INHERIT |		\
> +		ACL4_PROTECTED |		\
>  		ACL4_MASKED)
>  
>  /* e_type values */
> @@ -67,6 +73,7 @@ struct richacl {
>  /*#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG	0x0010*/
>  /*#define ACE4_FAILED_ACCESS_ACE_FLAG	0x0020*/
>  #define ACE4_IDENTIFIER_GROUP		0x0040
> +#define ACE4_INHERITED_ACE		0x0080
>  /* in-memory representation only */
>  #define ACE4_SPECIAL_WHO		0x4000
>  
> @@ -75,7 +82,8 @@ struct richacl {
>  	ACE4_DIRECTORY_INHERIT_ACE |		\
>  	ACE4_NO_PROPAGATE_INHERIT_ACE |		\
>  	ACE4_INHERIT_ONLY_ACE |			\
> -	ACE4_IDENTIFIER_GROUP)
> +	ACE4_IDENTIFIER_GROUP |			\
> +	ACE4_INHERITED_ACE)
>  
>  /* e_mask bitflags */
>  #define ACE4_READ_DATA			0x00000001
> @@ -181,6 +189,18 @@ richacl_put(struct richacl *acl)
>  		kfree(acl);
>  }
>  
> +static inline int
> +richacl_is_auto_inherit(const struct richacl *acl)
> +{
> +	return acl->a_flags & ACL4_AUTO_INHERIT;
> +}
> +
> +static inline int
> +richacl_is_protected(const struct richacl *acl)
> +{
> +	return acl->a_flags & ACL4_PROTECTED;
> +}
> +
>  /*
>   * Special e_who identifiers: we use these pointer values in comparisons
>   * instead of doing a strcmp.
> @@ -259,7 +279,8 @@ richace_clear_inheritance_flags(struct richace *ace)
>  	ace->e_flags &= ~(ACE4_FILE_INHERIT_ACE |
>  			  ACE4_DIRECTORY_INHERIT_ACE |
>  			  ACE4_NO_PROPAGATE_INHERIT_ACE |
> -			  ACE4_INHERIT_ONLY_ACE);
> +			  ACE4_INHERIT_ONLY_ACE |
> +			  ACE4_INHERITED_ACE);
>  }
>  
>  /**
> -- 
> 1.7.4.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (27 preceding siblings ...)
  2011-09-06  9:41 ` Steven Whitehouse
@ 2011-09-07 23:44 ` J. Bruce Fields
  2011-09-08 10:40     ` Aneesh Kumar K.V
  2011-09-09 10:02 ` [PATCH -V6 08/26] vfs: Add new file and directory create permission flags David Howells
                   ` (8 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-07 23:44 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel,
	Jeremy Allison

On Mon, Sep 05, 2011 at 10:55:22PM +0530, Aneesh Kumar K.V wrote:
> Hi,
> 
> The following set of patches implements VFS and ext4 changes needed to implement
> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> extended by file masks to fit into the standard POSIX file permission model.
> They are designed to work seamlessly locally as well as across the NFSv4 and
> CIFS/SMB2 network file system protocols.

The posix acl mapping that samba and nfsd currently have to do is
painful for everyone and I'm delighted to get away from it.

My main remaining worry (besides the fact that cifs/v4 acls are too
complicated--but what can we do about that?)--is about how exactly the
(acl, mask)->acl mapping is going to work for nfsd and samba.

If we assume that filesystems are going to mostly use acls or mostly
mode bits, then maybe that part doesn't matter a whole lot.  I don't
know.

--b.

> 
> A user-space utility for displaying and changing richacls is available at [4]
> (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> 
> [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> 
> To test richacl on ext4 use -o richacl mount option. This mount option may later be
> dropped in favour of a feature flag.
> 
> More details regarding richacl can be found at
> http://acl.bestbits.at/richacl/
> 
> Changes from v5:
> a) rebase to v3.1-rc4-131-g9e79e3e
> 
> NOTE: The kernel changes will be pushed to
> git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> when kernel.org is back
> 
> -aneesh
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-08  0:46     ` Valdis.Kletnieks-PjAqaU27lzQ
  0 siblings, 0 replies; 116+ messages in thread
From: Valdis.Kletnieks @ 2011-09-08  0:46 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Aneesh Kumar K.V, agruen, bfields, akpm, dhowells, linux-fsdevel,
	linux-nfs, linux-kernel, LSM

[-- Attachment #1: Type: text/plain, Size: 1047 bytes --]

On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
> > The following set of patches implements VFS and ext4 changes needed to implement
> > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > extended by file masks to fit into the standard POSIX file permission model.
> > They are designed to work seamlessly locally as well as across the NFSv4 and
> > CIFS/SMB2 network file system protocols.
>
> POSIX ACLs predate the LSM and can't be done as an LSM due to
> the interactions between mode bits and ACLs as defined by the
> POSIX DRAFT specification. Is there a reason that "rich" ACLs
> can not be done as an LSM?

Well, if it was done as an LSM, it would mean that if I wanted to build a
system where I have a few hundred terabytes of disk exported via Samba, and I
wanted Samba to save the CIFS permission ACL, I couldn't also run Selinux or
SMACK or anything like that - unless somebody actually snuck in the "LSMs are
stackable" patch while I wasn't looking?


[-- Attachment #2: Type: application/pgp-signature, Size: 227 bytes --]

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-08  0:46     ` Valdis.Kletnieks-PjAqaU27lzQ
  0 siblings, 0 replies; 116+ messages in thread
From: Valdis.Kletnieks-PjAqaU27lzQ @ 2011-09-08  0:46 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Aneesh Kumar K.V, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, LSM

[-- Attachment #1: Type: text/plain, Size: 1047 bytes --]

On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
> > The following set of patches implements VFS and ext4 changes needed to implement
> > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > extended by file masks to fit into the standard POSIX file permission model.
> > They are designed to work seamlessly locally as well as across the NFSv4 and
> > CIFS/SMB2 network file system protocols.
>
> POSIX ACLs predate the LSM and can't be done as an LSM due to
> the interactions between mode bits and ACLs as defined by the
> POSIX DRAFT specification. Is there a reason that "rich" ACLs
> can not be done as an LSM?

Well, if it was done as an LSM, it would mean that if I wanted to build a
system where I have a few hundred terabytes of disk exported via Samba, and I
wanted Samba to save the CIFS permission ACL, I couldn't also run Selinux or
SMACK or anything like that - unless somebody actually snuck in the "LSMs are
stackable" patch while I wasn't looking?


[-- Attachment #2: Type: application/pgp-signature, Size: 227 bytes --]

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
  2011-09-07 20:39     ` J. Bruce Fields
  (?)
@ 2011-09-08  9:30     ` Aneesh Kumar K.V
  2011-09-08 20:07       ` J. Bruce Fields
  -1 siblings, 1 reply; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-08  9:30 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Wed, 7 Sep 2011 16:39:16 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> > From: Andreas Gruenbacher <agruen@kernel.org>
> > 
> > Normally, deleting a file requires write access to the parent directory.
> > Some permission models use a different permission on the parent
> > directory to indicate delete access.  In addition, a process can have
> > per-file delete access even without delete access on the parent
> > directory.
> > 
> > Introduce two new inode_permission() mask flags and use them in
> > may_delete()
> > 
> > Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
> > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> > ---
> >  fs/namei.c         |   41 +++++++++++++++++++++++++++--------------
> >  include/linux/fs.h |    2 ++
> >  2 files changed, 29 insertions(+), 14 deletions(-)
> > 
> > diff --git a/fs/namei.c b/fs/namei.c
> > index d52a4cd..eacb530 100644
> > --- a/fs/namei.c
> > +++ b/fs/namei.c
> > @@ -337,7 +337,7 @@ static inline int do_inode_permission(struct inode *inode, int mask)
> >   * are used for other things.
> >   *
> >   * When checking for MAY_APPEND, MAY_CREATE_FILE, MAY_CREATE_DIR,
> > - * MAY_WRITE must also be set in @mask.
> > + * MAY_DELETE_CHILD, MAY_DELETE_SELF, MAY_WRITE must also be set in @mask.
> >   */
> >  int inode_permission(struct inode *inode, int mask)
> >  {
> > @@ -1862,7 +1862,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
> >  		return 0;
> >  
> >  other_userns:
> > -	return !ns_capable(inode_userns(inode), CAP_FOWNER);
> > +	return 1;
> >  }
> >  
> >  /*
> > @@ -1884,30 +1884,43 @@ other_userns:
> >   * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
> >   *     nfs_async_unlink().
> >   */
> > -static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
> > +static int may_delete(struct inode *dir, struct dentry *victim,
> > +		      int isdir, int replace)
> >  {
> > -	int error;
> > +	int mask, error, is_sticky;
> > +	struct inode *inode = victim->d_inode;
> >  
> > -	if (!victim->d_inode)
> > +	if (!inode)
> >  		return -ENOENT;
> >  
> >  	BUG_ON(victim->d_parent->d_inode != dir);
> >  	audit_inode_child(victim, dir);
> >  
> > -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> > +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> > +	if (replace)
> > +		mask |= S_ISDIR(inode->i_mode) ?
> > +			MAY_CREATE_DIR : MAY_CREATE_FILE;
> 
> I'm having trouble understanding this next bit:
> 
> > +	is_sticky = check_sticky(dir, inode);
> > +	error = inode_permission(dir, mask);
> > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > +		error = 0;
> 
> OK, so we can ignore the lack of write or delete permissions on the
> parent if we have delete_self permissions on the child.  I guess that's
> right.
> 
> Why the "|| is_sticky" above?
> 
> Is there some less complicated why to write this?

we removed the ns_capable check out of check_sticky, because we don't
want to do capability check when richacl allows access. We also want to
make sure that even if mode bits allow access (inode_permission(dir, mask))
if sticky bit is set we do additional check.


-aneesh

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 10/26] vfs: Make the inode passed to inode_change_ok non-const
@ 2011-09-08  9:32       ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-08  9:32 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Wed, 7 Sep 2011 16:43:22 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Mon, Sep 05, 2011 at 10:55:32PM +0530, Aneesh Kumar K.V wrote:
> > From: Andreas Gruenbacher <agruen@kernel.org>
> > 
> > We will need to call iop->permission and iop->get_acl from
> > inode_change_ok() for additional permission checks, and both take a
> > non-const inode.
> 
> OK, the essential difference being that richacls have a say in whether
> we can change attributes or not, which posix acls (for example) don't?
> 

yes, next patch explain the details of the check

-aneesh


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 10/26] vfs: Make the inode passed to inode_change_ok non-const
@ 2011-09-08  9:32       ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-08  9:32 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Wed, 7 Sep 2011 16:43:22 -0400, "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> On Mon, Sep 05, 2011 at 10:55:32PM +0530, Aneesh Kumar K.V wrote:
> > From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > 
> > We will need to call iop->permission and iop->get_acl from
> > inode_change_ok() for additional permission checks, and both take a
> > non-const inode.
> 
> OK, the essential difference being that richacls have a say in whether
> we can change attributes or not, which posix acls (for example) don't?
> 

yes, next patch explain the details of the check

-aneesh

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 11/26] vfs: Add permission flags for setting file attributes
  2011-09-07 20:55   ` J. Bruce Fields
@ 2011-09-08  9:36     ` Aneesh Kumar K.V
  2011-09-08 20:08       ` J. Bruce Fields
  0 siblings, 1 reply; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-08  9:36 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Wed, 7 Sep 2011 16:55:03 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Mon, Sep 05, 2011 at 10:55:33PM +0530, Aneesh Kumar K.V wrote:
> > From: Andreas Gruenbacher <agruen@kernel.org>
> > 
> > Some permission models can allow processes to take ownership of a file,
> > change the file permissions, and set the file timestamps.  Introduce new
> > permission mask flags and check for those permissions in
> > inode_change_ok().
> 
> These little helper functions seem like they might be reasonable cleanup
> even without the richacl_change_ok() piece; wonder if it'd be worth
> splitting out the cleanup and applying it now?
> 
> Not that it's necessary--seems like a straightforward enough patch as
> is.

Those helpers also have richacl_chage_ok(..) done as a part of the call. So
they cannot directly be applied to upstream. But we can do similar
helpers for upstream and add richacl changes as a separate patch ? Is
that what you are suggesting. I can split this patch to two in that case

-aneesh


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 14/26] richacl: Permission mapping functions
  2011-09-07 21:24   ` J. Bruce Fields
@ 2011-09-08 10:27     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-08 10:27 UTC (permalink / raw)
  To: J. Bruce Fields, agruen
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Wed, 7 Sep 2011 17:24:00 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Mon, Sep 05, 2011 at 10:55:36PM +0530, Aneesh Kumar K.V wrote:
> > From: Andreas Gruenbacher <agruen@kernel.org>
> > 
> > We need to map from POSIX permissions to NFSv4 permissions when a
> > chmod() is done, from NFSv4 permissions to POSIX permissions when an acl
> > is set (which implicitly sets the file permission bits), and from the
> > MAY_READ/MAY_WRITE/MAY_EXEC/MAY_APPEND flags to NFSv4 permissions when
> > doing an access check in a richacl.
> > 
> > Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
> > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> > ---
> >  fs/richacl_base.c       |  118 +++++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/richacl.h |   46 ++++++++++++++++++
> >  2 files changed, 164 insertions(+), 0 deletions(-)
> > 
> > diff --git a/fs/richacl_base.c b/fs/richacl_base.c
> > index 3536626..d55b436 100644
> > --- a/fs/richacl_base.c
> > +++ b/fs/richacl_base.c
> > @@ -69,6 +69,124 @@ richacl_clone(const struct richacl *acl)
> >  }
> >  
> >  /**
> > + * richacl_mask_to_mode  -  compute the file permission bits which correspond to @mask
> > + * @mask:	%ACE4_* permission mask
> > + *
> > + * See richacl_masks_to_mode().
> > + */
> > +static int
> > +richacl_mask_to_mode(unsigned int mask)
> > +{
> > +	int mode = 0;
> > +
> > +	if (mask & ACE4_POSIX_MODE_READ)
> > +		mode |= MAY_READ;
> > +	if (mask & ACE4_POSIX_MODE_WRITE)
> > +		mode |= MAY_WRITE;
> > +	if (mask & ACE4_POSIX_MODE_EXEC)
> > +		mode |= MAY_EXEC;
> > +
> > +	return mode;
> > +}
> > +
> > +/**
> > + * richacl_masks_to_mode  -  compute the file permission bits from the file masks
> > + *
> > + * When setting a richacl, we set the file permission bits to indicate maximum
> > + * permissions: for example, we set the Write permission when a mask contains
> > + * ACE4_APPEND_DATA even if it does not also contain ACE4_WRITE_DATA.
> > + *
> > + * Permissions which are not in ACE4_POSIX_MODE_READ, ACE4_POSIX_MODE_WRITE, or
> > + * ACE4_POSIX_MODE_EXEC cannot be represented in the file permission bits.
> > + * Such permissions can still be effective, but not for new files or after a
> > + * chmod(), and only if they were set explicitly, for example, by setting a
> > + * richacl.
> > + */
> > +int
> > +richacl_masks_to_mode(const struct richacl *acl)
> > +{
> > +	return richacl_mask_to_mode(acl->a_owner_mask) << 6 |
> > +	       richacl_mask_to_mode(acl->a_group_mask) << 3 |
> > +	       richacl_mask_to_mode(acl->a_other_mask);
> > +}
> > +EXPORT_SYMBOL_GPL(richacl_masks_to_mode);
> > +
> > +/**
> > + * richacl_mode_to_mask  - compute a file mask from the lowest three mode bits
> > + *
> > + * When the file permission bits of a file are set with chmod(), this specifies
> > + * the maximum permissions that processes will get.  All permissions beyond
> > + * that will be removed from the file masks, and become ineffective.
> > + *
> > + * We also add in the permissions which are always allowed no matter what the
> > + * acl says.
> > + */
> > +unsigned int
> > +richacl_mode_to_mask(mode_t mode)
> > +{
> > +	unsigned int mask = ACE4_POSIX_ALWAYS_ALLOWED;
> > +
> > +	if (mode & MAY_READ)
> > +		mask |= ACE4_POSIX_MODE_READ;
> > +	if (mode & MAY_WRITE)
> > +		mask |= ACE4_POSIX_MODE_WRITE;
> > +	if (mode & MAY_EXEC)
> > +		mask |= ACE4_POSIX_MODE_EXEC;
> > +
> > +	return mask;
> > +}
> > +
> > +/**
> > + * richacl_want_to_mask  - convert the iop->permission want argument to a mask
> > + * @want:	@want argument of the permission inode operation
> > + *
> > + * When checking for append, @want is (MAY_WRITE | MAY_APPEND).
> > + *
> > + * Richacls use the iop->may_create and iop->may_delete hooks which are
> > + * used for checking if creating and deleting files is allowed.  These hooks do
> > + * not use richacl_want_to_mask(), so we do not have to deal with mapping
> > + * MAY_WRITE to ACE4_ADD_FILE, ACE4_ADD_SUBDIRECTORY, and ACE4_DELETE_CHILD
> > + * here.
> > + */
> > +unsigned int
> > +richacl_want_to_mask(int want)
> > +{
> > +	unsigned int mask = 0;
> > +
> > +	if (want & MAY_READ)
> > +		mask |= ACE4_READ_DATA;
> > +	if (want & (MAY_APPEND |
> > +		    MAY_CREATE_FILE | MAY_CREATE_DIR |
> > +		    MAY_DELETE_CHILD | MAY_DELETE_SELF |
> > +		    MAY_TAKE_OWNERSHIP | MAY_CHMOD | MAY_SET_TIMES)) {
> > +		if (want & MAY_APPEND)
> > +			mask |= ACE4_APPEND_DATA;
> > +		else if (want & MAY_DELETE_SELF)
> > +			mask |= ACE4_DELETE;
> > +		else if (want & MAY_TAKE_OWNERSHIP)
> > +			mask |= ACE4_WRITE_OWNER;
> > +		else if (want & MAY_CHMOD)
> > +			mask |= ACE4_WRITE_ACL;
> > +		else if (want & MAY_SET_TIMES)
> > +			mask |= ACE4_WRITE_ATTRIBUTES;
> > +		else {
> > +			if (want & MAY_CREATE_FILE)
> > +				mask |= ACE4_ADD_FILE;
> > +			if (want & MAY_CREATE_DIR)
> > +				mask |= ACE4_ADD_SUBDIRECTORY;
> > +			if (want & MAY_DELETE_CHILD)
> > +				mask |= ACE4_DELETE_CHILD;
> > +		}
> 
> Possibly dumb question: why isn't this whole function a simple series of
> if's, one for each MAY_ bit?
> 
> I guess you're using knowledge about the callers to know that, for
> example, no one will ask for MAY_APPEND and MAY_TAKE_OWNERSHIP at the
> same time?
> 
> And adding that big "if (want & (MAY_APPEND | .. | MAY_SET_TIMES))" to
> let you skip over a bunch of checks in the common case?
> 
> Does this help measurably?  It seems complicated and, to the extent it
> makes assumptions about the callers, possibly fragile with respect to
> future changes.
> 

Not the complete function. But I guess we can do the below change. 
We still want to keep  MAY_WRITE check separate, because VFS do add
MAY_WRITE request to different type of request other than write.

Andreas,

Do you see any issue in doing below ?

richacl_want_to_mask(int want)
{
	unsigned int mask = 0;

	if (want & MAY_READ)
		mask |= ACE4_READ_DATA;
	if (want & MAY_DELETE_SELF)
		mask |= ACE4_DELETE;
	if (want & MAY_TAKE_OWNERSHIP)
		mask |= ACE4_WRITE_OWNER;
	if (want & MAY_CHMOD)
		mask |= ACE4_WRITE_ACL;
	if (want & MAY_SET_TIMES)
		mask |= ACE4_WRITE_ATTRIBUTES;
	if (want & MAY_EXEC)
		mask |= ACE4_EXECUTE;
	/*
	 * differentiate MAY_WRITE from these request
	 */
	if (want & (MAY_APPEND |
		    MAY_CREATE_FILE | MAY_CREATE_DIR |
		    MAY_DELETE_CHILD)) {
		if (want & MAY_APPEND)
			mask |= ACE4_APPEND_DATA;
		if (want & MAY_CREATE_FILE)
			mask |= ACE4_ADD_FILE;
		if (want & MAY_CREATE_DIR)
			mask |= ACE4_ADD_SUBDIRECTORY;
		if (want & MAY_DELETE_CHILD)
			mask |= ACE4_DELETE_CHILD;
	} else if (want & MAY_WRITE)
		mask |= ACE4_WRITE_DATA;
	return mask;
}

-aneesh

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 17/26] richacl: Permission check algorithm
@ 2011-09-08 10:34       ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-08 10:34 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Wed, 7 Sep 2011 17:50:22 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Mon, Sep 05, 2011 at 10:55:39PM +0530, Aneesh Kumar K.V wrote:
> > From: Andreas Gruenbacher <agruen@kernel.org>
> > 
> > As in the standard POSIX file permission model, each process is the
> > owner, group, or other file class.  A process is
> > 
> >   - in the owner file class if it owns the file,
> >   - in the group file class if it is in the file's owning group or it
> >     matches any of the user or group entries, and
> >   - in the other file class otherwise.
> > 
> > Each file class is associated with a file mask.
> > 
> > A richacl grants a requested access if the NFSv4 acl in the richacl
> > grants the requested permissions (according to the NFSv4 permission
> > check algorithm) and the file mask that applies to the process includes
> > the requested permissions.
> 
> I assume that by default any ui normally recalculates an upper-bound
> mask automatically when you add an ace, as the posix setfacl does, so
> the user doesn't have to think about masks too much?
> 

yes. richacl userspace command does this.

-aneesh


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 17/26] richacl: Permission check algorithm
@ 2011-09-08 10:34       ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-08 10:34 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Wed, 7 Sep 2011 17:50:22 -0400, "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> On Mon, Sep 05, 2011 at 10:55:39PM +0530, Aneesh Kumar K.V wrote:
> > From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > 
> > As in the standard POSIX file permission model, each process is the
> > owner, group, or other file class.  A process is
> > 
> >   - in the owner file class if it owns the file,
> >   - in the group file class if it is in the file's owning group or it
> >     matches any of the user or group entries, and
> >   - in the other file class otherwise.
> > 
> > Each file class is associated with a file mask.
> > 
> > A richacl grants a requested access if the NFSv4 acl in the richacl
> > grants the requested permissions (according to the NFSv4 permission
> > check algorithm) and the file mask that applies to the process includes
> > the requested permissions.
> 
> I assume that by default any ui normally recalculates an upper-bound
> mask automatically when you add an ace, as the posix setfacl does, so
> the user doesn't have to think about masks too much?
> 

yes. richacl userspace command does this.

-aneesh

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-08 10:40     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-08 10:40 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel,
	Jeremy Allison

On Wed, 7 Sep 2011 19:44:08 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Mon, Sep 05, 2011 at 10:55:22PM +0530, Aneesh Kumar K.V wrote:
> > Hi,
> > 
> > The following set of patches implements VFS and ext4 changes needed to implement
> > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > extended by file masks to fit into the standard POSIX file permission model.
> > They are designed to work seamlessly locally as well as across the NFSv4 and
> > CIFS/SMB2 network file system protocols.
> 
> The posix acl mapping that samba and nfsd currently have to do is
> painful for everyone and I'm delighted to get away from it.
> 
> My main remaining worry (besides the fact that cifs/v4 acls are too
> complicated--but what can we do about that?)--is about how exactly the
> (acl, mask)->acl mapping is going to work for nfsd and samba.

I already have changes to nfsd that maps NFSv4 ACL to the richacl. You
will find that in richaclv23 branch

git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richaclv23

> 
> If we assume that filesystems are going to mostly use acls or mostly
> mode bits, then maybe that part doesn't matter a whole lot.  I don't
> know.
> 

-aneesh

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-08 10:40     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-08 10:40 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jeremy Allison

On Wed, 7 Sep 2011 19:44:08 -0400, "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> On Mon, Sep 05, 2011 at 10:55:22PM +0530, Aneesh Kumar K.V wrote:
> > Hi,
> > 
> > The following set of patches implements VFS and ext4 changes needed to implement
> > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > extended by file masks to fit into the standard POSIX file permission model.
> > They are designed to work seamlessly locally as well as across the NFSv4 and
> > CIFS/SMB2 network file system protocols.
> 
> The posix acl mapping that samba and nfsd currently have to do is
> painful for everyone and I'm delighted to get away from it.
> 
> My main remaining worry (besides the fact that cifs/v4 acls are too
> complicated--but what can we do about that?)--is about how exactly the
> (acl, mask)->acl mapping is going to work for nfsd and samba.

I already have changes to nfsd that maps NFSv4 ACL to the richacl. You
will find that in richaclv23 branch

git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richaclv23

> 
> If we assume that filesystems are going to mostly use acls or mostly
> mode bits, then maybe that part doesn't matter a whole lot.  I don't
> know.
> 

-aneesh
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
  2011-09-08  9:30     ` Aneesh Kumar K.V
@ 2011-09-08 20:07       ` J. Bruce Fields
  2011-09-08 22:02         ` J. Bruce Fields
  2011-09-09  5:14           ` Aneesh Kumar K.V
  0 siblings, 2 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-08 20:07 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Thu, Sep 08, 2011 at 03:00:58PM +0530, Aneesh Kumar K.V wrote:
> On Wed, 7 Sep 2011 16:39:16 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> > On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> > > From: Andreas Gruenbacher <agruen@kernel.org>
> > > 
> > > Normally, deleting a file requires write access to the parent directory.
> > > Some permission models use a different permission on the parent
> > > directory to indicate delete access.  In addition, a process can have
> > > per-file delete access even without delete access on the parent
> > > directory.
> > > 
> > > Introduce two new inode_permission() mask flags and use them in
> > > may_delete()
> > > 
> > > Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
> > > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> > > ---
> > >  fs/namei.c         |   41 +++++++++++++++++++++++++++--------------
> > >  include/linux/fs.h |    2 ++
> > >  2 files changed, 29 insertions(+), 14 deletions(-)
> > > 
> > > diff --git a/fs/namei.c b/fs/namei.c
> > > index d52a4cd..eacb530 100644
> > > --- a/fs/namei.c
> > > +++ b/fs/namei.c
> > > @@ -337,7 +337,7 @@ static inline int do_inode_permission(struct inode *inode, int mask)
> > >   * are used for other things.
> > >   *
> > >   * When checking for MAY_APPEND, MAY_CREATE_FILE, MAY_CREATE_DIR,
> > > - * MAY_WRITE must also be set in @mask.
> > > + * MAY_DELETE_CHILD, MAY_DELETE_SELF, MAY_WRITE must also be set in @mask.
> > >   */
> > >  int inode_permission(struct inode *inode, int mask)
> > >  {
> > > @@ -1862,7 +1862,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
> > >  		return 0;
> > >  
> > >  other_userns:
> > > -	return !ns_capable(inode_userns(inode), CAP_FOWNER);
> > > +	return 1;
> > >  }
> > >  
> > >  /*
> > > @@ -1884,30 +1884,43 @@ other_userns:
> > >   * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
> > >   *     nfs_async_unlink().
> > >   */
> > > -static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
> > > +static int may_delete(struct inode *dir, struct dentry *victim,
> > > +		      int isdir, int replace)
> > >  {
> > > -	int error;
> > > +	int mask, error, is_sticky;
> > > +	struct inode *inode = victim->d_inode;
> > >  
> > > -	if (!victim->d_inode)
> > > +	if (!inode)
> > >  		return -ENOENT;
> > >  
> > >  	BUG_ON(victim->d_parent->d_inode != dir);
> > >  	audit_inode_child(victim, dir);
> > >  
> > > -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> > > +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> > > +	if (replace)
> > > +		mask |= S_ISDIR(inode->i_mode) ?
> > > +			MAY_CREATE_DIR : MAY_CREATE_FILE;
> > 
> > I'm having trouble understanding this next bit:
> > 
> > > +	is_sticky = check_sticky(dir, inode);
> > > +	error = inode_permission(dir, mask);
> > > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > > +		error = 0;
> > 
> > OK, so we can ignore the lack of write or delete permissions on the
> > parent if we have delete_self permissions on the child.  I guess that's
> > right.
> > 
> > Why the "|| is_sticky" above?
> > 
> > Is there some less complicated why to write this?
> 
> we removed the ns_capable check out of check_sticky, because we don't
> want to do capability check when richacl allows access. We also want to
> make sure that even if mode bits allow access (inode_permission(dir, mask))
> if sticky bit is set we do additional check.

Why are the two inode_permissions ANDed?  The windows semantics are that
you can delete if you have MAY_DELETE_CHILD *or* MAY_DELETE_SELF.

--b.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 11/26] vfs: Add permission flags for setting file attributes
  2011-09-08  9:36     ` Aneesh Kumar K.V
@ 2011-09-08 20:08       ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-08 20:08 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Thu, Sep 08, 2011 at 03:06:03PM +0530, Aneesh Kumar K.V wrote:
> On Wed, 7 Sep 2011 16:55:03 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> > On Mon, Sep 05, 2011 at 10:55:33PM +0530, Aneesh Kumar K.V wrote:
> > > From: Andreas Gruenbacher <agruen@kernel.org>
> > > 
> > > Some permission models can allow processes to take ownership of a file,
> > > change the file permissions, and set the file timestamps.  Introduce new
> > > permission mask flags and check for those permissions in
> > > inode_change_ok().
> > 
> > These little helper functions seem like they might be reasonable cleanup
> > even without the richacl_change_ok() piece; wonder if it'd be worth
> > splitting out the cleanup and applying it now?
> > 
> > Not that it's necessary--seems like a straightforward enough patch as
> > is.
> 
> Those helpers also have richacl_chage_ok(..) done as a part of the call. So
> they cannot directly be applied to upstream. But we can do similar
> helpers for upstream and add richacl changes as a separate patch ? Is
> that what you are suggesting. I can split this patch to two in that case

Yes, that's what I was suggesting, though I don't feel terribly strong
about it; up to you whether you think it's worth it.

--b.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
  2011-09-08 20:07       ` J. Bruce Fields
@ 2011-09-08 22:02         ` J. Bruce Fields
  2011-09-09  5:19             ` Aneesh Kumar K.V
  2011-09-09  5:14           ` Aneesh Kumar K.V
  1 sibling, 1 reply; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-08 22:02 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Thu, Sep 08, 2011 at 04:07:54PM -0400, J. Bruce Fields wrote:
> On Thu, Sep 08, 2011 at 03:00:58PM +0530, Aneesh Kumar K.V wrote:
> > On Wed, 7 Sep 2011 16:39:16 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> > > On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> > > > +static int may_delete(struct inode *dir, struct dentry *victim,
> > > > +		      int isdir, int replace)
> > > >  {
> > > > -	int error;
> > > > +	int mask, error, is_sticky;
> > > > +	struct inode *inode = victim->d_inode;
> > > >  
> > > > -	if (!victim->d_inode)
> > > > +	if (!inode)
> > > >  		return -ENOENT;
> > > >  
> > > >  	BUG_ON(victim->d_parent->d_inode != dir);
> > > >  	audit_inode_child(victim, dir);
> > > >  
> > > > -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> > > > +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> > > > +	if (replace)
> > > > +		mask |= S_ISDIR(inode->i_mode) ?
> > > > +			MAY_CREATE_DIR : MAY_CREATE_FILE;
> > > 
> > > I'm having trouble understanding this next bit:
> > > 
> > > > +	is_sticky = check_sticky(dir, inode);
> > > > +	error = inode_permission(dir, mask);
> > > > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > > > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > > > +		error = 0;
> > > 
> > > OK, so we can ignore the lack of write or delete permissions on the
> > > parent if we have delete_self permissions on the child.  I guess that's
> > > right.
> > > 
> > > Why the "|| is_sticky" above?
> > > 
> > > Is there some less complicated why to write this?
> > 
> > we removed the ns_capable check out of check_sticky, because we don't
> > want to do capability check when richacl allows access. We also want to
> > make sure that even if mode bits allow access (inode_permission(dir, mask))
> > if sticky bit is set we do additional check.
> 
> Why are the two inode_permissions ANDed?  The windows semantics are that
> you can delete if you have MAY_DELETE_CHILD *or* MAY_DELETE_SELF.

Either way, those conditions are just really hard to follow.  Could you
simplify the logic, add comments, maybe move the richacl stuff into a
little helper function?

Also, a nit:

> > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&

The way you calculated mask above it always includes MAY_WRITE and
MAY_DELETE_CHILD, so the above is equivalent to just

		    !inode_permission(dir, MAY_WRITE | MAY_DELETE_CHILD) &&

isn't it?

--b.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
@ 2011-09-09  5:14           ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-09  5:14 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Thu, 8 Sep 2011 16:07:54 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Thu, Sep 08, 2011 at 03:00:58PM +0530, Aneesh Kumar K.V wrote:
> > On Wed, 7 Sep 2011 16:39:16 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> > > On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> > > > From: Andreas Gruenbacher <agruen@kernel.org>
> > > > 
> > > > Normally, deleting a file requires write access to the parent directory.
> > > > Some permission models use a different permission on the parent
> > > > directory to indicate delete access.  In addition, a process can have
> > > > per-file delete access even without delete access on the parent
> > > > directory.
> > > > 
> > > > Introduce two new inode_permission() mask flags and use them in
> > > > may_delete()
> > > > 
> > > > Signed-off-by: Andreas Gruenbacher <agruen@kernel.org>
> > > > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> > > > ---
> > > >  fs/namei.c         |   41 +++++++++++++++++++++++++++--------------
> > > >  include/linux/fs.h |    2 ++
> > > >  2 files changed, 29 insertions(+), 14 deletions(-)
> > > > 
> > > > diff --git a/fs/namei.c b/fs/namei.c
> > > > index d52a4cd..eacb530 100644
> > > > --- a/fs/namei.c
> > > > +++ b/fs/namei.c
> > > > @@ -337,7 +337,7 @@ static inline int do_inode_permission(struct inode *inode, int mask)
> > > >   * are used for other things.
> > > >   *
> > > >   * When checking for MAY_APPEND, MAY_CREATE_FILE, MAY_CREATE_DIR,
> > > > - * MAY_WRITE must also be set in @mask.
> > > > + * MAY_DELETE_CHILD, MAY_DELETE_SELF, MAY_WRITE must also be set in @mask.
> > > >   */
> > > >  int inode_permission(struct inode *inode, int mask)
> > > >  {
> > > > @@ -1862,7 +1862,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
> > > >  		return 0;
> > > >  
> > > >  other_userns:
> > > > -	return !ns_capable(inode_userns(inode), CAP_FOWNER);
> > > > +	return 1;
> > > >  }
> > > >  
> > > >  /*
> > > > @@ -1884,30 +1884,43 @@ other_userns:
> > > >   * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
> > > >   *     nfs_async_unlink().
> > > >   */
> > > > -static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
> > > > +static int may_delete(struct inode *dir, struct dentry *victim,
> > > > +		      int isdir, int replace)
> > > >  {
> > > > -	int error;
> > > > +	int mask, error, is_sticky;
> > > > +	struct inode *inode = victim->d_inode;
> > > >  
> > > > -	if (!victim->d_inode)
> > > > +	if (!inode)
> > > >  		return -ENOENT;
> > > >  
> > > >  	BUG_ON(victim->d_parent->d_inode != dir);
> > > >  	audit_inode_child(victim, dir);
> > > >  
> > > > -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> > > > +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> > > > +	if (replace)
> > > > +		mask |= S_ISDIR(inode->i_mode) ?
> > > > +			MAY_CREATE_DIR : MAY_CREATE_FILE;
> > > 
> > > I'm having trouble understanding this next bit:
> > > 
> > > > +	is_sticky = check_sticky(dir, inode);
> > > > +	error = inode_permission(dir, mask);
> > > > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > > > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > > > +		error = 0;
> > > 
> > > OK, so we can ignore the lack of write or delete permissions on the
> > > parent if we have delete_self permissions on the child.  I guess that's
> > > right.
> > > 
> > > Why the "|| is_sticky" above?
> > > 
> > > Is there some less complicated why to write this?
> > 
> > we removed the ns_capable check out of check_sticky, because we don't
> > want to do capability check when richacl allows access. We also want to
> > make sure that even if mode bits allow access (inode_permission(dir, mask))
> > if sticky bit is set we do additional check.
> 
> Why are the two inode_permissions ANDed?  The windows semantics are that
> you can delete if you have MAY_DELETE_CHILD *or* MAY_DELETE_SELF.
> 

error = inode_permission(dir, mask) check for whether we have MAY_EXEC and
MAY_DELETE_CHILD permission on the directory. If we don't have one then
we check whether directory have MAY_EXEC permission and (hence && ) the inode being
deleted have MAY_DELETE_SELF permission. 

NOTE: if it is a replace, we need to add MAY_CREATE_DIR or
MAY_CREATE_FILE to the first two permission check.

-aneesh


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
@ 2011-09-09  5:14           ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-09  5:14 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Thu, 8 Sep 2011 16:07:54 -0400, "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> On Thu, Sep 08, 2011 at 03:00:58PM +0530, Aneesh Kumar K.V wrote:
> > On Wed, 7 Sep 2011 16:39:16 -0400, "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> > > On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> > > > From: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > > > 
> > > > Normally, deleting a file requires write access to the parent directory.
> > > > Some permission models use a different permission on the parent
> > > > directory to indicate delete access.  In addition, a process can have
> > > > per-file delete access even without delete access on the parent
> > > > directory.
> > > > 
> > > > Introduce two new inode_permission() mask flags and use them in
> > > > may_delete()
> > > > 
> > > > Signed-off-by: Andreas Gruenbacher <agruen-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > > > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> > > > ---
> > > >  fs/namei.c         |   41 +++++++++++++++++++++++++++--------------
> > > >  include/linux/fs.h |    2 ++
> > > >  2 files changed, 29 insertions(+), 14 deletions(-)
> > > > 
> > > > diff --git a/fs/namei.c b/fs/namei.c
> > > > index d52a4cd..eacb530 100644
> > > > --- a/fs/namei.c
> > > > +++ b/fs/namei.c
> > > > @@ -337,7 +337,7 @@ static inline int do_inode_permission(struct inode *inode, int mask)
> > > >   * are used for other things.
> > > >   *
> > > >   * When checking for MAY_APPEND, MAY_CREATE_FILE, MAY_CREATE_DIR,
> > > > - * MAY_WRITE must also be set in @mask.
> > > > + * MAY_DELETE_CHILD, MAY_DELETE_SELF, MAY_WRITE must also be set in @mask.
> > > >   */
> > > >  int inode_permission(struct inode *inode, int mask)
> > > >  {
> > > > @@ -1862,7 +1862,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
> > > >  		return 0;
> > > >  
> > > >  other_userns:
> > > > -	return !ns_capable(inode_userns(inode), CAP_FOWNER);
> > > > +	return 1;
> > > >  }
> > > >  
> > > >  /*
> > > > @@ -1884,30 +1884,43 @@ other_userns:
> > > >   * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
> > > >   *     nfs_async_unlink().
> > > >   */
> > > > -static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
> > > > +static int may_delete(struct inode *dir, struct dentry *victim,
> > > > +		      int isdir, int replace)
> > > >  {
> > > > -	int error;
> > > > +	int mask, error, is_sticky;
> > > > +	struct inode *inode = victim->d_inode;
> > > >  
> > > > -	if (!victim->d_inode)
> > > > +	if (!inode)
> > > >  		return -ENOENT;
> > > >  
> > > >  	BUG_ON(victim->d_parent->d_inode != dir);
> > > >  	audit_inode_child(victim, dir);
> > > >  
> > > > -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> > > > +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> > > > +	if (replace)
> > > > +		mask |= S_ISDIR(inode->i_mode) ?
> > > > +			MAY_CREATE_DIR : MAY_CREATE_FILE;
> > > 
> > > I'm having trouble understanding this next bit:
> > > 
> > > > +	is_sticky = check_sticky(dir, inode);
> > > > +	error = inode_permission(dir, mask);
> > > > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > > > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > > > +		error = 0;
> > > 
> > > OK, so we can ignore the lack of write or delete permissions on the
> > > parent if we have delete_self permissions on the child.  I guess that's
> > > right.
> > > 
> > > Why the "|| is_sticky" above?
> > > 
> > > Is there some less complicated why to write this?
> > 
> > we removed the ns_capable check out of check_sticky, because we don't
> > want to do capability check when richacl allows access. We also want to
> > make sure that even if mode bits allow access (inode_permission(dir, mask))
> > if sticky bit is set we do additional check.
> 
> Why are the two inode_permissions ANDed?  The windows semantics are that
> you can delete if you have MAY_DELETE_CHILD *or* MAY_DELETE_SELF.
> 

error = inode_permission(dir, mask) check for whether we have MAY_EXEC and
MAY_DELETE_CHILD permission on the directory. If we don't have one then
we check whether directory have MAY_EXEC permission and (hence && ) the inode being
deleted have MAY_DELETE_SELF permission. 

NOTE: if it is a replace, we need to add MAY_CREATE_DIR or
MAY_CREATE_FILE to the first two permission check.

-aneesh

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
@ 2011-09-09  5:19             ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-09  5:19 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Thu, 8 Sep 2011 18:02:46 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Thu, Sep 08, 2011 at 04:07:54PM -0400, J. Bruce Fields wrote:
> > On Thu, Sep 08, 2011 at 03:00:58PM +0530, Aneesh Kumar K.V wrote:
> > > On Wed, 7 Sep 2011 16:39:16 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> > > > On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> > > > > +static int may_delete(struct inode *dir, struct dentry *victim,
> > > > > +		      int isdir, int replace)
> > > > >  {
> > > > > -	int error;
> > > > > +	int mask, error, is_sticky;
> > > > > +	struct inode *inode = victim->d_inode;
> > > > >  
> > > > > -	if (!victim->d_inode)
> > > > > +	if (!inode)
> > > > >  		return -ENOENT;
> > > > >  
> > > > >  	BUG_ON(victim->d_parent->d_inode != dir);
> > > > >  	audit_inode_child(victim, dir);
> > > > >  
> > > > > -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> > > > > +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> > > > > +	if (replace)
> > > > > +		mask |= S_ISDIR(inode->i_mode) ?
> > > > > +			MAY_CREATE_DIR : MAY_CREATE_FILE;
> > > > 
> > > > I'm having trouble understanding this next bit:
> > > > 
> > > > > +	is_sticky = check_sticky(dir, inode);
> > > > > +	error = inode_permission(dir, mask);
> > > > > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > > > > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > > > > +		error = 0;
> > > > 
> > > > OK, so we can ignore the lack of write or delete permissions on the
> > > > parent if we have delete_self permissions on the child.  I guess that's
> > > > right.
> > > > 
> > > > Why the "|| is_sticky" above?
> > > > 
> > > > Is there some less complicated why to write this?
> > > 
> > > we removed the ns_capable check out of check_sticky, because we don't
> > > want to do capability check when richacl allows access. We also want to
> > > make sure that even if mode bits allow access (inode_permission(dir, mask))
> > > if sticky bit is set we do additional check.
> > 
> > Why are the two inode_permissions ANDed?  The windows semantics are that
> > you can delete if you have MAY_DELETE_CHILD *or* MAY_DELETE_SELF.
> 
> Either way, those conditions are just really hard to follow.  Could you
> simplify the logic, add comments, maybe move the richacl stuff into a
> little helper function?
> 
> Also, a nit:
> 
> > > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> 
> The way you calculated mask above it always includes MAY_WRITE and
> MAY_DELETE_CHILD, so the above is equivalent to just
> 
> 		    !inode_permission(dir, MAY_WRITE | MAY_DELETE_CHILD) &&
> 
> isn't it?
> 

I guess i can simplify it as 
  !inode_permission(dir, MAY_EXEC | replace_mask)
  
-aneesh

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
@ 2011-09-09  5:19             ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-09  5:19 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Thu, 8 Sep 2011 18:02:46 -0400, "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> On Thu, Sep 08, 2011 at 04:07:54PM -0400, J. Bruce Fields wrote:
> > On Thu, Sep 08, 2011 at 03:00:58PM +0530, Aneesh Kumar K.V wrote:
> > > On Wed, 7 Sep 2011 16:39:16 -0400, "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> > > > On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> > > > > +static int may_delete(struct inode *dir, struct dentry *victim,
> > > > > +		      int isdir, int replace)
> > > > >  {
> > > > > -	int error;
> > > > > +	int mask, error, is_sticky;
> > > > > +	struct inode *inode = victim->d_inode;
> > > > >  
> > > > > -	if (!victim->d_inode)
> > > > > +	if (!inode)
> > > > >  		return -ENOENT;
> > > > >  
> > > > >  	BUG_ON(victim->d_parent->d_inode != dir);
> > > > >  	audit_inode_child(victim, dir);
> > > > >  
> > > > > -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> > > > > +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> > > > > +	if (replace)
> > > > > +		mask |= S_ISDIR(inode->i_mode) ?
> > > > > +			MAY_CREATE_DIR : MAY_CREATE_FILE;
> > > > 
> > > > I'm having trouble understanding this next bit:
> > > > 
> > > > > +	is_sticky = check_sticky(dir, inode);
> > > > > +	error = inode_permission(dir, mask);
> > > > > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > > > > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > > > > +		error = 0;
> > > > 
> > > > OK, so we can ignore the lack of write or delete permissions on the
> > > > parent if we have delete_self permissions on the child.  I guess that's
> > > > right.
> > > > 
> > > > Why the "|| is_sticky" above?
> > > > 
> > > > Is there some less complicated why to write this?
> > > 
> > > we removed the ns_capable check out of check_sticky, because we don't
> > > want to do capability check when richacl allows access. We also want to
> > > make sure that even if mode bits allow access (inode_permission(dir, mask))
> > > if sticky bit is set we do additional check.
> > 
> > Why are the two inode_permissions ANDed?  The windows semantics are that
> > you can delete if you have MAY_DELETE_CHILD *or* MAY_DELETE_SELF.
> 
> Either way, those conditions are just really hard to follow.  Could you
> simplify the logic, add comments, maybe move the richacl stuff into a
> little helper function?
> 
> Also, a nit:
> 
> > > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> 
> The way you calculated mask above it always includes MAY_WRITE and
> MAY_DELETE_CHILD, so the above is equivalent to just
> 
> 		    !inode_permission(dir, MAY_WRITE | MAY_DELETE_CHILD) &&
> 
> isn't it?
> 

I guess i can simplify it as 
  !inode_permission(dir, MAY_EXEC | replace_mask)
  
-aneesh
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
  2011-09-09  5:19             ` Aneesh Kumar K.V
  (?)
@ 2011-09-09  5:25             ` Aneesh Kumar K.V
  2011-09-09 12:02               ` J. Bruce Fields
  -1 siblings, 1 reply; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-09  5:25 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Fri, 09 Sep 2011 10:49:19 +0530, "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> wrote:
> On Thu, 8 Sep 2011 18:02:46 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> > On Thu, Sep 08, 2011 at 04:07:54PM -0400, J. Bruce Fields wrote:
> > > On Thu, Sep 08, 2011 at 03:00:58PM +0530, Aneesh Kumar K.V wrote:
> > > > On Wed, 7 Sep 2011 16:39:16 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> > > > > On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> > > > > > +static int may_delete(struct inode *dir, struct dentry *victim,
> > > > > > +		      int isdir, int replace)
> > > > > >  {
> > > > > > -	int error;
> > > > > > +	int mask, error, is_sticky;
> > > > > > +	struct inode *inode = victim->d_inode;
> > > > > >  
> > > > > > -	if (!victim->d_inode)
> > > > > > +	if (!inode)
> > > > > >  		return -ENOENT;
> > > > > >  
> > > > > >  	BUG_ON(victim->d_parent->d_inode != dir);
> > > > > >  	audit_inode_child(victim, dir);
> > > > > >  
> > > > > > -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> > > > > > +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> > > > > > +	if (replace)
> > > > > > +		mask |= S_ISDIR(inode->i_mode) ?
> > > > > > +			MAY_CREATE_DIR : MAY_CREATE_FILE;
> > > > > 
> > > > > I'm having trouble understanding this next bit:
> > > > > 
> > > > > > +	is_sticky = check_sticky(dir, inode);
> > > > > > +	error = inode_permission(dir, mask);
> > > > > > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > > > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > > > > > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > > > > > +		error = 0;
> > > > > 
> > > > > OK, so we can ignore the lack of write or delete permissions on the
> > > > > parent if we have delete_self permissions on the child.  I guess that's
> > > > > right.
> > > > > 
> > > > > Why the "|| is_sticky" above?
> > > > > 
> > > > > Is there some less complicated why to write this?
> > > > 
> > > > we removed the ns_capable check out of check_sticky, because we don't
> > > > want to do capability check when richacl allows access. We also want to
> > > > make sure that even if mode bits allow access (inode_permission(dir, mask))
> > > > if sticky bit is set we do additional check.
> > > 
> > > Why are the two inode_permissions ANDed?  The windows semantics are that
> > > you can delete if you have MAY_DELETE_CHILD *or* MAY_DELETE_SELF.
> > 
> > Either way, those conditions are just really hard to follow.  Could you
> > simplify the logic, add comments, maybe move the richacl stuff into a
> > little helper function?
> > 
> > Also, a nit:
> > 
> > > > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > 
> > The way you calculated mask above it always includes MAY_WRITE and
> > MAY_DELETE_CHILD, so the above is equivalent to just
> > 
> > 		    !inode_permission(dir, MAY_WRITE | MAY_DELETE_CHILD) &&
> > 
> > isn't it?
> > 
> 
> I guess i can simplify it as 
>   !inode_permission(dir, MAY_EXEC | replace_mask)
>   

diff --git a/fs/namei.c b/fs/namei.c
index 1054bc3..e545c81 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1912,8 +1912,9 @@ other_userns:
 static int may_delete(struct inode *dir, struct dentry *victim,
 		      int isdir, int replace)
 {
-	int mask, error, is_sticky;
 	struct inode *inode = victim->d_inode;
+	int mask, replace_mask = 0, error, is_sticky;
+
 
 	if (!inode)
 		return -ENOENT;
@@ -1923,12 +1924,12 @@ static int may_delete(struct inode *dir, struct dentry *victim,
 
 	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
 	if (replace)
-		mask |= S_ISDIR(inode->i_mode) ?
-			MAY_CREATE_DIR : MAY_CREATE_FILE;
+		replace_mask = S_ISDIR(inode->i_mode) ?
+				MAY_CREATE_DIR : MAY_CREATE_FILE;
 	is_sticky = check_sticky(dir, inode);
-	error = inode_permission(dir, mask);
+	error = inode_permission(dir, mask | replace_mask);
 	if ((error || is_sticky) && IS_RICHACL(inode) &&
-	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
+	    !inode_permission(dir, MAY_EXEC | replace_mask) &&
 	    !inode_permission(inode, MAY_DELETE_SELF))
 		error = 0;
 	else if (!error && is_sticky &&


^ permalink raw reply related	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 08/26] vfs: Add new file and directory create permission flags
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (28 preceding siblings ...)
  2011-09-07 23:44 ` J. Bruce Fields
@ 2011-09-09 10:02 ` David Howells
  2011-09-09 11:59   ` Aneesh Kumar K.V
  2011-09-09 10:12   ` David Howells
                   ` (7 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: David Howells @ 2011-09-09 10:02 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:

> -static inline int may_create(struct inode *dir, struct dentry *child)
> +static inline int may_create(struct inode *dir, struct dentry *child, int isdir)

Would it make sense to pass the proposed mode_t instead?  That way you can
check for symlinks and other file types too if necessary later.

David

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
@ 2011-09-09 10:12   ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-09 10:12 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:

> +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> +	    !inode_permission(inode, MAY_DELETE_SELF))
> +		error = 0;

This might be easier to follow if you used == 0 rather than !.  The problem
with ! is that it looks like:

	not_have inode_permission.

I guess this is just one of the fun consequences of having 0 (false) meaning
okay.

David

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
@ 2011-09-09 10:12   ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-09 10:12 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:

> +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> +	    !inode_permission(inode, MAY_DELETE_SELF))
> +		error = 0;

This might be easier to follow if you used == 0 rather than !.  The problem
with ! is that it looks like:

	not_have inode_permission.

I guess this is just one of the fun consequences of having 0 (false) meaning
okay.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 14/26] richacl: Permission mapping functions
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (30 preceding siblings ...)
  2011-09-09 10:12   ` David Howells
@ 2011-09-09 10:36 ` David Howells
  2011-09-09 11:54     ` Aneesh Kumar K.V
  2011-09-09 12:14   ` David Howells
                   ` (5 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: David Howells @ 2011-09-09 10:36 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:

> +unsigned int
> +richacl_want_to_mask(int want)

unsigned int want?

David

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 14/26] richacl: Permission mapping functions
@ 2011-09-09 11:54     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-09 11:54 UTC (permalink / raw)
  To: David Howells
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

On Fri, 09 Sep 2011 11:36:10 +0100, David Howells <dhowells@redhat.com> wrote:
> Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:
> 
> > +unsigned int
> > +richacl_want_to_mask(int want)
> 
> unsigned int want?
> 

updated the patch

-aneesh


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 14/26] richacl: Permission mapping functions
@ 2011-09-09 11:54     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-09 11:54 UTC (permalink / raw)
  To: David Howells
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, 09 Sep 2011 11:36:10 +0100, David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> 
> > +unsigned int
> > +richacl_want_to_mask(int want)
> 
> unsigned int want?
> 

updated the patch

-aneesh

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
@ 2011-09-09 11:55     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-09 11:55 UTC (permalink / raw)
  To: David Howells
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

On Fri, 09 Sep 2011 11:12:06 +0100, David Howells <dhowells@redhat.com> wrote:
> Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:
> 
> > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > +		error = 0;
> 
> This might be easier to follow if you used == 0 rather than !.  The problem
> with ! is that it looks like:
> 
> 	not_have inode_permission.
> 
> I guess this is just one of the fun consequences of having 0 (false) meaning
> okay.
> 

Updated to do == 0 check

-aneesh


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
@ 2011-09-09 11:55     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-09 11:55 UTC (permalink / raw)
  To: David Howells
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, 09 Sep 2011 11:12:06 +0100, David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> 
> > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > +		error = 0;
> 
> This might be easier to follow if you used == 0 rather than !.  The problem
> with ! is that it looks like:
> 
> 	not_have inode_permission.
> 
> I guess this is just one of the fun consequences of having 0 (false) meaning
> okay.
> 

Updated to do == 0 check

-aneesh

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 08/26] vfs: Add new file and directory create permission flags
  2011-09-09 10:02 ` [PATCH -V6 08/26] vfs: Add new file and directory create permission flags David Howells
@ 2011-09-09 11:59   ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-09 11:59 UTC (permalink / raw)
  To: David Howells
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

On Fri, 09 Sep 2011 11:02:58 +0100, David Howells <dhowells@redhat.com> wrote:
> Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:
> 
> > -static inline int may_create(struct inode *dir, struct dentry *child)
> > +static inline int may_create(struct inode *dir, struct dentry *child, int isdir)
> 
> Would it make sense to pass the proposed mode_t instead?  That way you can
> check for symlinks and other file types too if necessary later.
> 

How about making that change when we need to check for those file types
?. Currently we need to check only if it is a directory or not, and most
of the callers and simply use 1, 0, converting it to mode_t would mean
we build proper mode values there.

-aneesh

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 09/26] vfs: Add delete child and delete self permission flags
  2011-09-09  5:25             ` Aneesh Kumar K.V
@ 2011-09-09 12:02               ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-09 12:02 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Fri, Sep 09, 2011 at 10:55:29AM +0530, Aneesh Kumar K.V wrote:
> On Fri, 09 Sep 2011 10:49:19 +0530, "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> wrote:
> > On Thu, 8 Sep 2011 18:02:46 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> > > On Thu, Sep 08, 2011 at 04:07:54PM -0400, J. Bruce Fields wrote:
> > > > On Thu, Sep 08, 2011 at 03:00:58PM +0530, Aneesh Kumar K.V wrote:
> > > > > On Wed, 7 Sep 2011 16:39:16 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> > > > > > On Mon, Sep 05, 2011 at 10:55:31PM +0530, Aneesh Kumar K.V wrote:
> > > > > > > +static int may_delete(struct inode *dir, struct dentry *victim,
> > > > > > > +		      int isdir, int replace)
> > > > > > >  {
> > > > > > > -	int error;
> > > > > > > +	int mask, error, is_sticky;
> > > > > > > +	struct inode *inode = victim->d_inode;
> > > > > > >  
> > > > > > > -	if (!victim->d_inode)
> > > > > > > +	if (!inode)
> > > > > > >  		return -ENOENT;
> > > > > > >  
> > > > > > >  	BUG_ON(victim->d_parent->d_inode != dir);
> > > > > > >  	audit_inode_child(victim, dir);
> > > > > > >  
> > > > > > > -	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
> > > > > > > +	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
> > > > > > > +	if (replace)
> > > > > > > +		mask |= S_ISDIR(inode->i_mode) ?
> > > > > > > +			MAY_CREATE_DIR : MAY_CREATE_FILE;
> > > > > > 
> > > > > > I'm having trouble understanding this next bit:
> > > > > > 
> > > > > > > +	is_sticky = check_sticky(dir, inode);
> > > > > > > +	error = inode_permission(dir, mask);
> > > > > > > +	if ((error || is_sticky) && IS_RICHACL(inode) &&
> > > > > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > > > > > > +	    !inode_permission(inode, MAY_DELETE_SELF))
> > > > > > > +		error = 0;
> > > > > > 
> > > > > > OK, so we can ignore the lack of write or delete permissions on the
> > > > > > parent if we have delete_self permissions on the child.  I guess that's
> > > > > > right.
> > > > > > 
> > > > > > Why the "|| is_sticky" above?
> > > > > > 
> > > > > > Is there some less complicated why to write this?
> > > > > 
> > > > > we removed the ns_capable check out of check_sticky, because we don't
> > > > > want to do capability check when richacl allows access. We also want to
> > > > > make sure that even if mode bits allow access (inode_permission(dir, mask))
> > > > > if sticky bit is set we do additional check.
> > > > 
> > > > Why are the two inode_permissions ANDed?  The windows semantics are that
> > > > you can delete if you have MAY_DELETE_CHILD *or* MAY_DELETE_SELF.
> > > 
> > > Either way, those conditions are just really hard to follow.  Could you
> > > simplify the logic, add comments, maybe move the richacl stuff into a
> > > little helper function?
> > > 
> > > Also, a nit:
> > > 
> > > > > > > +	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> > > 
> > > The way you calculated mask above it always includes MAY_WRITE and
> > > MAY_DELETE_CHILD, so the above is equivalent to just
> > > 
> > > 		    !inode_permission(dir, MAY_WRITE | MAY_DELETE_CHILD) &&
> > > 
> > > isn't it?
> > > 
> > 
> > I guess i can simplify it as 
> >   !inode_permission(dir, MAY_EXEC | replace_mask)

Oh, crap, I see, I was misreading the & ~(MAY_WRITE...) as
&(MAY_WRITE...).  OK, that makes more sense now.  And using replace_mask
as below does make it clearer, thanks.

--b.

> >   
> 
> diff --git a/fs/namei.c b/fs/namei.c
> index 1054bc3..e545c81 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -1912,8 +1912,9 @@ other_userns:
>  static int may_delete(struct inode *dir, struct dentry *victim,
>  		      int isdir, int replace)
>  {
> -	int mask, error, is_sticky;
>  	struct inode *inode = victim->d_inode;
> +	int mask, replace_mask = 0, error, is_sticky;
> +
>  
>  	if (!inode)
>  		return -ENOENT;
> @@ -1923,12 +1924,12 @@ static int may_delete(struct inode *dir, struct dentry *victim,
>  
>  	mask = MAY_WRITE | MAY_EXEC | MAY_DELETE_CHILD;
>  	if (replace)
> -		mask |= S_ISDIR(inode->i_mode) ?
> -			MAY_CREATE_DIR : MAY_CREATE_FILE;
> +		replace_mask = S_ISDIR(inode->i_mode) ?
> +				MAY_CREATE_DIR : MAY_CREATE_FILE;
>  	is_sticky = check_sticky(dir, inode);
> -	error = inode_permission(dir, mask);
> +	error = inode_permission(dir, mask | replace_mask);
>  	if ((error || is_sticky) && IS_RICHACL(inode) &&
> -	    !inode_permission(dir, mask & ~(MAY_WRITE | MAY_DELETE_CHILD)) &&
> +	    !inode_permission(dir, MAY_EXEC | replace_mask) &&
>  	    !inode_permission(inode, MAY_DELETE_SELF))
>  		error = 0;
>  	else if (!error && is_sticky &&

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 18/26] richacl: Create-time inheritance
@ 2011-09-09 12:14   ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-09 12:14 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:

> + * @dir_acl:	acl of the containing direcory

"directory".

David

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 18/26] richacl: Create-time inheritance
@ 2011-09-09 12:14   ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-09 12:14 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:

> + * @dir_acl:	acl of the containing direcory

"directory".

David
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 22/26] vfs: Cache richacl in struct inode
@ 2011-09-09 12:37   ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-09 12:37 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:

> Cache richacls in struct inode so that this doesn't have to be done
> individually in each filesystem.

Since many ACLs in a filesystem are going to be identical, can you have a
global hash table and share them?

David

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 22/26] vfs: Cache richacl in struct inode
@ 2011-09-09 12:37   ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-09 12:37 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:

> Cache richacls in struct inode so that this doesn't have to be done
> individually in each filesystem.

Since many ACLs in a filesystem are going to be identical, can you have a
global hash table and share them?

David
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 25/26] ext4: Implement rich acl for ext4
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (33 preceding siblings ...)
  2011-09-09 12:37   ` David Howells
@ 2011-09-09 12:45 ` David Howells
  2011-09-13  4:25     ` Aneesh Kumar K.V
  2011-09-09 12:48   ` David Howells
                   ` (2 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: David Howells @ 2011-09-09 12:45 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:

> +	retval = ext4_set_richacl(handle, inode, acl);
> +	ext4_journal_stop(handle);
> +	if (retval == ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
> +		goto retry;

Should that be -ENOSPC?

I do wonder, why does ext4 need to know about richacls at all?  Surely, as far
as ext4 is concerned, they should be seen as xattrs?

If ext4 needs a mark on disk to say it supports richacls, then why can't that
simply be the presence or lack thereof of a richacl on the root dir?

David

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-09 12:48   ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-09 12:48 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:

> The following set of patches implements VFS and ext4 changes needed to implement
> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> extended by file masks to fit into the standard POSIX file permission model.
> They are designed to work seamlessly locally as well as across the NFSv4 and
> CIFS/SMB2 network file system protocols.
> 
> A user-space utility for displaying and changing richacls is available at [4]
> (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> 
> [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> 
> To test richacl on ext4 use -o richacl mount option. This mount option may later be
> dropped in favour of a feature flag.
> 
> More details regarding richacl can be found at
> http://acl.bestbits.at/richacl/
> 
> Changes from v5:
> a) rebase to v3.1-rc4-131-g9e79e3e
> 
> NOTE: The kernel changes will be pushed to
> git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> when kernel.org is back

Acked-by: David Howells <dhowells@redhat.com> for all patches generally where
I haven't found anything bad.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-09 12:48   ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-09 12:48 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:

> The following set of patches implements VFS and ext4 changes needed to implement
> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> extended by file masks to fit into the standard POSIX file permission model.
> They are designed to work seamlessly locally as well as across the NFSv4 and
> CIFS/SMB2 network file system protocols.
> 
> A user-space utility for displaying and changing richacls is available at [4]
> (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> 
> [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> 
> To test richacl on ext4 use -o richacl mount option. This mount option may later be
> dropped in favour of a feature flag.
> 
> More details regarding richacl can be found at
> http://acl.bestbits.at/richacl/
> 
> Changes from v5:
> a) rebase to v3.1-rc4-131-g9e79e3e
> 
> NOTE: The kernel changes will be pushed to
> git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> when kernel.org is back

Acked-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> for all patches generally where
I haven't found anything bad.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-09 14:03   ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-09 14:03 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

David Howells <dhowells@redhat.com> wrote:

> Acked-by: David Howells <dhowells@redhat.com> for all patches generally where
> I haven't found anything bad.

Having said that, there's a distinct lack of changes in the Documentation
directory...

David

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-09 14:03   ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-09 14:03 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:

> Acked-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> for all patches generally where
> I haven't found anything bad.

Having said that, there's a distinct lack of changes in the Documentation
directory...

David
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
  2011-09-08  0:46     ` Valdis.Kletnieks-PjAqaU27lzQ
  (?)
@ 2011-09-12 21:34     ` Casey Schaufler
  2011-09-12 22:20       ` J. Bruce Fields
  2011-09-13 18:12       ` Valdis.Kletnieks
  -1 siblings, 2 replies; 116+ messages in thread
From: Casey Schaufler @ 2011-09-12 21:34 UTC (permalink / raw)
  To: Valdis.Kletnieks
  Cc: Aneesh Kumar K.V, agruen, bfields, akpm, dhowells, linux-fsdevel,
	linux-nfs, linux-kernel, LSM, Casey Schaufler

On 9/7/2011 5:46 PM, Valdis.Kletnieks@vt.edu wrote:
> On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
>> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
>>> The following set of patches implements VFS and ext4 changes needed to implement
>>> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
>>> extended by file( masks to fit into the standard POSIX file permission model.
>>> They are designed to work seamlessly locally as well as across the NFSv4 and
>>> CIFS/SMB2 network file system protocols.
>>
>> POSIX ACLs predate the LSM and can't be done as an LSM due to
>> the interactions between mode bits and ACLs as defined by the
>> POSIX DRAFT specification. Is there a reason that "rich" ACLs
>> can not be done as an LSM?
>
> Well, if it was done as an LSM, it would mean that if I wanted to build a
> system where I have a few hundred terabytes of disk exported via Samba, and I
> wanted Samba to save the CIFS permission ACL, I couldn't also run Selinux or
> SMACK or anything like that - unless somebody actually snuck in the "LSMs are
> stackable" patch while I wasn't looking?
>
 
True, but not an acceptable argument for not doing it as an LSM.
It is an argument in favor of LSM stacking, and after the Linux
Security Summit this past week it seems only a matter of time before
we have that. This could be the compelling use case that we've been
missing for LSM stacking.
 
So at this point, unless there is another reason why it can't be an
LSM it should be an LSM.
 


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
  2011-09-12 21:34     ` Casey Schaufler
@ 2011-09-12 22:20       ` J. Bruce Fields
  2011-09-12 22:38           ` Casey Schaufler
  2011-09-13 18:12       ` Valdis.Kletnieks
  1 sibling, 1 reply; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-12 22:20 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Valdis.Kletnieks, Aneesh Kumar K.V, agruen, akpm, dhowells,
	linux-fsdevel, linux-nfs, linux-kernel, LSM

On Mon, Sep 12, 2011 at 02:34:04PM -0700, Casey Schaufler wrote:
> On 9/7/2011 5:46 PM, Valdis.Kletnieks@vt.edu wrote:
> > On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
> >> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
> >>> The following set of patches implements VFS and ext4 changes needed to implement
> >>> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> >>> extended by file( masks to fit into the standard POSIX file permission model.
> >>> They are designed to work seamlessly locally as well as across the NFSv4 and
> >>> CIFS/SMB2 network file system protocols.
> >>
> >> POSIX ACLs predate the LSM and can't be done as an LSM due to
> >> the interactions between mode bits and ACLs as defined by the
> >> POSIX DRAFT specification.

I don't know LSM so don't understand what you mean when you say that
interactions between mode bits and ACLs would make an ACL model hard to
implement as an LSM.

But in any case the rich acl/mode bit interactions are similar to the
posix acl/mode bit interactions, so the same issue probably applies.

--b.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-12 22:23     ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-12 22:23 UTC (permalink / raw)
  To: David Howells
  Cc: Aneesh Kumar K.V, agruen, akpm, linux-fsdevel, linux-nfs, linux-kernel

On Fri, Sep 09, 2011 at 03:03:36PM +0100, David Howells wrote:
> David Howells <dhowells@redhat.com> wrote:
> 
> > Acked-by: David Howells <dhowells@redhat.com> for all patches generally where
> > I haven't found anything bad.
> 
> Having said that, there's a distinct lack of changes in the Documentation
> directory...

Probably the documentation belongs in man pages.  Which I think they've
done, but alas the git repos (on kernel.org) aren't accesible right
now....

--b.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-12 22:23     ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-12 22:23 UTC (permalink / raw)
  To: David Howells
  Cc: Aneesh Kumar K.V, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, Sep 09, 2011 at 03:03:36PM +0100, David Howells wrote:
> David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> 
> > Acked-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> for all patches generally where
> > I haven't found anything bad.
> 
> Having said that, there's a distinct lack of changes in the Documentation
> directory...

Probably the documentation belongs in man pages.  Which I think they've
done, but alas the git repos (on kernel.org) aren't accesible right
now....

--b.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-12 22:27     ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-12 22:27 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: dhowells, Aneesh Kumar K.V, agruen, akpm, linux-fsdevel,
	linux-nfs, linux-kernel

J. Bruce Fields <bfields@fieldses.org> wrote:

> Probably the documentation belongs in man pages.  Which I think they've
> done, but alas the git repos (on kernel.org) aren't accesible right
> now....

There is also an in-kernel API that filesystems have to deal with if they want
to support richacls.  See the ext4 patches...  There should probably be one
document describing how to 'use' ACLs of all kinds from a filesystem internals
point of view somewhere under Documentation/filesystems/

David

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-12 22:27     ` David Howells
  0 siblings, 0 replies; 116+ messages in thread
From: David Howells @ 2011-09-12 22:27 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Aneesh Kumar K.V,
	agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

J. Bruce Fields <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:

> Probably the documentation belongs in man pages.  Which I think they've
> done, but alas the git repos (on kernel.org) aren't accesible right
> now....

There is also an in-kernel API that filesystems have to deal with if they want
to support richacls.  See the ext4 patches...  There should probably be one
document describing how to 'use' ACLs of all kinds from a filesystem internals
point of view somewhere under Documentation/filesystems/

David
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-12 22:38           ` Casey Schaufler
  0 siblings, 0 replies; 116+ messages in thread
From: Casey Schaufler @ 2011-09-12 22:38 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: Valdis.Kletnieks, Aneesh Kumar K.V, agruen, akpm, dhowells,
	linux-fsdevel, linux-nfs, linux-kernel, LSM, Casey Schaufler

On 9/12/2011 3:20 PM, J. Bruce Fields wrote:
> On Mon, Sep 12, 2011 at 02:34:04PM -0700, Casey Schaufler wrote:
>> On 9/7/2011 5:46 PM, Valdis.Kletnieks@vt.edu wrote:
>>> On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
>>>> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
>>>>> The following set of patches implements VFS and ext4 changes needed to implement
>>>>> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
>>>>> extended by file( masks to fit into the standard POSIX file permission model.
>>>>> They are designed to work seamlessly locally as well as across the NFSv4 and
>>>>> CIFS/SMB2 network file system protocols.
>>>> POSIX ACLs predate the LSM and can't be done as an LSM due to
>>>> the interactions between mode bits and ACLs as defined by the
>>>> POSIX DRAFT specification.
> I don't know LSM so don't understand what you mean when you say that
> interactions between mode bits and ACLs would make an ACL model hard to
> implement as an LSM.

POSIX ACLs require that the file permission bits change when
the ACL changes. This interaction violates the strict "additional
restriction" model of the LSM.


> But in any case the rich acl/mode bit interactions are similar to the
> posix acl/mode bit interactions, so the same issue probably applies.

It would help if you knew for sure and could explain the interaction
in sufficient detail to justify the position.

>
> --b.
>


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-12 22:38           ` Casey Schaufler
  0 siblings, 0 replies; 116+ messages in thread
From: Casey Schaufler @ 2011-09-12 22:38 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: Valdis.Kletnieks-PjAqaU27lzQ, Aneesh Kumar K.V,
	agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, LSM, Casey Schaufler

On 9/12/2011 3:20 PM, J. Bruce Fields wrote:
> On Mon, Sep 12, 2011 at 02:34:04PM -0700, Casey Schaufler wrote:
>> On 9/7/2011 5:46 PM, Valdis.Kletnieks-PjAqaU27lzQ@public.gmane.org wrote:
>>> On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
>>>> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
>>>>> The following set of patches implements VFS and ext4 changes needed to implement
>>>>> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
>>>>> extended by file( masks to fit into the standard POSIX file permission model.
>>>>> They are designed to work seamlessly locally as well as across the NFSv4 and
>>>>> CIFS/SMB2 network file system protocols.
>>>> POSIX ACLs predate the LSM and can't be done as an LSM due to
>>>> the interactions between mode bits and ACLs as defined by the
>>>> POSIX DRAFT specification.
> I don't know LSM so don't understand what you mean when you say that
> interactions between mode bits and ACLs would make an ACL model hard to
> implement as an LSM.

POSIX ACLs require that the file permission bits change when
the ACL changes. This interaction violates the strict "additional
restriction" model of the LSM.


> But in any case the rich acl/mode bit interactions are similar to the
> posix acl/mode bit interactions, so the same issue probably applies.

It would help if you knew for sure and could explain the interaction
in sufficient detail to justify the position.

>
> --b.
>

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
  2011-09-12 22:38           ` Casey Schaufler
  (?)
@ 2011-09-12 22:43           ` J. Bruce Fields
  2011-09-12 23:23             ` Casey Schaufler
  -1 siblings, 1 reply; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-12 22:43 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Valdis.Kletnieks, Aneesh Kumar K.V, agruen, akpm, dhowells,
	linux-fsdevel, linux-nfs, linux-kernel, LSM

On Mon, Sep 12, 2011 at 03:38:24PM -0700, Casey Schaufler wrote:
> On 9/12/2011 3:20 PM, J. Bruce Fields wrote:
> > On Mon, Sep 12, 2011 at 02:34:04PM -0700, Casey Schaufler wrote:
> >> On 9/7/2011 5:46 PM, Valdis.Kletnieks@vt.edu wrote:
> >>> On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
> >>>> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
> >>>>> The following set of patches implements VFS and ext4 changes needed to implement
> >>>>> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> >>>>> extended by file( masks to fit into the standard POSIX file permission model.
> >>>>> They are designed to work seamlessly locally as well as across the NFSv4 and
> >>>>> CIFS/SMB2 network file system protocols.
> >>>> POSIX ACLs predate the LSM and can't be done as an LSM due to
> >>>> the interactions between mode bits and ACLs as defined by the
> >>>> POSIX DRAFT specification.
> > I don't know LSM so don't understand what you mean when you say that
> > interactions between mode bits and ACLs would make an ACL model hard to
> > implement as an LSM.
> 
> POSIX ACLs require that the file permission bits change when
> the ACL changes. This interaction violates the strict "additional
> restriction" model of the LSM.

Oh, OK.  Yes, rich ACLs are the same as POSIX ACLs in this respect.
When you set an ACL the mode bits are reset to represent an "upper
bound" on the permissions granted by the ACL.

--b.

> > But in any case the rich acl/mode bit interactions are similar to the
> > posix acl/mode bit interactions, so the same issue probably applies.
> 
> It would help if you knew for sure and could explain the interaction
> in sufficient detail to justify the position.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
  2011-09-12 22:43           ` J. Bruce Fields
@ 2011-09-12 23:23             ` Casey Schaufler
  2011-09-12 23:53                 ` J. Bruce Fields
  0 siblings, 1 reply; 116+ messages in thread
From: Casey Schaufler @ 2011-09-12 23:23 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: Valdis.Kletnieks, Aneesh Kumar K.V, agruen, akpm, dhowells,
	linux-fsdevel, linux-nfs, linux-kernel, LSM, Casey Schaufler

On 9/12/2011 3:43 PM, J. Bruce Fields wrote:
> On Mon, Sep 12, 2011 at 03:38:24PM -0700, Casey Schaufler wrote:
>> On 9/12/2011 3:20 PM, J. Bruce Fields wrote:
>>> On Mon, Sep 12, 2011 at 02:34:04PM -0700, Casey Schaufler wrote:
>>>> On 9/7/2011 5:46 PM, Valdis.Kletnieks@vt.edu wrote:
>>>>> On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
>>>>>> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
>>>>>>> The following set of patches implements VFS and ext4 changes needed to implement
>>>>>>> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
>>>>>>> extended by file( masks to fit into the standard POSIX file permission model.
>>>>>>> They are designed to work seamlessly locally as well as across the NFSv4 and
>>>>>>> CIFS/SMB2 network file system protocols.
>>>>>> POSIX ACLs predate the LSM and can't be done as an LSM due to
>>>>>> the interactions between mode bits and ACLs as defined by the
>>>>>> POSIX DRAFT specification.
>>> I don't know LSM so don't understand what you mean when you say that
>>> interactions between mode bits and ACLs would make an ACL model hard to
>>> implement as an LSM.
>> POSIX ACLs require that the file permission bits change when
>> the ACL changes. This interaction violates the strict "additional
>> restriction" model of the LSM.
> Oh, OK.  Yes, rich ACLs are the same as POSIX ACLs in this respect.
> When you set an ACL the mode bits are reset to represent an "upper
> bound" on the permissions granted by the ACL.

One of the areas in which the POSIX group was careful almost beyond
reason was the program that uses chmod() judiciously in the absence
of ACLs and how the presence of ACLs might result in a less secure
situation. Thus, a program that does
    stat(..., &buf);
    chmod(..., 0);
    chmod(..., buf.st_mode)

should get the exact same access at the end as it had at the beginning
and the file must be completely inaccessible after the chmod(..., 0)
regardless of the content of the ACL. Without this requirement the ACL
scheme would have worked fine as an LSM. If rich ACLs can't make these
claims, they aren't safe.

>
> --b.
>
>>> But in any case the rich acl/mode bit interactions are similar to the
>>> posix acl/mode bit interactions, so the same issue probably applies.
>> It would help if you knew for sure and could explain the interaction
>> in sufficient detail to justify the position.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-12 23:53                 ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-12 23:53 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Valdis.Kletnieks, Aneesh Kumar K.V, agruen, akpm, dhowells,
	linux-fsdevel, linux-nfs, linux-kernel, LSM

On Mon, Sep 12, 2011 at 04:23:24PM -0700, Casey Schaufler wrote:
> On 9/12/2011 3:43 PM, J. Bruce Fields wrote:
> > On Mon, Sep 12, 2011 at 03:38:24PM -0700, Casey Schaufler wrote:
> >> On 9/12/2011 3:20 PM, J. Bruce Fields wrote:
> >>> On Mon, Sep 12, 2011 at 02:34:04PM -0700, Casey Schaufler wrote:
> >>>> On 9/7/2011 5:46 PM, Valdis.Kletnieks@vt.edu wrote:
> >>>>> On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
> >>>>>> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
> >>>>>>> The following set of patches implements VFS and ext4 changes needed to implement
> >>>>>>> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> >>>>>>> extended by file( masks to fit into the standard POSIX file permission model.
> >>>>>>> They are designed to work seamlessly locally as well as across the NFSv4 and
> >>>>>>> CIFS/SMB2 network file system protocols.
> >>>>>> POSIX ACLs predate the LSM and can't be done as an LSM due to
> >>>>>> the interactions between mode bits and ACLs as defined by the
> >>>>>> POSIX DRAFT specification.
> >>> I don't know LSM so don't understand what you mean when you say that
> >>> interactions between mode bits and ACLs would make an ACL model hard to
> >>> implement as an LSM.
> >> POSIX ACLs require that the file permission bits change when
> >> the ACL changes. This interaction violates the strict "additional
> >> restriction" model of the LSM.
> > Oh, OK.  Yes, rich ACLs are the same as POSIX ACLs in this respect.
> > When you set an ACL the mode bits are reset to represent an "upper
> > bound" on the permissions granted by the ACL.
> 
> One of the areas in which the POSIX group was careful almost beyond
> reason was the program that uses chmod() judiciously in the absence
> of ACLs and how the presence of ACLs might result in a less secure
> situation. Thus, a program that does
>     stat(..., &buf);
>     chmod(..., 0);
>     chmod(..., buf.st_mode)
> 
> should get the exact same access at the end as it had at the beginning
> and the file must be completely inaccessible after the chmod(..., 0)
> regardless of the content of the ACL. Without this requirement the ACL
> scheme would have worked fine as an LSM. If rich ACLs can't make these
> claims, they aren't safe.

Yes, see the patches--rich ACLs have the same property, using a similar
mechanism.  (They're essentially windows/NFSv4 ACLs + mask bits.)

--b.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-12 23:53                 ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-12 23:53 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Valdis.Kletnieks-PjAqaU27lzQ, Aneesh Kumar K.V,
	agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, LSM

On Mon, Sep 12, 2011 at 04:23:24PM -0700, Casey Schaufler wrote:
> On 9/12/2011 3:43 PM, J. Bruce Fields wrote:
> > On Mon, Sep 12, 2011 at 03:38:24PM -0700, Casey Schaufler wrote:
> >> On 9/12/2011 3:20 PM, J. Bruce Fields wrote:
> >>> On Mon, Sep 12, 2011 at 02:34:04PM -0700, Casey Schaufler wrote:
> >>>> On 9/7/2011 5:46 PM, Valdis.Kletnieks-PjAqaU27lzQ@public.gmane.org wrote:
> >>>>> On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
> >>>>>> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
> >>>>>>> The following set of patches implements VFS and ext4 changes needed to implement
> >>>>>>> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> >>>>>>> extended by file( masks to fit into the standard POSIX file permission model.
> >>>>>>> They are designed to work seamlessly locally as well as across the NFSv4 and
> >>>>>>> CIFS/SMB2 network file system protocols.
> >>>>>> POSIX ACLs predate the LSM and can't be done as an LSM due to
> >>>>>> the interactions between mode bits and ACLs as defined by the
> >>>>>> POSIX DRAFT specification.
> >>> I don't know LSM so don't understand what you mean when you say that
> >>> interactions between mode bits and ACLs would make an ACL model hard to
> >>> implement as an LSM.
> >> POSIX ACLs require that the file permission bits change when
> >> the ACL changes. This interaction violates the strict "additional
> >> restriction" model of the LSM.
> > Oh, OK.  Yes, rich ACLs are the same as POSIX ACLs in this respect.
> > When you set an ACL the mode bits are reset to represent an "upper
> > bound" on the permissions granted by the ACL.
> 
> One of the areas in which the POSIX group was careful almost beyond
> reason was the program that uses chmod() judiciously in the absence
> of ACLs and how the presence of ACLs might result in a less secure
> situation. Thus, a program that does
>     stat(..., &buf);
>     chmod(..., 0);
>     chmod(..., buf.st_mode)
> 
> should get the exact same access at the end as it had at the beginning
> and the file must be completely inaccessible after the chmod(..., 0)
> regardless of the content of the ACL. Without this requirement the ACL
> scheme would have worked fine as an LSM. If rich ACLs can't make these
> claims, they aren't safe.

Yes, see the patches--rich ACLs have the same property, using a similar
mechanism.  (They're essentially windows/NFSv4 ACLs + mask bits.)

--b.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 25/26] ext4: Implement rich acl for ext4
@ 2011-09-13  4:25     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-13  4:25 UTC (permalink / raw)
  To: David Howells
  Cc: dhowells, agruen, bfields, akpm, linux-fsdevel, linux-nfs, linux-kernel

On Fri, 09 Sep 2011 13:45:58 +0100, David Howells <dhowells@redhat.com> wrote:
> Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> wrote:
> 
> > +	retval = ext4_set_richacl(handle, inode, acl);
> > +	ext4_journal_stop(handle);
> > +	if (retval == ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
> > +		goto retry;
> 
> Should that be -ENOSPC?

Fixed 

> 
> I do wonder, why does ext4 need to know about richacls at all?  Surely, as far
> as ext4 is concerned, they should be seen as xattrs?
> 

richacl related changes to ext4 is minimal. They mostly are to call
necessary permission check functions and to map xattr to richacl
structure.


> If ext4 needs a mark on disk to say it supports richacls, then why can't that
> simply be the presence or lack thereof of a richacl on the root dir?
> 

I have a patch in the full series which enable richacl on ext4 file system
based on ext4 compatibility flags. I didn't add that as a part of this
series to enable easy testing. The goal is to use tune2fs to enable
richacl and them the mount option -o acl enable richacl/posix acl
accordingly. 

-aneesh

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 25/26] ext4: Implement rich acl for ext4
@ 2011-09-13  4:25     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-13  4:25 UTC (permalink / raw)
  To: David Howells
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, 09 Sep 2011 13:45:58 +0100, David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> Aneesh Kumar K.V <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> 
> > +	retval = ext4_set_richacl(handle, inode, acl);
> > +	ext4_journal_stop(handle);
> > +	if (retval == ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
> > +		goto retry;
> 
> Should that be -ENOSPC?

Fixed 

> 
> I do wonder, why does ext4 need to know about richacls at all?  Surely, as far
> as ext4 is concerned, they should be seen as xattrs?
> 

richacl related changes to ext4 is minimal. They mostly are to call
necessary permission check functions and to map xattr to richacl
structure.


> If ext4 needs a mark on disk to say it supports richacls, then why can't that
> simply be the presence or lack thereof of a richacl on the root dir?
> 

I have a patch in the full series which enable richacl on ext4 file system
based on ext4 compatibility flags. I didn't add that as a part of this
series to enable easy testing. The goal is to use tune2fs to enable
richacl and them the mount option -o acl enable richacl/posix acl
accordingly. 

-aneesh
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-13  4:41             ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-13  4:41 UTC (permalink / raw)
  To: Casey Schaufler, J. Bruce Fields
  Cc: Valdis.Kletnieks, agruen, akpm, dhowells, linux-fsdevel,
	linux-nfs, linux-kernel, LSM, Casey Schaufler

On Mon, 12 Sep 2011 15:38:24 -0700, Casey Schaufler <casey@schaufler-ca.com> wrote:
> On 9/12/2011 3:20 PM, J. Bruce Fields wrote:
> > On Mon, Sep 12, 2011 at 02:34:04PM -0700, Casey Schaufler wrote:
> >> On 9/7/2011 5:46 PM, Valdis.Kletnieks@vt.edu wrote:
> >>> On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
> >>>> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
> >>>>> The following set of patches implements VFS and ext4 changes needed to implement
> >>>>> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> >>>>> extended by file( masks to fit into the standard POSIX file permission model.
> >>>>> They are designed to work seamlessly locally as well as across the NFSv4 and
> >>>>> CIFS/SMB2 network file system protocols.
> >>>> POSIX ACLs predate the LSM and can't be done as an LSM due to
> >>>> the interactions between mode bits and ACLs as defined by the
> >>>> POSIX DRAFT specification.
> > I don't know LSM so don't understand what you mean when you say that
> > interactions between mode bits and ACLs would make an ACL model hard to
> > implement as an LSM.
> 
> POSIX ACLs require that the file permission bits change when
> the ACL changes. This interaction violates the strict "additional
> restriction" model of the LSM.
> 
> 
> > But in any case the rich acl/mode bit interactions are similar to the
> > posix acl/mode bit interactions, so the same issue probably applies.
> 
> It would help if you knew for sure and could explain the interaction
> in sufficient detail to justify the position.
> 

Andreas have documented the details here
http://acl.bestbits.at/richacl/draft-gruenbacher-nfsv4-acls-in-posix-00.html

In short with respect to mode bits, the interaction between acl/mode
bits is more or less similar between posix acl and richacl. When we set
richacl we need to make sure that mode bits represent allowed permission
on the file system object. We need to do the above to be posix
compliant.  As per POSIX additional file access control mechanisms may
only further restrict the access permissions defined by the file
permission bits. You can find further details in the OLS 2010 paper on
richacl. http://www.fmeh.org/ols-2010-implementing-richacl-paper.pdf


-aneesh




^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
@ 2011-09-13  4:41             ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-13  4:41 UTC (permalink / raw)
  To: Casey Schaufler, J. Bruce Fields
  Cc: Valdis.Kletnieks-PjAqaU27lzQ, agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, LSM, Casey Schaufler

On Mon, 12 Sep 2011 15:38:24 -0700, Casey Schaufler <casey-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org> wrote:
> On 9/12/2011 3:20 PM, J. Bruce Fields wrote:
> > On Mon, Sep 12, 2011 at 02:34:04PM -0700, Casey Schaufler wrote:
> >> On 9/7/2011 5:46 PM, Valdis.Kletnieks-PjAqaU27lzQ@public.gmane.org wrote:
> >>> On Mon, 05 Sep 2011 15:42:17 PDT, Casey Schaufler said:
> >>>> On 9/5/2011 10:25 AM, Aneesh Kumar K.V wrote:
> >>>>> The following set of patches implements VFS and ext4 changes needed to implement
> >>>>> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> >>>>> extended by file( masks to fit into the standard POSIX file permission model.
> >>>>> They are designed to work seamlessly locally as well as across the NFSv4 and
> >>>>> CIFS/SMB2 network file system protocols.
> >>>> POSIX ACLs predate the LSM and can't be done as an LSM due to
> >>>> the interactions between mode bits and ACLs as defined by the
> >>>> POSIX DRAFT specification.
> > I don't know LSM so don't understand what you mean when you say that
> > interactions between mode bits and ACLs would make an ACL model hard to
> > implement as an LSM.
> 
> POSIX ACLs require that the file permission bits change when
> the ACL changes. This interaction violates the strict "additional
> restriction" model of the LSM.
> 
> 
> > But in any case the rich acl/mode bit interactions are similar to the
> > posix acl/mode bit interactions, so the same issue probably applies.
> 
> It would help if you knew for sure and could explain the interaction
> in sufficient detail to justify the position.
> 

Andreas have documented the details here
http://acl.bestbits.at/richacl/draft-gruenbacher-nfsv4-acls-in-posix-00.html

In short with respect to mode bits, the interaction between acl/mode
bits is more or less similar between posix acl and richacl. When we set
richacl we need to make sure that mode bits represent allowed permission
on the file system object. We need to do the above to be posix
compliant.  As per POSIX additional file access control mechanisms may
only further restrict the access permissions defined by the file
permission bits. You can find further details in the OLS 2010 paper on
richacl. http://www.fmeh.org/ols-2010-implementing-richacl-paper.pdf


-aneesh



--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
  2011-09-12 22:27     ` David Howells
  (?)
@ 2011-09-13  5:07     ` Aneesh Kumar K.V
  -1 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-13  5:07 UTC (permalink / raw)
  To: David Howells, J. Bruce Fields
  Cc: dhowells, agruen, akpm, linux-fsdevel, linux-nfs, linux-kernel

On Mon, 12 Sep 2011 23:27:02 +0100, David Howells <dhowells@redhat.com> wrote:
> J. Bruce Fields <bfields@fieldses.org> wrote:
> 
> > Probably the documentation belongs in man pages.  Which I think they've
> > done, but alas the git repos (on kernel.org) aren't accesible right
> > now....
> 
> There is also an in-kernel API that filesystems have to deal with if they want
> to support richacls.  See the ext4 patches...  There should probably be one
> document describing how to 'use' ACLs of all kinds from a filesystem internals
> point of view somewhere under Documentation/filesystems/
> 

setattr callback should call richacl_chmod when called with ATTR_MODE
and we should have new xattr callbacks for "system.richacl" . Those are
the only two changes needed for file system.

-aneesh

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability
  2011-09-12 21:34     ` Casey Schaufler
  2011-09-12 22:20       ` J. Bruce Fields
@ 2011-09-13 18:12       ` Valdis.Kletnieks
  1 sibling, 0 replies; 116+ messages in thread
From: Valdis.Kletnieks @ 2011-09-13 18:12 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Aneesh Kumar K.V, agruen, bfields, akpm, dhowells, linux-fsdevel,
	linux-nfs, linux-kernel, LSM

[-- Attachment #1: Type: text/plain, Size: 2029 bytes --]

(merging two replies)

On Mon, 12 Sep 2011 14:34:04 PDT, Casey Schaufler said:
> > Well, if it was done as an LSM, it would mean that if I wanted to build a
> > system where I have a few hundred terabytes of disk exported via Samba, and I
> > wanted Samba to save the CIFS permission ACL, I couldn't also run Selinux or
> > SMACK or anything like that - unless somebody actually snuck in the "LSMs are
> > stackable" patch while I wasn't looking?

> True, but not an acceptable argument for not doing it as an LSM.
> It is an argument in favor of LSM stacking, and after the Linux
> Security Summit this past week it seems only a matter of time before
> we have that. This could be the compelling use case that we've been
> missing for LSM stacking.

OK, I can certainly agree with that logic..

> So at this point, unless there is another reason why it can't be an
> LSM it should be an LSM.

Well, this issue still:

On Mon, 12 Sep 2011 18:43:51 EDT, "J. Bruce Fields" said:
> On Mon, Sep 12, 2011 at 03:38:24PM -0700, Casey Schaufler wrote:
> > POSIX ACLs require that the file permission bits change when
> > the ACL changes. This interaction violates the strict "additional
> > restriction" model of the LSM.
>
> Oh, OK.  Yes, rich ACLs are the same as POSIX ACLs in this respect.
> When you set an ACL the mode bits are reset to represent an "upper
> bound" on the permissions granted by the ACL.

Can we finess this detail by making the "set an ACL and make needed changes to
the mode bits" part of the VFS's responsibility as part of whatever syscall/
ioctl handling?  After all, the LSM doesn't get involved in the handling of
chmod() other than to say "yes/no this chmod can be issued" -  for instance,
the clearing of setUID/setGID bits when a file is written is done by each
individual filesystem. So there's certianly precident for doing the permission
tweaking in the VFS code. Then we can limit the LSM part to *applying* an
already existing ACL to permission checking.

Or should I go get some more caffeine? ;)


[-- Attachment #2: Type: application/pgp-signature, Size: 227 bytes --]

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
  2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
                   ` (36 preceding siblings ...)
  2011-09-09 14:03   ` David Howells
@ 2011-09-21  7:30 ` Aneesh Kumar K.V
  2011-09-21 19:45     ` J. Bruce Fields
  37 siblings, 1 reply; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-21  7:30 UTC (permalink / raw)
  To: agruen, bfields, akpm, dhowells; +Cc: linux-fsdevel, linux-nfs, linux-kernel

On Mon,  5 Sep 2011 22:55:22 +0530, "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> wrote:
> Hi,
> 
> The following set of patches implements VFS and ext4 changes needed to implement
> a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> extended by file masks to fit into the standard POSIX file permission model.
> They are designed to work seamlessly locally as well as across the NFSv4 and
> CIFS/SMB2 network file system protocols.
> 
> A user-space utility for displaying and changing richacls is available at [4]
> (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> 
> [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> 
> To test richacl on ext4 use -o richacl mount option. This mount option may later be
> dropped in favour of a feature flag.
> 
> More details regarding richacl can be found at
> http://acl.bestbits.at/richacl/
> 
> Changes from v5:
> a) rebase to v3.1-rc4-131-g9e79e3e
> 
> NOTE: The kernel changes will be pushed to
> git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> when kernel.org is back
> 

I pushed the kernel changes to

git://github.com/kvaneesh/linux.git richacl

Userspace code can be found at 

git://github.com/kvaneesh/richacl-tools.git

-aneesh

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-21 19:45     ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-21 19:45 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Wed, Sep 21, 2011 at 01:00:43PM +0530, Aneesh Kumar K.V wrote:
> On Mon,  5 Sep 2011 22:55:22 +0530, "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> wrote:
> > Hi,
> > 
> > The following set of patches implements VFS and ext4 changes needed to implement
> > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > extended by file masks to fit into the standard POSIX file permission model.
> > They are designed to work seamlessly locally as well as across the NFSv4 and
> > CIFS/SMB2 network file system protocols.
> > 
> > A user-space utility for displaying and changing richacls is available at [4]
> > (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> > 
> > [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> > 
> > To test richacl on ext4 use -o richacl mount option. This mount option may later be
> > dropped in favour of a feature flag.
> > 
> > More details regarding richacl can be found at
> > http://acl.bestbits.at/richacl/
> > 
> > Changes from v5:
> > a) rebase to v3.1-rc4-131-g9e79e3e
> > 
> > NOTE: The kernel changes will be pushed to
> > git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> > when kernel.org is back
> > 
> 
> I pushed the kernel changes to
> 
> git://github.com/kvaneesh/linux.git richacl

Thanks!  This doesn't seem to have the branch with the followup patches
for nfsd?

--b.

> 
> Userspace code can be found at 
> 
> git://github.com/kvaneesh/richacl-tools.git
> 
> -aneesh
> 

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-21 19:45     ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-21 19:45 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Wed, Sep 21, 2011 at 01:00:43PM +0530, Aneesh Kumar K.V wrote:
> On Mon,  5 Sep 2011 22:55:22 +0530, "Aneesh Kumar K.V" <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> > Hi,
> > 
> > The following set of patches implements VFS and ext4 changes needed to implement
> > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > extended by file masks to fit into the standard POSIX file permission model.
> > They are designed to work seamlessly locally as well as across the NFSv4 and
> > CIFS/SMB2 network file system protocols.
> > 
> > A user-space utility for displaying and changing richacls is available at [4]
> > (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> > 
> > [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> > 
> > To test richacl on ext4 use -o richacl mount option. This mount option may later be
> > dropped in favour of a feature flag.
> > 
> > More details regarding richacl can be found at
> > http://acl.bestbits.at/richacl/
> > 
> > Changes from v5:
> > a) rebase to v3.1-rc4-131-g9e79e3e
> > 
> > NOTE: The kernel changes will be pushed to
> > git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> > when kernel.org is back
> > 
> 
> I pushed the kernel changes to
> 
> git://github.com/kvaneesh/linux.git richacl

Thanks!  This doesn't seem to have the branch with the followup patches
for nfsd?

--b.

> 
> Userspace code can be found at 
> 
> git://github.com/kvaneesh/richacl-tools.git
> 
> -aneesh
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-22  5:31       ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-22  5:31 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Wed, 21 Sep 2011 15:45:31 -0400, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Wed, Sep 21, 2011 at 01:00:43PM +0530, Aneesh Kumar K.V wrote:
> > On Mon,  5 Sep 2011 22:55:22 +0530, "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> wrote:
> > > Hi,
> > > 
> > > The following set of patches implements VFS and ext4 changes needed to implement
> > > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > > extended by file masks to fit into the standard POSIX file permission model.
> > > They are designed to work seamlessly locally as well as across the NFSv4 and
> > > CIFS/SMB2 network file system protocols.
> > > 
> > > A user-space utility for displaying and changing richacls is available at [4]
> > > (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> > > 
> > > [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> > > 
> > > To test richacl on ext4 use -o richacl mount option. This mount option may later be
> > > dropped in favour of a feature flag.
> > > 
> > > More details regarding richacl can be found at
> > > http://acl.bestbits.at/richacl/
> > > 
> > > Changes from v5:
> > > a) rebase to v3.1-rc4-131-g9e79e3e
> > > 
> > > NOTE: The kernel changes will be pushed to
> > > git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> > > when kernel.org is back
> > > 
> > 
> > I pushed the kernel changes to
> > 
> > git://github.com/kvaneesh/linux.git richacl
> 
> Thanks!  This doesn't seem to have the branch with the followup patches
> for nfsd?
> 

richacl-fullset branch should have the full patchset including nfsd
changes. The changes are based on an older kernel version. Currently i
am planning to focus on the local file system and VFS changes so that we
can get that merged upstream.


-aneesh


^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-22  5:31       ` Aneesh Kumar K.V
  0 siblings, 0 replies; 116+ messages in thread
From: Aneesh Kumar K.V @ 2011-09-22  5:31 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Wed, 21 Sep 2011 15:45:31 -0400, "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> On Wed, Sep 21, 2011 at 01:00:43PM +0530, Aneesh Kumar K.V wrote:
> > On Mon,  5 Sep 2011 22:55:22 +0530, "Aneesh Kumar K.V" <aneesh.kumar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> > > Hi,
> > > 
> > > The following set of patches implements VFS and ext4 changes needed to implement
> > > a new acl model for linux. Rich ACLs are an implementation of NFSv4 ACLs,
> > > extended by file masks to fit into the standard POSIX file permission model.
> > > They are designed to work seamlessly locally as well as across the NFSv4 and
> > > CIFS/SMB2 network file system protocols.
> > > 
> > > A user-space utility for displaying and changing richacls is available at [4]
> > > (a number of examples can be found at http://acl.bestbits.at/richacl/examples.html).
> > > 
> > > [4] git://git.kernel.org/pub/scm/fs/acl/kvaneesh/richacl.git master
> > > 
> > > To test richacl on ext4 use -o richacl mount option. This mount option may later be
> > > dropped in favour of a feature flag.
> > > 
> > > More details regarding richacl can be found at
> > > http://acl.bestbits.at/richacl/
> > > 
> > > Changes from v5:
> > > a) rebase to v3.1-rc4-131-g9e79e3e
> > > 
> > > NOTE: The kernel changes will be pushed to
> > > git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-richacl.git richacl
> > > when kernel.org is back
> > > 
> > 
> > I pushed the kernel changes to
> > 
> > git://github.com/kvaneesh/linux.git richacl
> 
> Thanks!  This doesn't seem to have the branch with the followup patches
> for nfsd?
> 

richacl-fullset branch should have the full patchset including nfsd
changes. The changes are based on an older kernel version. Currently i
am planning to focus on the local file system and VFS changes so that we
can get that merged upstream.


-aneesh

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-22 12:01         ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-22 12:01 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen, akpm, dhowells, linux-fsdevel, linux-nfs, linux-kernel

On Thu, Sep 22, 2011 at 11:01:41AM +0530, Aneesh Kumar K.V wrote:
> richacl-fullset branch should have the full patchset including nfsd
> changes. The changes are based on an older kernel version.

Got it, thanks!

> Currently i
> am planning to focus on the local file system and VFS changes so that we
> can get that merged upstream.

Understood.

--b.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH -V6 00/26]  New ACL format for better NFSv4 acl interoperability
@ 2011-09-22 12:01         ` J. Bruce Fields
  0 siblings, 0 replies; 116+ messages in thread
From: J. Bruce Fields @ 2011-09-22 12:01 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: agruen-DgEjT+Ai2ygdnm+yROfE0A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Thu, Sep 22, 2011 at 11:01:41AM +0530, Aneesh Kumar K.V wrote:
> richacl-fullset branch should have the full patchset including nfsd
> changes. The changes are based on an older kernel version.

Got it, thanks!

> Currently i
> am planning to focus on the local file system and VFS changes so that we
> can get that merged upstream.

Understood.

--b.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 116+ messages in thread

end of thread, other threads:[~2011-09-22 12:01 UTC | newest]

Thread overview: 116+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-05 17:25 [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 01/26] vfs: Indicate that the permission functions take all the MAY_* flags Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 02/26] vfs: Add hex format for MAY_* flag values Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 03/26] vfs: Pass all mask flags down to iop->check_acl Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 04/26] vfs: Add a comment to inode_permission() Aneesh Kumar K.V
2011-09-05 17:25   ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 05/26] vfs: Add generic IS_ACL() test for acl support Aneesh Kumar K.V
2011-09-05 17:25   ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 06/26] vfs: Add IS_RICHACL() test for richacl support Aneesh Kumar K.V
2011-09-05 17:25   ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 07/26] vfs: Optimize out IS_RICHACL() if CONFIG_FS_RICHACL is not defined Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 08/26] vfs: Add new file and directory create permission flags Aneesh Kumar K.V
2011-09-05 17:25   ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 09/26] vfs: Add delete child and delete self " Aneesh Kumar K.V
2011-09-07 20:39   ` J. Bruce Fields
2011-09-07 20:39     ` J. Bruce Fields
2011-09-08  9:30     ` Aneesh Kumar K.V
2011-09-08 20:07       ` J. Bruce Fields
2011-09-08 22:02         ` J. Bruce Fields
2011-09-09  5:19           ` Aneesh Kumar K.V
2011-09-09  5:19             ` Aneesh Kumar K.V
2011-09-09  5:25             ` Aneesh Kumar K.V
2011-09-09 12:02               ` J. Bruce Fields
2011-09-09  5:14         ` Aneesh Kumar K.V
2011-09-09  5:14           ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 10/26] vfs: Make the inode passed to inode_change_ok non-const Aneesh Kumar K.V
2011-09-07 20:43   ` J. Bruce Fields
2011-09-08  9:32     ` Aneesh Kumar K.V
2011-09-08  9:32       ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 11/26] vfs: Add permission flags for setting file attributes Aneesh Kumar K.V
2011-09-05 17:25   ` Aneesh Kumar K.V
2011-09-07 20:55   ` J. Bruce Fields
2011-09-08  9:36     ` Aneesh Kumar K.V
2011-09-08 20:08       ` J. Bruce Fields
2011-09-05 17:25 ` [PATCH -V6 12/26] vfs: Make acl_permission_check() work for richacls Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 13/26] richacl: In-memory representation and helper functions Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 14/26] richacl: Permission mapping functions Aneesh Kumar K.V
2011-09-05 17:25   ` Aneesh Kumar K.V
2011-09-07 21:24   ` J. Bruce Fields
2011-09-08 10:27     ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 15/26] richacl: Compute maximum file masks from an acl Aneesh Kumar K.V
2011-09-05 17:25   ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 16/26] richacl: Update the file masks in chmod() Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 17/26] richacl: Permission check algorithm Aneesh Kumar K.V
2011-09-07 21:50   ` J. Bruce Fields
2011-09-07 21:50     ` J. Bruce Fields
2011-09-08 10:34     ` Aneesh Kumar K.V
2011-09-08 10:34       ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 18/26] richacl: Create-time inheritance Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 19/26] richacl: Check if an acl is equivalent to a file mode Aneesh Kumar K.V
2011-09-05 17:25   ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 20/26] richacl: Automatic Inheritance Aneesh Kumar K.V
2011-09-07 21:56   ` J. Bruce Fields
2011-09-07 21:56     ` J. Bruce Fields
2011-09-05 17:25 ` [PATCH -V6 21/26] richacl: xattr mapping functions Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 22/26] vfs: Cache richacl in struct inode Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 23/26] vfs: Add richacl permission check Aneesh Kumar K.V
2011-09-05 17:25   ` Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 24/26] ext4: Use IS_POSIXACL() to check for POSIX ACL support Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 25/26] ext4: Implement rich acl for ext4 Aneesh Kumar K.V
2011-09-05 17:25 ` [PATCH -V6 26/26] ext4: Add temporary richacl mount option " Aneesh Kumar K.V
2011-09-05 17:25   ` Aneesh Kumar K.V
2011-09-05 22:42 ` [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability Casey Schaufler
2011-09-05 22:42   ` Casey Schaufler
2011-09-08  0:46   ` Valdis.Kletnieks
2011-09-08  0:46     ` Valdis.Kletnieks-PjAqaU27lzQ
2011-09-12 21:34     ` Casey Schaufler
2011-09-12 22:20       ` J. Bruce Fields
2011-09-12 22:38         ` Casey Schaufler
2011-09-12 22:38           ` Casey Schaufler
2011-09-12 22:43           ` J. Bruce Fields
2011-09-12 23:23             ` Casey Schaufler
2011-09-12 23:53               ` J. Bruce Fields
2011-09-12 23:53                 ` J. Bruce Fields
2011-09-13  4:41           ` Aneesh Kumar K.V
2011-09-13  4:41             ` Aneesh Kumar K.V
2011-09-13 18:12       ` Valdis.Kletnieks
2011-09-06  9:41 ` Steven Whitehouse
2011-09-06 13:58   ` Aneesh Kumar K.V
2011-09-06 13:58     ` Aneesh Kumar K.V
2011-09-07 20:18     ` J. Bruce Fields
2011-09-07 23:44 ` J. Bruce Fields
2011-09-08 10:40   ` Aneesh Kumar K.V
2011-09-08 10:40     ` Aneesh Kumar K.V
2011-09-09 10:02 ` [PATCH -V6 08/26] vfs: Add new file and directory create permission flags David Howells
2011-09-09 11:59   ` Aneesh Kumar K.V
2011-09-09 10:12 ` [PATCH -V6 09/26] vfs: Add delete child and delete self " David Howells
2011-09-09 10:12   ` David Howells
2011-09-09 11:55   ` Aneesh Kumar K.V
2011-09-09 11:55     ` Aneesh Kumar K.V
2011-09-09 10:36 ` [PATCH -V6 14/26] richacl: Permission mapping functions David Howells
2011-09-09 11:54   ` Aneesh Kumar K.V
2011-09-09 11:54     ` Aneesh Kumar K.V
2011-09-09 12:14 ` [PATCH -V6 18/26] richacl: Create-time inheritance David Howells
2011-09-09 12:14   ` David Howells
2011-09-09 12:37 ` [PATCH -V6 22/26] vfs: Cache richacl in struct inode David Howells
2011-09-09 12:37   ` David Howells
2011-09-09 12:45 ` [PATCH -V6 25/26] ext4: Implement rich acl for ext4 David Howells
2011-09-13  4:25   ` Aneesh Kumar K.V
2011-09-13  4:25     ` Aneesh Kumar K.V
2011-09-09 12:48 ` [PATCH -V6 00/26] New ACL format for better NFSv4 acl interoperability David Howells
2011-09-09 12:48   ` David Howells
2011-09-09 14:03 ` David Howells
2011-09-09 14:03   ` David Howells
2011-09-12 22:23   ` J. Bruce Fields
2011-09-12 22:23     ` J. Bruce Fields
2011-09-12 22:27   ` David Howells
2011-09-12 22:27     ` David Howells
2011-09-13  5:07     ` Aneesh Kumar K.V
2011-09-21  7:30 ` Aneesh Kumar K.V
2011-09-21 19:45   ` J. Bruce Fields
2011-09-21 19:45     ` J. Bruce Fields
2011-09-22  5:31     ` Aneesh Kumar K.V
2011-09-22  5:31       ` Aneesh Kumar K.V
2011-09-22 12:01       ` J. Bruce Fields
2011-09-22 12:01         ` J. Bruce Fields

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.