Linux-Doc Archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/5] ubifs: Support POSIX Access Control Lists (ACLs)
@ 2024-03-22 15:48 Li Zetao
  2024-03-22 15:48 ` [RFC PATCH v2 1/5] ubifs: Add ACLs config option Li Zetao
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Li Zetao @ 2024-03-22 15:48 UTC (permalink / raw
  To: richard, chengzhihao1, corbet, kent.overstreet, agruenba
  Cc: lizetao1, linux-mtd, linux-doc, linux-kernel

Hi,

This patchset is base on [1] and [2], adding implementation of ACLs for
ubifs.

Implement ACLs features based on POSIX to solve some difficulties that
require fine-grained access control. At the same time, it is also to
facilitate cross-file system migration.

In order to simplify the implementation, only v2 version POSIX ACLs are
implemented, eliminating the need for in-memory and on-flash format
conversion. And no need to implement security xattr handler in ubifs.

Some testcases have been tested and passed:
  * generic testcases (modified version) for acl group in xfstest[3], they are generic/026/053/077/099/105/237/307/318/319/375/389/444/449/529/697.
  * tacl_xattr.sh (modified version) in LTP[4].

[1]: https://lore.kernel.org/linux-mtd/1441962597-13543-1-git-send-email-shengyong1@huawei.com/
[2]: https://lore.kernel.org/linux-mtd/1476046382-19185-1-git-send-email-pascal.eberhard@gmail.com/
[3]: https://kernel.googlesource.com/pub/scm/fs/xfs/xfstests-dev/+/refs/heads/master/tests/generic/
[4]: https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/fs/acl/tacl_xattr.sh

Changelog:
v1 -> v2:
  * Adjust patch order.
  * Modify ubifs_xattr_remove to an external function to remove the
  * xattr of ACL.
  * Fix handling of updating file mode via ACL.

v1: https://lore.kernel.org/all/20240319161646.2153867-1-lizetao1@huawei.com/


Li Zetao (5):
  ubifs: Add ACLs config option
  ubifs: Implement POSIX Access Control Lists (ACLs)
  ubifs: Initialize or update ACLs for inode
  ubifs: Support accessing ACLs through inode_operations
  ubifs: Introduce ACLs mount options

 Documentation/filesystems/ubifs.rst |   4 +
 fs/ubifs/Kconfig                    |  14 ++
 fs/ubifs/Makefile                   |   1 +
 fs/ubifs/acl.c                      | 192 ++++++++++++++++++++++++++++
 fs/ubifs/dir.c                      |  22 ++++
 fs/ubifs/file.c                     |   6 +
 fs/ubifs/super.c                    |  41 ++++++
 fs/ubifs/ubifs.h                    |  16 +++
 fs/ubifs/xattr.c                    |   3 +-
 9 files changed, 297 insertions(+), 2 deletions(-)
 create mode 100644 fs/ubifs/acl.c

-- 
2.34.1


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

* [RFC PATCH v2 1/5] ubifs: Add ACLs config option
  2024-03-22 15:48 [RFC PATCH v2 0/5] ubifs: Support POSIX Access Control Lists (ACLs) Li Zetao
@ 2024-03-22 15:48 ` Li Zetao
  2024-03-22 15:48 ` [RFC PATCH v2 2/5] ubifs: Implement POSIX Access Control Lists (ACLs) Li Zetao
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Li Zetao @ 2024-03-22 15:48 UTC (permalink / raw
  To: richard, chengzhihao1, corbet, kent.overstreet, agruenba
  Cc: lizetao1, linux-mtd, linux-doc, linux-kernel

Add CONFIG_UBIFS_FS_POSIX_ACL to select ACL for UBIFS, but it should
be noted that this config option depends on UBIFS_FS_XATTR.

Signed-off-by: Li Zetao <lizetao1@huawei.com>
---
v1 -> v2: Put this patch first.
v1: https://lore.kernel.org/all/20240319161646.2153867-6-lizetao1@huawei.com/

 fs/ubifs/Kconfig | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index 45d3d207fb99..9ac5ddd5ded3 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -98,4 +98,18 @@ config UBIFS_FS_AUTHENTICATION
 	  sha256, these are not selected automatically since there are many
 	  different options.
 
+config UBIFS_FS_POSIX_ACL
+	bool "UBIFS POSIX Access Control Lists"
+	depends on UBIFS_FS_XATTR
+	select FS_POSIX_ACL
+	default y
+	help
+	  Posix Access Control Lists (ACLs) support permissions for users and
+	  groups beyond the owner/group/world scheme.
+
+	  To learn more about Access Control Lists, visit the Posix ACLs for
+	  Linux website <http://acl.bestbits.at/>.
+
+	  If you don't know what Access Control Lists are, say N
+
 endif # UBIFS_FS
-- 
2.34.1


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

* [RFC PATCH v2 2/5] ubifs: Implement POSIX Access Control Lists (ACLs)
  2024-03-22 15:48 [RFC PATCH v2 0/5] ubifs: Support POSIX Access Control Lists (ACLs) Li Zetao
  2024-03-22 15:48 ` [RFC PATCH v2 1/5] ubifs: Add ACLs config option Li Zetao
