2024-03-22 15:48:45

by Li Zetao

[permalink] [raw]
Subject: [RFC PATCH v2 0/5] ubifs: Support POSIX Access Control Lists (ACLs)

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/[email protected]/
[2]: https://lore.kernel.org/linux-mtd/[email protected]/
[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/[email protected]/


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



2024-03-22 15:48:55

by Li Zetao

[permalink] [raw]
Subject: [RFC PATCH v2 5/5] ubifs: Introduce ACLs mount options

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 <[email protected]>
---
v1 -> v2:
* Remove redundant assignments to mount.acl.
* Added the description of acl mount options in ubifs.rst.

v1: https://lore.kernel.org/all/[email protected]/

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


2024-03-22 15:49:01

by Li Zetao

[permalink] [raw]
Subject: [RFC PATCH v2 3/5] ubifs: Initialize or update ACLs for inode

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 <[email protected]>
---
v1 -> v2: Add initialization ACL in create_whiteout()
v1: https://lore.kernel.org/all/[email protected]/

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


2024-03-22 15:49:24

by Li Zetao

[permalink] [raw]
Subject: [RFC PATCH v2 4/5] ubifs: Support accessing ACLs through inode_operations

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

Signed-off-by: Li Zetao <[email protected]>
---
v1 -> v2: There are no changes to this patch.
v1: https://lore.kernel.org/all/[email protected]/

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


2024-03-23 02:55:42

by Zhihao Cheng

[permalink] [raw]
Subject: Re: [RFC PATCH v2 5/5] ubifs: Introduce ACLs mount options

?? 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 <[email protected]>
> ---
> v1 -> v2:
> * Remove redundant assignments to mount.acl.
> * Added the description of acl mount options in ubifs.rst.
>
> v1: https://lore.kernel.org/all/[email protected]/
>
> 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?