[v15,00/22] Richacls (Core and Ext4)
mbox series

Message ID 1447067343-31479-1-git-send-email-agruenba@redhat.com
Headers show
Series
  • Richacls (Core and Ext4)
Related show

Message

Andreas Gruenbacher Nov. 9, 2015, 11:08 a.m. UTC
Here is another update to the richacl patch queue.  This posting contains
the patches ready to be merged; the patches later in the queue still need
some more review.

Changes since the last posting (http://thread.gmane.org/gmane.linux.kernel.cifs/11221):

 * Replacing an existing file or directory requires to be able to delete
   and recreate it.  A new function may_replace was added to test for replace
   access vs. delete access (may_delete); this simplifies the code and makes it
   more readable.  Without richacls, deleting and creating requires the same
   permissions, and making that distinction wasn't useful.

 * The DELETE permission on a file was accidentally allowing to replace the
   file without also requiring the ADD_FILE permission on the containing
   directory.  This was fixed and a regression test was added to the test
   suite.

 * A comment as to how pages for XDR-encoded ACLs are alocated was added to
   __nfs4_proc_set_acl.  (See the complete patch queue for that.)


The complete patch queue is available in git form here:

  git://git.kernel.org/pub/scm/linux/kernel/git/agruen/linux-richacl.git \
	richacl-2015-11-09


The richacl user-space utilitites, man pages, and test suite are available
here:

  https://github.com/andreas-gruenbacher/richacl


Changes to other user-space packages for richacl are available here:

  https://github.com/andreas-gruenbacher/coreutils
  https://github.com/andreas-gruenbacher/e2fsprogs
  https://github.com/andreas-gruenbacher/xfsprogs-dev
  https://github.com/andreas-gruenbacher/nfs-utils


Please see the richacl homepage for more information:

  http://www.bestbits.at/richacl/


Thanks,
Andreas

Andreas Gruenbacher (20):
  vfs: Add IS_ACL() and IS_RICHACL() tests
  vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags
  vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags
  vfs: Make the inode passed to inode_change_ok non-const
  vfs: Add permission flags for setting file attributes
  richacl: In-memory representation and helper functions
  richacl: Permission mapping functions
  richacl: Compute maximum file masks from an acl
  richacl: Permission check algorithm
  posix_acl: Unexport acl_by_type and make it static
  vfs: Cache base_acl objects in inodes
  vfs: Add get_richacl and set_richacl inode operations
  vfs: Cache richacl in struct inode
  richacl: Update the file masks in chmod()
  richacl: Check if an acl is equivalent to a file mode
  richacl: Create-time inheritance
  richacl: Automatic Inheritance
  richacl: xattr mapping functions
  richacl: Add richacl xattr handler
  vfs: Add richacl permission checking

Aneesh Kumar K.V (2):
  ext4: Add richacl support
  ext4: Add richacl feature flag

 drivers/staging/lustre/lustre/llite/llite_lib.c |   2 +-
 fs/Kconfig                                      |   3 +
 fs/Makefile                                     |   2 +
 fs/attr.c                                       |  81 +++-
 fs/ext4/Kconfig                                 |  11 +
 fs/ext4/Makefile                                |   1 +
 fs/ext4/ext4.h                                  |   6 +-
 fs/ext4/file.c                                  |   3 +
 fs/ext4/ialloc.c                                |  11 +-
 fs/ext4/inode.c                                 |  12 +-
 fs/ext4/namei.c                                 |   5 +
 fs/ext4/richacl.c                               | 142 ++++++
 fs/ext4/richacl.h                               |  40 ++
 fs/ext4/super.c                                 |  49 +-
 fs/ext4/xattr.c                                 |   7 +
 fs/f2fs/acl.c                                   |   4 +-
 fs/inode.c                                      |  15 +-
 fs/jffs2/acl.c                                  |  10 +-
 fs/namei.c                                      | 118 +++--
 fs/posix_acl.c                                  |  50 +--
 fs/richacl_base.c                               | 564 ++++++++++++++++++++++++
 fs/richacl_inode.c                              | 333 ++++++++++++++
 fs/richacl_xattr.c                              | 298 +++++++++++++
 fs/xattr.c                                      |  34 +-
 include/linux/fs.h                              |  60 ++-
 include/linux/posix_acl.h                       |  13 +-
 include/linux/richacl.h                         | 208 +++++++++
 include/linux/richacl_xattr.h                   |  44 ++
 include/uapi/linux/Kbuild                       |   2 +
 include/uapi/linux/fs.h                         |   3 +-
 include/uapi/linux/richacl.h                    | 152 +++++++
 include/uapi/linux/richacl_xattr.h              |  44 ++
 include/uapi/linux/xattr.h                      |   2 +
 33 files changed, 2222 insertions(+), 107 deletions(-)
 create mode 100644 fs/ext4/richacl.c
 create mode 100644 fs/ext4/richacl.h
 create mode 100644 fs/richacl_base.c
 create mode 100644 fs/richacl_inode.c
 create mode 100644 fs/richacl_xattr.c
 create mode 100644 include/linux/richacl.h
 create mode 100644 include/linux/richacl_xattr.h
 create mode 100644 include/uapi/linux/richacl.h
 create mode 100644 include/uapi/linux/richacl_xattr.h

Comments

Christoph Hellwig Nov. 10, 2015, 11:29 a.m. UTC | #1
On Mon, Nov 09, 2015 at 12:08:41PM +0100, Andreas Gruenbacher wrote:
> Here is another update to the richacl patch queue.  This posting contains
> the patches ready to be merged; the patches later in the queue still need
> some more review.

It still has the same crappy fs interfaces with lots of boilerplate
code and still abuses xattrs instead of a proper syscall interface.
That's far from being ready to merge.
--
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/
Andreas Gruenbacher Nov. 10, 2015, 12:39 p.m. UTC | #2
On Tue, Nov 10, 2015 at 12:29 PM, Christoph Hellwig <hch@infradead.org> wrote:
> On Mon, Nov 09, 2015 at 12:08:41PM +0100, Andreas Gruenbacher wrote:
>> Here is another update to the richacl patch queue.  This posting contains
>> the patches ready to be merged; the patches later in the queue still need
>> some more review.
>
> It still has the same crappy fs interfaces with lots of boilerplate
> code

Could you please be more specific so that I can trace this complaint
to some actual code?

> and still abuses xattrs instead of a proper syscall interface.
> That's far from being ready to merge.

The xattr syscall interface is what's used for very similar kinds of
things today; using it for richacls as well sure does not count as
abuse. Things could be improved in the xattr interface and in its
implementation, but we need more substantial reasons than that for
reimplementing the wheel once again.

[The recently discussed xattr fixes
(http://permalink.gmane.org/gmane.linux.file-systems/101502) and two
small POSIX ACL fixes
(http://permalink.gmane.org/gmane.linux.file-systems/101499) are
currently stuck waiting for Al, by the way.]

Thanks,
Andreas
--
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/
Steve French Nov. 10, 2015, 4:43 p.m. UTC | #3
On Tue, Nov 10, 2015 at 6:39 AM, Andreas Gruenbacher
<agruenba@redhat.com> wrote:
> On Tue, Nov 10, 2015 at 12:29 PM, Christoph Hellwig <hch@infradead.org> wrote:
>> On Mon, Nov 09, 2015 at 12:08:41PM +0100, Andreas Gruenbacher wrote:
>>> Here is another update to the richacl patch queue.  This posting contains
>>> the patches ready to be merged; the patches later in the queue still need
>>> some more review.
<snip>
>> and still abuses xattrs instead of a proper syscall interface.
>> That's far from being ready to merge.
>
> The xattr syscall interface is what's used for very similar kinds of
> things today; using it for richacls as well sure does not count as
> abuse. Things could be improved in the xattr interface and in its
> implementation, but we need more substantial reasons than that for
> reimplementing the wheel once again.

I don't have strong disagreement with using pseudo-xattrs to
store/retrieve ACLs (we already do this) but retrieving/setting an ACL
all at once can be awkward  when ACLs are quite large e.g. when it
encodes to over 1MB (not all administrators think about the size of
ACLs when they add hundreds of users or groups or apps to ACLs).

The bigger problem is that when ACLs are created -- after -- the file
is created there is a potential race (harder to deal with in cluster
and network file systems).   Ideally we should be able to optionally
pass all the security information needed to create a file in the
create call itself.  For apps which don't care they can continue to
use the old syscalls.

In the meantime, I don't mind the approach of staging this in via a
pseudo-xattr, Samba can deal with that (and it will make some of the
backup and data movement tools easier for the cifs.ko client which
currently rely on a cifs specific xattr).

In cifs.ko I still need to enable the SMB3 ACL helper functions
(currently only enabled for the older cifs dialect) since that will
make it easier, and figure out a way to allow helper tools to view
"claims based ACLs" (DAC), not just traditional
CIFS/NTFS/SMB3/RichACLs.
J. Bruce Fields Nov. 10, 2015, 5:07 p.m. UTC | #4
On Tue, Nov 10, 2015 at 10:43:46AM -0600, Steve French wrote:
> On Tue, Nov 10, 2015 at 6:39 AM, Andreas Gruenbacher
> <agruenba@redhat.com> wrote:
> > On Tue, Nov 10, 2015 at 12:29 PM, Christoph Hellwig <hch@infradead.org> wrote:
> >> On Mon, Nov 09, 2015 at 12:08:41PM +0100, Andreas Gruenbacher wrote:
> >>> Here is another update to the richacl patch queue.  This posting contains
> >>> the patches ready to be merged; the patches later in the queue still need
> >>> some more review.
> <snip>
> >> and still abuses xattrs instead of a proper syscall interface.
> >> That's far from being ready to merge.
> >
> > The xattr syscall interface is what's used for very similar kinds of
> > things today; using it for richacls as well sure does not count as
> > abuse. Things could be improved in the xattr interface and in its
> > implementation, but we need more substantial reasons than that for
> > reimplementing the wheel once again.
> 
> I don't have strong disagreement with using pseudo-xattrs to
> store/retrieve ACLs (we already do this) but retrieving/setting an ACL
> all at once can be awkward  when ACLs are quite large e.g. when it
> encodes to over 1MB

At least in the NFS case, that's also a limitation of the protocol.  If
we really wanted to support massive ACLs then we'd need both syscall and
NFS interfaces to allow incrementally reading and writing ACLs, and I
don't even know what those would look like.

So this is a fine limitation as far as I'm concerned.

> (not all administrators think about the size of
> ACLs when they add hundreds of users or groups or apps to ACLs).
> 
> The bigger problem is that when ACLs are created -- after -- the file
> is created there is a potential race (harder to deal with in cluster
> and network file systems).   Ideally we should be able to optionally
> pass all the security information needed to create a file in the
> create call itself.  For apps which don't care they can continue to
> use the old syscalls.

That would be most of them, I'd think.

But I suppose windows apps (via Samba or Wine?) could use this.

Definitely a project for another day, in any case.

--b.

> In cifs.ko I still need to enable the SMB3 ACL helper functions
> (currently only enabled for the older cifs dialect) since that will
> make it easier, and figure out a way to allow helper tools to view
> "claims based ACLs" (DAC), not just traditional
> CIFS/NTFS/SMB3/RichACLs.
> -- 
> Thanks,
> 
> Steve
--
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/
Andreas Gruenbacher Nov. 10, 2015, 5:58 p.m. UTC | #5
On Tue, Nov 10, 2015 at 6:07 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
> On Tue, Nov 10, 2015 at 10:43:46AM -0600, Steve French wrote:
>> On Tue, Nov 10, 2015 at 6:39 AM, Andreas Gruenbacher
>> <agruenba@redhat.com> wrote:
>> > On Tue, Nov 10, 2015 at 12:29 PM, Christoph Hellwig <hch@infradead.org> wrote:
>> >> On Mon, Nov 09, 2015 at 12:08:41PM +0100, Andreas Gruenbacher wrote:
>> >>> Here is another update to the richacl patch queue.  This posting contains
>> >>> the patches ready to be merged; the patches later in the queue still need
>> >>> some more review.
>> <snip>
>> >> and still abuses xattrs instead of a proper syscall interface.
>> >> That's far from being ready to merge.
>> >
>> > The xattr syscall interface is what's used for very similar kinds of
>> > things today; using it for richacls as well sure does not count as
>> > abuse. Things could be improved in the xattr interface and in its
>> > implementation, but we need more substantial reasons than that for
>> > reimplementing the wheel once again.
>>
>> I don't have strong disagreement with using pseudo-xattrs to
>> store/retrieve ACLs (we already do this) but retrieving/setting an ACL
>> all at once can be awkward  when ACLs are quite large e.g. when it
>> encodes to over 1MB
>
> At least in the NFS case, that's also a limitation of the protocol.

I couldn't find a limit in the NFSv4 specification, but the client and
server implementations both define arbitrary ACL size limits. In
addition, the xattr syscalls allow attributes to be up to 64k long.

> If
> we really wanted to support massive ACLs then we'd need both syscall and
> NFS interfaces to allow incrementally reading and writing ACLs, and I
> don't even know what those would look like.
>
> So this is a fine limitation as far as I'm concerned.

The bigger problem would be incrementally setting ACLs. To prevent
processes from racing with each other, we would need a locking
mechanism. In addition, the memory overhead would be prohibitive and
access decisions would become extremely slow; we would have to come up
with mechanisms to avoid those problems.

Thanks,
Andreas
--
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/
J. Bruce Fields Nov. 10, 2015, 7:17 p.m. UTC | #6
On Tue, Nov 10, 2015 at 06:58:19PM +0100, Andreas Gruenbacher wrote:
> On Tue, Nov 10, 2015 at 6:07 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
> > On Tue, Nov 10, 2015 at 10:43:46AM -0600, Steve French wrote:
> >> I don't have strong disagreement with using pseudo-xattrs to
> >> store/retrieve ACLs (we already do this) but retrieving/setting an ACL
> >> all at once can be awkward  when ACLs are quite large e.g. when it
> >> encodes to over 1MB
> >
> > At least in the NFS case, that's also a limitation of the protocol.
> 
> I couldn't find a limit in the NFSv4 specification, but the client and
> server implementations both define arbitrary ACL size limits. In
> addition, the xattr syscalls allow attributes to be up to 64k long.

I don't recall 4.0 specifying any limit, 4.1 does include negotiation of
maximum rpc calls and replies, and that effectively limits ACL sizes
since they have to fit in a single rpc.

> The bigger problem would be incrementally setting ACLs. To prevent
> processes from racing with each other, we would need a locking
> mechanism. In addition, the memory overhead would be prohibitive and
> access decisions would become extremely slow; we would have to come up
> with mechanisms to avoid those problems.

Right.  Anyway, not worth the trouble, I think.

(Though what might be worth thinking about at some point is just making
sure we fail in helpful ways.)

--b.
--
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/
Christoph Hellwig Nov. 11, 2015, 7:57 a.m. UTC | #7
On Tue, Nov 10, 2015 at 01:39:52PM +0100, Andreas Gruenbacher wrote:
> > It still has the same crappy fs interfaces with lots of boilerplate
> > code
> 
> Could you please be more specific so that I can trace this complaint
> to some actual code?

if (IS_RICHACL())
	richacl_foo()
else
	posix_acl_foo()

for every call from the filesystem is the major one that came to mind.

> > and still abuses xattrs instead of a proper syscall interface.
> > That's far from being ready to merge.
> 
> The xattr syscall interface is what's used for very similar kinds of
> things today; using it for richacls as well sure does not count as
> abuse. Things could be improved in the xattr interface and in its
> implementation, but we need more substantial reasons than that for
> reimplementing the wheel once again.

And it's a horrible interface.  Look at all the pain for example in
XFS which has a different ACL format, or in fact everyone who just
uses a different xattr name or even none at all.  And all the mess
of people trying to shoe horn crazy interfaces into xattrs.

It was an experiment worth trying with Posix ACLs, but it failed, so
do not repeat it.
--
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/
Andreas Gruenbacher Nov. 11, 2015, 1:59 p.m. UTC | #8
On Wed, Nov 11, 2015 at 8:57 AM, Christoph Hellwig <hch@infradead.org> wrote:
> On Tue, Nov 10, 2015 at 01:39:52PM +0100, Andreas Gruenbacher wrote:
>> > It still has the same crappy fs interfaces with lots of boilerplate
>> > code
>>
>> Could you please be more specific so that I can trace this complaint
>> to some actual code?
>
> if (IS_RICHACL())
>         richacl_foo()
> else
>         posix_acl_foo()
>
> for every call from the filesystem is the major one that came to mind.

There are two such places in ext4, ext4_new_acl and ext4_acl_chmod.  Those
could be replaced by function pointers as below, I'm not sure we seriously
want to consider that.

In xfs, we have xfs_acl_chmod which is similar.  xfs_generic_create doesn't
quite follow this pattern.

This seems to be about it though.

Thanks,
Andreas

---
 fs/ext4/ext4.h     | 10 ++++++++++
 fs/ext4/ialloc.c   | 11 +----------
 fs/ext4/inode.c    | 11 +----------
 fs/ext4/super.c    | 30 ++++++++++++++++++++++++++++++
 include/linux/fs.h |  1 +
 5 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index b97a3b1..5ff4556 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -3049,6 +3049,16 @@ extern struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
 extern int ext4_resize_begin(struct super_block *sb);
 extern void ext4_resize_end(struct super_block *sb);
 
+struct ext4_acl_ops {
+	int (*chmod)(struct inode *, umode_t);
+	int (*init_acl)(handle_t *, struct inode *, struct inode *);
+};
+
+static inline const struct ext4_acl_ops *ACL_OPS(struct inode *inode)
+{
+	return inode->i_sb->s_private;
+}
+
 #endif	/* __KERNEL__ */
 
 #endif	/* _EXT4_H */
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 9657b3a..e33646f 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -27,7 +27,6 @@
 #include "ext4_jbd2.h"
 #include "xattr.h"
 #include "acl.h"
-#include "richacl.h"
 
 #include <trace/events/ext4.h>
 
@@ -698,14 +697,6 @@ out:
 	return ret;
 }
 
-static inline int
-ext4_new_acl(handle_t *handle, struct inode *inode, struct inode *dir)
-{
-	if (IS_RICHACL(dir))
-		return ext4_init_richacl(handle, inode, dir);
-	return ext4_init_acl(handle, inode, dir);
-}
-
 /*
  * There are two policies for allocating an inode.  If the new inode is
  * a directory, then a forward search is made for a block group with both
@@ -1061,7 +1052,7 @@ got:
 	if (err)
 		goto fail_drop;
 
-	err = ext4_new_acl(handle, inode, dir);
+	err = ACL_OPS(inode)->init_acl(handle, inode, dir);
 	if (err)
 		goto fail_free_drop;
 
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 647f3c3..9f179ee 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -42,7 +42,6 @@
 #include "xattr.h"
 #include "acl.h"
 #include "truncate.h"
-#include "richacl.h"
 
 #include <trace/events/ext4.h>
 
@@ -4639,14 +4638,6 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode)
 	}
 }
 
-static inline int
-ext4_acl_chmod(struct inode *inode, umode_t mode)
-{
-	if (IS_RICHACL(inode))
-		return richacl_chmod(inode, inode->i_mode);
-	return posix_acl_chmod(inode, inode->i_mode);
-}
-
 /*
  * ext4_setattr()
  *
@@ -4815,7 +4806,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
 		ext4_orphan_del(NULL, inode);
 
 	if (!rc && (ia_valid & ATTR_MODE))
-		rc = ext4_acl_chmod(inode, inode->i_mode);
+		rc = ACL_OPS(inode)->chmod(inode, inode->i_mode);
 err_out:
 	ext4_std_error(inode->i_sb, error);
 	if (!error)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 7457ea8..879bc2c 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -49,6 +49,7 @@
 #include "ext4_jbd2.h"
 #include "xattr.h"
 #include "acl.h"
+#include "richacl.h"
 #include "mballoc.h"
 
 #define CREATE_TRACE_POINTS
@@ -1270,25 +1271,54 @@ static ext4_fsblk_t get_sb_block(void **data)
 	return sb_block;
 }
 
+static int no_chmod_acl(struct inode *inode, umode_t mode)
+{
+	return 0;
+}
+
+static int no_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
+{
+	return 0;
+}
+
+struct ext4_acl_ops no_acl_ops = {
+	.chmod = no_chmod_acl,
+	.init_acl = no_init_acl,
+};
+
+struct ext4_acl_ops ext4_posix_acl_ops = {
+	.chmod = posix_acl_chmod,
+	.init_acl = ext4_init_acl,
+};
+
+struct ext4_acl_ops ext4_richacl_ops = {
+	.chmod = richacl_chmod,
+	.init_acl = ext4_init_richacl,
+};
+
 static int enable_acl(struct super_block *sb)
 {
 	sb->s_flags &= ~(MS_POSIXACL | MS_RICHACL);
+	sb->s_private = &no_acl_ops;
 	if (test_opt(sb, ACL)) {
 		if (EXT4_HAS_INCOMPAT_FEATURE(sb,
 					      EXT4_FEATURE_INCOMPAT_RICHACL)) {
 #ifdef CONFIG_EXT4_FS_RICHACL
 			sb->s_flags |= MS_RICHACL;
+			sb->s_private = &ext4_richacl_ops;
 #else
 			return -EOPNOTSUPP;
 #endif
 		} else {
 #ifdef CONFIG_EXT4_FS_POSIX_ACL
 			sb->s_flags |= MS_POSIXACL;
+			sb->s_private = &ext4_posix_acl_ops;
 #else
 			return -EOPNOTSUPP;
 #endif
 		}
 	}
+
 	return 0;
 }
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 05fb943..5803bf6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1324,6 +1324,7 @@ struct super_block {
 	void                    *s_security;
 #endif
 	const struct xattr_handler **s_xattr;
+	const void *s_private;
 
 	struct hlist_bl_head	s_anon;		/* anonymous dentries for (nfs) exporting */
 	struct list_head	s_mounts;	/* list of mounts; _not_ for fs use */