@ 2024-03-22 15:48 ` Li Zetao
  2024-03-23  2:42   ` Zhihao Cheng
  2024-03-22 15:48 ` [RFC PATCH v2 3/5] ubifs: Initialize or update ACLs for inode Li Zetao
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Li Zetao @ 2024-03-22 15:48 UTC (permalink / raw
  To: richard, chengzhihao1, corbet, kent.overstreet, agruenba
  Cc: lizetao1, linux-mtd, linux-doc, linux-kernel

Implement the ACLs feature for ubifs based on vfs Posix ACLs,
details as follows:
  * Initialize acl for newly created inode.
  * Provides get/set interface to access ACLs.

ACLs feature relies on xattr implementation which using specific key
names "system.posix_acl_default" and "system.posix_acl_access". Now Only
the v2 version of POSIX ACLs is supported, and ubifs does not need to
customize the storage format, which can simplify the implementation.

It should be noted that Linux supports updating the file mode through
ACLs. However the acl may not exist, so ubifs_xattr_remove() returns
-ENODATA. Such a scenario needs to be specially handled. At the same
time, it needs to ensure that the updated inode is written to flash.

Signed-off-by: Li Zetao <lizetao1@huawei.com>
---
v1 -> v2:
  * Get xattr_name by direct expansion instead of posix_acl_xattr_name().
  * Modify ubifs_xattr_remove to an external function to remove the xattr of ACL.
  * Remove redundant likely() and unlikely().
  * Fix updating file mode via ACL and support writing to flash.

v1: https://lore.kernel.org/all/20240319161646.2153867-2-lizetao1@huawei.com/

 fs/ubifs/Makefile |   1 +
 fs/ubifs/acl.c    | 192 ++++++++++++++++++++++++++++++++++++++++++++++
 fs/ubifs/ubifs.h  |  14 ++++
 fs/ubifs/xattr.c  |   3 +-
 4 files changed, 208 insertions(+), 2 deletions(-)
 create mode 100644 fs/ubifs/acl.c

diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile
index 314c80b24a76..b615fbb73908 100644
--- a/fs/ubifs/Makefile
+++ b/fs/ubifs/Makefile
@@ -9,3 +9,4 @@ ubifs-y += misc.o sysfs.o
 ubifs-$(CONFIG_FS_ENCRYPTION) += crypto.o
 ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o
 ubifs-$(CONFIG_UBIFS_FS_AUTHENTICATION) += auth.o
+ubifs-$(CONFIG_UBIFS_FS_POSIX_ACL) += acl.o
diff --git a/fs/ubifs/acl.c b/fs/ubifs/acl.c
new file mode 100644
index 000000000000..8ac5bd86f32d
--- /dev/null
+++ b/fs/ubifs/acl.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file is part of UBIFS.
+ *
+ * Copyright (C) 2024 Huawei Tech. Co., Ltd.
+ *
+ * Authors: Li Zetao <lizetao1@huawei.com>
+ */
+
+/* This file implements POSIX Access Control Lists (ACLs) */
+
+#include "ubifs.h"
+
+#include <linux/posix_acl_xattr.h>
+
+struct posix_acl *ubifs_get_inode_acl(struct inode *inode, int type, bool rcu)
+{
+	char *xattr_value = NULL;
+	const char *xattr_name;
+	struct posix_acl *acl;
+	ssize_t size;
+
+	if (rcu)
+		return ERR_PTR(-ECHILD);
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
+		break;
+	case ACL_TYPE_DEFAULT:
+		xattr_name = XATTR_NAME_POSIX_ACL_DEFAULT;
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+
+	size = ubifs_xattr_get(inode, xattr_name, NULL, 0);
+	if (size > 0) {
+		xattr_value = kzalloc(size, GFP_KERNEL);
+		if (unlikely(!xattr_value))
+			return ERR_PTR(-ENOMEM);
+
+		size = ubifs_xattr_get(inode, xattr_name, xattr_value, size);
+	}
+
+	if (size > 0)
+		acl = posix_acl_from_xattr(&init_user_ns, xattr_value, size);
+	else if (size == -ENODATA || size == 0)
+		acl = NULL;
+	else
+		acl = ERR_PTR(size);
+
+	kfree(xattr_value);
+
+	return acl;
+}
+
+static int __ubifs_set_acl(struct inode *inode, int type, struct posix_acl *acl, int flags)
+{
+	void *xattr_value = NULL;
+	const char *xattr_name;
+	size_t size = 0;
+	int error;
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
+		break;
+
+	case ACL_TYPE_DEFAULT:
+		xattr_name = XATTR_NAME_POSIX_ACL_DEFAULT;
+		if (!S_ISDIR(inode->i_mode))
+			return acl ? -EACCES : 0;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if (acl) {
+		size = posix_acl_xattr_size(acl->a_count);
+		xattr_value = kmalloc(size, GFP_KERNEL);
+		if (unlikely(!xattr_value))
+			return -ENOMEM;
+
+		error = posix_acl_to_xattr(&init_user_ns, acl, xattr_value, size);
+		if (unlikely(error < 0))
+			goto out;
+
+		error = ubifs_xattr_set(inode, xattr_name, xattr_value, size, flags, false);
+	} else {
+		error = ubifs_xattr_remove(inode, xattr_name);
+		if (error == -ENODATA)
+			return 0;
+	}
+
+	if (!error)
+		set_cached_acl(inode, type, acl);
+out:
+	kfree(xattr_value);
+	return error;
+}
+
+static int ubifs_update_mode(struct inode *inode, umode_t mode)
+{
+	struct ubifs_inode *ui = ubifs_inode(inode);
+	struct ubifs_info *c = inode->i_sb->s_fs_info;
+	struct ubifs_budget_req req = { .dirtied_ino = 1,
+				.dirtied_ino_d = ALIGN(ui->data_len, 8) };
+	int release;
+	int err;
+
+	err = ubifs_budget_space(c, &req);
+	if (err)
+		return err;
+
+	mutex_lock(&ui->ui_mutex);
+	release = ui->dirty;
+	inode->i_mode = mode;
+	inode_set_ctime_current(inode);
+	mark_inode_dirty_sync(inode);
+	mutex_unlock(&ui->ui_mutex);
+
+	if (release)
+		ubifs_release_budget(c, &req);
+	if (IS_SYNC(inode))
+		err = inode->i_sb->s_op->write_inode(inode, NULL);
+
+	return err;
+}
+
+int ubifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, struct posix_acl *acl, int type)
+{
+	struct inode *inode = d_inode(dentry);
+	umode_t mode = inode->i_mode;
+	bool update_mode = false;
+	int error;
+
+	if (type == ACL_TYPE_ACCESS && acl) {
+		error = posix_acl_update_mode(idmap, inode, &mode, &acl);
+		if (unlikely(error))
+			return error;
+
+		if (inode->i_mode != mode)
+			update_mode = true;
+	}
+
+	error = __ubifs_set_acl(inode, type, acl, 0);
+	if (!error && update_mode)
+		error = ubifs_update_mode(inode, mode);
+
+	return error;
+
+}
+
+/**
+ * ubifs_init_acl - initialize the ACLs for a new inode.
+ * @inode: newly created inode
+ * @dir: parent directory inode
+ *
+ * This function initializes ACLs, including inheriting the
+ * default ACLs of parent directory or modifying the default
+ * ACLs according to the mode parameter in open() / creat()
+ * system calls.
+ */
+int ubifs_init_acl(struct inode *inode, struct inode *dir)
+{
+	struct posix_acl *default_acl;
+	struct posix_acl *acl;
+	int error;
+
+	error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
+	if (unlikely(error))
+		return error;
+
+	if (default_acl) {
+		error = __ubifs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl, XATTR_CREATE);
+		posix_acl_release(default_acl);
+	} else {
+		inode->i_default_acl = NULL;
+	}
+
+	if (acl) {
+		if (!error)
+			error = __ubifs_set_acl(inode, ACL_TYPE_ACCESS, acl, XATTR_CREATE);
+		posix_acl_release(acl);
+	} else {
+		inode->i_acl = NULL;
+	}
+
+	return error;
+}
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 1f3ea879d93a..b96c2462237a 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -2046,6 +2046,7 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
 		    size_t size, int flags, bool check_lock);
 ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
 			size_t size);
+int ubifs_xattr_remove(struct inode *host, const char *name);
 
 #ifdef CONFIG_UBIFS_FS_XATTR
 extern const struct xattr_handler * const ubifs_xattr_handlers[];
@@ -2074,6 +2075,19 @@ static inline int ubifs_init_security(struct inode *dentry,
 }
 #endif
 
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+struct posix_acl *ubifs_get_inode_acl(struct inode *inode, int type, bool rcu);
+int ubifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, struct posix_acl *acl, int type);
+int ubifs_init_acl(struct inode *inode, struct inode *dir);
+
+#else /* CONFIG_UBIFS_FS_POSIX_ACL */
+#define ubifs_get_inode_acl NULL
+#define ubifs_set_acl NULL
+static inline int ubifs_init_acl(struct inode *inode, struct inode *dir)
+{
+	return 0;
+}
+#endif /* CONFIG_UBIFS_FS_POSIX_ACL */
 
 /* super.c */
 struct inode *ubifs_iget(struct super_block *sb, unsigned long inum);
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index 0847db521984..87350b15f2c2 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -40,7 +40,6 @@
  * in the VFS inode cache. The xentries are cached in the LNC cache (see
  * tnc.c).
  *
- * ACL support is not implemented.
  */
 
 #include "ubifs.h"
@@ -592,7 +591,7 @@ void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum)
 	}
 }
 
-static int ubifs_xattr_remove(struct inode *host, const char *name)
+int ubifs_xattr_remove(struct inode *host, const char *name)
 {
 	struct inode *inode;
 	struct ubifs_info *c = host->i_sb->s_fs_info;
-- 
2.34.1


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

* [RFC PATCH v2 3/5] ubifs: Initialize or update ACLs for inode
  2024-03-22 15:48 [RFC PATCH v2 0/5] ubifs: Support POSIX Access Control Lists (ACLs) Li Zetao
  2024-03-22 15:48 ` [RFC PATCH v2 1/5] ubifs: Add ACLs config option Li Zetao
  2024-03-22 15:48 ` [RFC PATCH v2 2/5] ubifs: Implement POSIX Access Control Lists (ACLs) Li Zetao
@ 2024-03-22 15:48 ` Li Zetao
  2024-03-22 15:48 ` [RFC PATCH v2 4/5] ubifs: Support accessing ACLs through inode_operations Li Zetao
  2024-03-22 15:48 ` [RFC PATCH v2 5/5] ubifs: Introduce ACLs mount options Li Zetao
  4 siblings, 0 replies; 8+ messages in thread
From: Li Zetao @ 2024-03-22 15:48 UTC (permalink / raw
  To: richard, chengzhihao1, corbet, kent.overstreet, agruenba
  Cc: lizetao1, linux-mtd, linux-doc, linux-kernel

There are two scenarios where ACL needs to be updated, the first one
is when creating the inode, and the second one is in the chmod process.
When creating directories/files/device node/tmpfile, ACLs needs to be
initialized, but symlink do not.

Signed-off-by: Li Zetao <lizetao1@huawei.com>
---
v1 -> v2: Add initialization ACL in create_whiteout()
v1: https://lore.kernel.org/all/20240319161646.2153867-3-lizetao1@huawei.com/

 fs/ubifs/dir.c  | 20 ++++++++++++++++++++
 fs/ubifs/file.c |  4 ++++
 2 files changed, 24 insertions(+)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index eac0fef801f1..243dfb478984 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -316,6 +316,10 @@ static int ubifs_create(struct mnt_idmap *idmap, struct inode *dir,
 		goto out_fname;
 	}
 
+	err = ubifs_init_acl(inode, dir);
+	if (err)
+		goto out_inode;
+
 	err = ubifs_init_security(dir, inode, &dentry->d_name);
 	if (err)
 		goto out_inode;
@@ -376,6 +380,10 @@ static struct inode *create_whiteout(struct inode *dir, struct dentry *dentry)
 	init_special_inode(inode, inode->i_mode, WHITEOUT_DEV);
 	ubifs_assert(c, inode->i_op == &ubifs_file_inode_operations);
 
+	err = ubifs_init_acl(inode, dir);
+	if (err)
+		goto out_inode;
+
 	err = ubifs_init_security(dir, inode, &dentry->d_name);
 	if (err)
 		goto out_inode;
@@ -466,6 +474,10 @@ static int ubifs_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
 	}
 	ui = ubifs_inode(inode);
 
+	err = ubifs_init_acl(inode, dir);
+	if (err)
+		goto out_inode;
+
 	err = ubifs_init_security(dir, inode, &dentry->d_name);
 	if (err)
 		goto out_inode;
@@ -1013,6 +1025,10 @@ static int ubifs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
 		goto out_fname;
 	}
 
+	err = ubifs_init_acl(inode, dir);
+	if (err)
+		goto out_inode;
+
 	err = ubifs_init_security(dir, inode, &dentry->d_name);
 	if (err)
 		goto out_inode;
@@ -1108,6 +1124,10 @@ static int ubifs_mknod(struct mnt_idmap *idmap, struct inode *dir,
 	ui->data = dev;
 	ui->data_len = devlen;
 
+	err = ubifs_init_acl(inode, dir);
+	if (err)
+		goto out_inode;
+
 	err = ubifs_init_security(dir, inode, &dentry->d_name);
 	if (err)
 		goto out_inode;
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index a1f46919934c..808a2ded4f8c 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -41,6 +41,7 @@
 #include <linux/mount.h>
 #include <linux/slab.h>
 #include <linux/migrate.h>
+#include <linux/posix_acl.h>
 
 static int read_block(struct inode *inode, void *addr, unsigned int block,
 		      struct ubifs_data_node *dn)
@@ -1297,6 +1298,9 @@ int ubifs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
 	else
 		err = do_setattr(c, inode, attr);
 
+	if (!err && (attr->ia_valid & ATTR_MODE))
+		err = posix_acl_chmod(idmap, dentry, inode->i_mode);
+
 	return err;
 }
 
-- 
2.34.1


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

* [RFC PATCH v2 4/5] ubifs: Support accessing ACLs through inode_operations
  2024-03-22 15:48 [RFC PATCH v2 0/5] ubifs: Support POSIX Access Control Lists (ACLs) Li Zetao
                   ` (2 preceding siblings ...)
  2024-03-22 15:48 ` [RFC PATCH v2 3/5] ubifs: Initialize or update ACLs for inode Li Zetao
@ 2024-03-22 15:48 ` Li Zetao
  2024-03-22 15:48 ` [RFC PATCH v2 5/5] ubifs: Introduce ACLs mount options Li Zetao
  4 siblings, 0 replies; 8+ messages in thread
From: Li Zetao @ 2024-03-22 15:48 UTC (permalink / raw
  To: richard, chengzhihao1, corbet, kent.overstreet, agruenba
  Cc: lizetao1, linux-mtd, linux-doc, linux-kernel

Register the get/set interfaces to the inode operations whilch
allows access to the ACL through the vfs layer.

Signed-off-by: Li Zetao <lizetao1@huawei.com>
---
v1 -> v2: There are no changes to this patch.
v1: https://lore.kernel.org/all/20240319161646.2153867-4-lizetao1@huawei.com/

 fs/ubifs/dir.c  | 2 ++
 fs/ubifs/file.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 243dfb478984..145ada316a46 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -1730,6 +1730,8 @@ const struct inode_operations ubifs_dir_inode_operations = {
 	.setattr     = ubifs_setattr,
 	.getattr     = ubifs_getattr,
 	.listxattr   = ubifs_listxattr,
+	.get_inode_acl = ubifs_get_inode_acl,
+	.set_acl     = ubifs_set_acl,
 	.update_time = ubifs_update_time,
 	.tmpfile     = ubifs_tmpfile,
 	.fileattr_get = ubifs_fileattr_get,
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 808a2ded4f8c..ba428af0a235 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1664,6 +1664,8 @@ const struct inode_operations ubifs_file_inode_operations = {
 	.setattr     = ubifs_setattr,
 	.getattr     = ubifs_getattr,
 	.listxattr   = ubifs_listxattr,
+	.get_inode_acl = ubifs_get_inode_acl,
+	.set_acl      = ubifs_set_acl,
 	.update_time = ubifs_update_time,
 	.fileattr_get = ubifs_fileattr_get,
 	.fileattr_set = ubifs_fileattr_set,
-- 
2.34.1


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

* [RFC PATCH v2 5/5] ubifs: Introduce ACLs mount options
  2024-03-22 15:48 [RFC PATCH v2 0/5] ubifs: Support POSIX Access Control Lists (ACLs) Li Zetao
                   ` (3 preceding siblings ...)
  2024-03-22 15:48 ` [RFC PATCH v2 4/5] ubifs: Support accessing ACLs through inode_operations Li Zetao
@ 2024-03-22 15:48 ` Li Zetao
  2024-03-23  2:55   ` Zhihao Cheng
  4 siblings, 1 reply; 8+ messages in thread
From: Li Zetao @ 2024-03-22 15:48 UTC (permalink / raw
  To: richard, chengzhihao1, corbet, kent.overstreet, agruenba
  Cc: lizetao1, linux-mtd, linux-doc, linux-kernel

Implement the ability to enable or disable the ACLs feature through
mount options. "-o acl" option means enable and "-o noacl" means disable
and it is enable by default.

Signed-off-by: Li Zetao <lizetao1@huawei.com>
---
v1 -> v2:
  * Remove redundant assignments to mount.acl.
  * Added the description of acl mount options in ubifs.rst.

v1: https://lore.kernel.org/all/20240319161646.2153867-5-lizetao1@huawei.com/

 Documentation/filesystems/ubifs.rst |  4 +++
 fs/ubifs/super.c                    | 41 +++++++++++++++++++++++++++++
 fs/ubifs/ubifs.h                    |  2 ++
 3 files changed, 47 insertions(+)

diff --git a/Documentation/filesystems/ubifs.rst b/Documentation/filesystems/ubifs.rst
index ced2f7679ddb..f9615104d7a3 100644
--- a/Documentation/filesystems/ubifs.rst
+++ b/Documentation/filesystems/ubifs.rst
@@ -105,6 +105,10 @@ auth_key=		specify the key used for authenticating the filesystem.
 auth_hash_name=		The hash algorithm used for authentication. Used for
 			both hashing and for creating HMACs. Typical values
 			include "sha256" or "sha512"
+noacl			This option disables POSIX Access Control List support. If ACL support
+			is enabled in the kernel configuration (CONFIG_EXT4_FS_POSIX_ACL), ACL
+			is enabled by default on mount. See the acl(5) manual page for more
+			information about acl.
 ====================	=======================================================
 
 
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 291583005dd1..53ea58ab83f5 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -457,6 +457,13 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root)
 	seq_printf(s, ",assert=%s", ubifs_assert_action_name(c));
 	seq_printf(s, ",ubi=%d,vol=%d", c->vi.ubi_num, c->vi.vol_id);
 
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+	if (c->mount_opts.acl == 2)
+		seq_puts(s, ",acl");
+	else if (c->mount_opts.acl == 1)
+		seq_puts(s, ",noacl");
+#endif
+
 	return 0;
 }
 
@@ -967,6 +974,8 @@ static int check_volume_empty(struct ubifs_info *c)
  * Opt_assert: set ubifs_assert() action
  * Opt_auth_key: The key name used for authentication
  * Opt_auth_hash_name: The hash type used for authentication
+ * Opt_acl: enable posix acl
+ * Opt_noacl: disable posix acl
  * Opt_err: just end of array marker
  */
 enum {
@@ -981,6 +990,8 @@ enum {
 	Opt_auth_key,
 	Opt_auth_hash_name,
 	Opt_ignore,
+	Opt_acl,
+	Opt_noacl,
 	Opt_err,
 };
 
@@ -997,6 +1008,8 @@ static const match_table_t tokens = {
 	{Opt_ignore, "ubi=%s"},
 	{Opt_ignore, "vol=%s"},
 	{Opt_assert, "assert=%s"},
+	{Opt_acl, "acl"},
+	{Opt_noacl, "noacl"},
 	{Opt_err, NULL},
 };
 
@@ -1137,6 +1150,21 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
 			break;
 		case Opt_ignore:
 			break;
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+		case Opt_acl:
+			c->mount_opts.acl = 2;
+			break;
+		case Opt_noacl:
+			c->mount_opts.acl = 1;
+			break;
+#else
+		case Opt_acl:
+			ubifs_err(c, "acl options not supported");
+			return -EINVAL;
+		case Opt_noacl:
+			ubifs_err(c, "noacl options not supported");
+			return -EINVAL;
+#endif
 		default:
 		{
 			unsigned long flag;
@@ -2017,6 +2045,12 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 		return err;
 	}
 
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+	if (c->mount_opts.acl == 1)
+		c->vfs_sb->s_flags &= ~SB_POSIXACL;
+	else
+		c->vfs_sb->s_flags |= SB_POSIXACL;
+#endif
 	if (c->ro_mount && !(*flags & SB_RDONLY)) {
 		if (c->ro_error) {
 			ubifs_msg(c, "cannot re-mount R/W due to prior errors");
@@ -2199,6 +2233,13 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 	if (err)
 		goto out_close;
 
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+	if (c->mount_opts.acl == 1)
+		c->vfs_sb->s_flags &= ~SB_POSIXACL;
+	else
+		c->vfs_sb->s_flags |= SB_POSIXACL;
+#endif
+
 	/*
 	 * UBIFS provides 'backing_dev_info' in order to disable read-ahead. For
 	 * UBIFS, I/O is not deferred, it is done immediately in read_folio,
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index b96c2462237a..731f433ded68 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -956,6 +956,7 @@ struct ubifs_orphan {
  *                  specified in @compr_type)
  * @compr_type: compressor type to override the superblock compressor with
  *              (%UBIFS_COMPR_NONE, etc)
+ * @acl: enable/disable posix acl (%0 default, %1 disable, %2 enable)
  */
 struct ubifs_mount_opts {
 	unsigned int unmount_mode:2;
@@ -963,6 +964,7 @@ struct ubifs_mount_opts {
 	unsigned int chk_data_crc:2;
 	unsigned int override_compr:1;
 	unsigned int compr_type:2;
+	unsigned int acl:2;
 };
 
 /**
-- 
2.34.1


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

* Re: [RFC PATCH v2 2/5] ubifs: Implement POSIX Access Control Lists (ACLs)
  2024-03-22 15:48 ` [RFC PATCH v2 2/5] ubifs: Implement POSIX Access Control Lists (ACLs) Li Zetao
@ 2024-03-23  2:42   ` Zhihao Cheng
  0 siblings, 0 replies; 8+ messages in thread
From: Zhihao Cheng @ 2024-03-23  2:42 UTC (permalink / raw
  To: Li Zetao, richard, corbet, kent.overstreet, agruenba
  Cc: linux-mtd, linux-doc, linux-kernel

在 2024/3/22 23:48, Li Zetao 写道:
> Implement the ACLs feature for ubifs based on vfs Posix ACLs,
> details as follows:
>    * Initialize acl for newly created inode.
>    * Provides get/set interface to access ACLs.
> 
> ACLs feature relies on xattr implementation which using specific key
> names "system.posix_acl_default" and "system.posix_acl_access". Now Only
> the v2 version of POSIX ACLs is supported, and ubifs does not need to
> customize the storage format, which can simplify the implementation.
> 
> It should be noted that Linux supports updating the file mode through
> ACLs. However the acl may not exist, so ubifs_xattr_remove() returns
> -ENODATA. Such a scenario needs to be specially handled. At the same
> time, it needs to ensure that the updated inode is written to flash.
> 
> Signed-off-by: Li Zetao <lizetao1@huawei.com>
> ---
> v1 -> v2:
>    * Get xattr_name by direct expansion instead of posix_acl_xattr_name().
>    * Modify ubifs_xattr_remove to an external function to remove the xattr of ACL.
>    * Remove redundant likely() and unlikely().
>    * Fix updating file mode via ACL and support writing to flash.
> 
> v1: https://lore.kernel.org/all/20240319161646.2153867-2-lizetao1@huawei.com/
> 
>   fs/ubifs/Makefile |   1 +
>   fs/ubifs/acl.c    | 192 ++++++++++++++++++++++++++++++++++++++++++++++
>   fs/ubifs/ubifs.h  |  14 ++++
>   fs/ubifs/xattr.c  |   3 +-
>   4 files changed, 208 insertions(+), 2 deletions(-)
>   create mode 100644 fs/ubifs/acl.c
> 
[...]
> +static int ubifs_update_mode(struct inode *inode, umode_t mode)
> +{
> +	struct ubifs_inode *ui = ubifs_inode(inode);
> +	struct ubifs_info *c = inode->i_sb->s_fs_info;
> +	struct ubifs_budget_req req = { .dirtied_ino = 1,
> +				.dirtied_ino_d = ALIGN(ui->data_len, 8) };
> +	int release;
> +	int err;
> +
> +	err = ubifs_budget_space(c, &req);
> +	if (err)
> +		return err;
> +
> +	mutex_lock(&ui->ui_mutex);
> +	release = ui->dirty;
> +	inode->i_mode = mode;
> +	inode_set_ctime_current(inode);
> +	mark_inode_dirty_sync(inode);
> +	mutex_unlock(&ui->ui_mutex);
> +
> +	if (release)
> +		ubifs_release_budget(c, &req);
> +	if (IS_SYNC(inode))
> +		err = inode->i_sb->s_op->write_inode(inode, NULL);
> +
> +	return err;
> +}
> +
> +int ubifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, struct posix_acl *acl, int type)
> +{
> +	struct inode *inode = d_inode(dentry);
> +	umode_t mode = inode->i_mode;
> +	bool update_mode = false;
> +	int error;
> +
> +	if (type == ACL_TYPE_ACCESS && acl) {
> +		error = posix_acl_update_mode(idmap, inode, &mode, &acl);
> +		if (unlikely(error))
> +			return error;
> +
> +		if (inode->i_mode != mode)
> +			update_mode = true;
> +	}
> +
> +	error = __ubifs_set_acl(inode, type, acl, 0);
> +	if (!error && update_mode)
> +		error = ubifs_update_mode(inode, mode);

Updating inode mode to disk is a right thing. However, this makes 
ubifs_set_acl is not atomic, which is manifested in two points:
1. If ubifs_budget_space fails by ENOSPC, __ubifs_set_acl has stored 
xattrs into disk, but inode mode is not updated, which makes inode->mode 
be inconsistent with acl. This problem can be easily solved by moving 
ubifs_budget_space before the __ubifs_set_acl.
2. If ubifs_write_inode fails or a powercut happens between 
__ubifs_set_acl and ubifs_write_inode, inode->mode becomes inconsistent 
with acl. PS: Ext4 makes set_acl atomic by 'handle'.
> +
> +	return error;
> +
> +}

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

* Re: [RFC PATCH v2 5/5] ubifs: Introduce ACLs mount options
  2024-03-22 15:48 ` [RFC PATCH v2 5/5] ubifs: Introduce ACLs mount options Li Zetao
@ 2024-03-23  2:55   ` Zhihao Cheng
  0 siblings, 0 replies; 8+ messages in thread
From: Zhihao Cheng @ 2024-03-23  2:55 UTC (permalink / raw
  To: Li Zetao, richard, corbet, kent.overstreet, agruenba
  Cc: linux-mtd, linux-doc, linux-kernel

在 2024/3/22 23:48, Li Zetao 写道:
> Implement the ability to enable or disable the ACLs feature through
> mount options. "-o acl" option means enable and "-o noacl" means disable
> and it is enable by default.
> 
> Signed-off-by: Li Zetao <lizetao1@huawei.com>
> ---
> v1 -> v2:
>    * Remove redundant assignments to mount.acl.
>    * Added the description of acl mount options in ubifs.rst.
> 
> v1: https://lore.kernel.org/all/20240319161646.2153867-5-lizetao1@huawei.com/
> 
>   Documentation/filesystems/ubifs.rst |  4 +++
>   fs/ubifs/super.c                    | 41 +++++++++++++++++++++++++++++
>   fs/ubifs/ubifs.h                    |  2 ++
>   3 files changed, 47 insertions(+)
> 
> diff --git a/Documentation/filesystems/ubifs.rst b/Documentation/filesystems/ubifs.rst
> index ced2f7679ddb..f9615104d7a3 100644
> --- a/Documentation/filesystems/ubifs.rst
> +++ b/Documentation/filesystems/ubifs.rst
> @@ -105,6 +105,10 @@ auth_key=		specify the key used for authenticating the filesystem.
>   auth_hash_name=		The hash algorithm used for authentication. Used for
>   			both hashing and for creating HMACs. Typical values
>   			include "sha256" or "sha512"
> +noacl			This option disables POSIX Access Control List support. If ACL support
> +			is enabled in the kernel configuration (CONFIG_EXT4_FS_POSIX_ACL), ACL
> +			is enabled by default on mount. See the acl(5) manual page for more
> +			information about acl.
Also add acl description?
Split documentation into a new patch?

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

end of thread, other threads:[~2024-03-23  2:55 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-22 15:48 [RFC PATCH v2 0/5] ubifs: Support POSIX Access Control Lists (ACLs) Li Zetao
2024-03-22 15:48 ` [RFC PATCH v2 1/5] ubifs: Add ACLs config option Li Zetao
2024-03-22 15:48 ` [RFC PATCH v2 2/5] ubifs: Implement POSIX Access Control Lists (ACLs) Li Zetao
2024-03-23  2:42   ` Zhihao Cheng
2024-03-22 15:48 ` [RFC PATCH v2 3/5] ubifs: Initialize or update ACLs for inode Li Zetao
2024-03-22 15:48 ` [RFC PATCH v2 4/5] ubifs: Support accessing ACLs through inode_operations Li Zetao
2024-03-22 15:48 ` [RFC PATCH v2 5/5] ubifs: Introduce ACLs mount options Li Zetao
2024-03-23  2:55   ` Zhihao Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).