From: Gou Hao gouhao@uniontech.com
uniontech inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I40JRR CVE: NA
--------------
Support non privileged process setting extended attributes.
Signed-off-by: Gou Hao gouhao@uniontech.com --- fs/eulerfs/Makefile | 2 +- fs/eulerfs/const.h | 1 + fs/eulerfs/super.c | 27 ++++++++++++++++++++++++++ fs/eulerfs/xattr.c | 10 ++++++++-- fs/eulerfs/xattr.h | 1 + fs/eulerfs/xattr_user.c | 43 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 fs/eulerfs/xattr_user.c
diff --git a/fs/eulerfs/Makefile b/fs/eulerfs/Makefile index 60803f44e586..fe12ea71603c 100644 --- a/fs/eulerfs/Makefile +++ b/fs/eulerfs/Makefile @@ -7,4 +7,4 @@ obj-$(CONFIG_EULER_FS) += eulerfs.o eulerfs-y := dir.o file.o inode.o namei.o super.o symlink.o eulerfs-y += dax.o dht.o dep.o nvalloc.o wear.o eulerfs-y += kmem_cache.o -eulerfs-$(CONFIG_EULER_FS_XATTR) += xattr.o +eulerfs-$(CONFIG_EULER_FS_XATTR) += xattr.o xattr_user.o diff --git a/fs/eulerfs/const.h b/fs/eulerfs/const.h index 1e3485ecc8a0..94a8a9ec0014 100644 --- a/fs/eulerfs/const.h +++ b/fs/eulerfs/const.h @@ -20,6 +20,7 @@ #define EUFS_MOUNT_ERRORS_RO 0x000001 /* Remount fs ro on errors */ #define EUFS_MOUNT_ERRORS_PANIC 0x000002 /* Panic on errors */ #define EUFS_MOUNT_FORMAT 0x000004 /* was FS formatted on mount? */ +#define EUFS_MOUNT_XATTR_USER 0x000008 /* Extended user attributes */
#define NULL_ADDR ((u64)-1ll) #define NULL_VAL (0) diff --git a/fs/eulerfs/super.c b/fs/eulerfs/super.c index d1886b5d3545..689b24e51cbd 100644 --- a/fs/eulerfs/super.c +++ b/fs/eulerfs/super.c @@ -40,6 +40,7 @@ #include "dep.h" #include "nvalloc.h" #include "wear.h" +#include "xattr.h"
int support_clwb; int support_clflushopt; @@ -164,12 +165,16 @@ static int eufs_get_block_info(struct super_block *sb, struct eufs_sb_info *sbi) enum { Opt_init, Opt_dax, + Opt_user_xattr, + Opt_nouser_xattr, Opt_err };
static const match_table_t tokens = { { Opt_init, "init" }, { Opt_dax, "dax" }, /* DAX is always on. This is for compatibility. */ + { Opt_user_xattr, "user_xattr"}, + { Opt_nouser_xattr, "nouser_xattr"}, { Opt_err, NULL }, };
@@ -197,6 +202,19 @@ static int eufs_parse_options(char *options, struct eufs_sb_info *sbi, break; case Opt_dax: break; +#ifdef CONFIG_EUFS_XATTR + case Opt_user_xattr: + set_opt(sbi->s_mount_opt, XATTR_USER); + break; + case Opt_nouser_xattr: + clear_opt(sbi->s_mount_opt, XATTR_USER); + break; +#else + case Opt_user_xattr: + case Opt_nouser_xattr: + eufs_info("(no)user_xattr options not supported"); + break; +#endif default: goto bad_opt; } @@ -401,6 +419,13 @@ static void eufs_destroy_super(struct super_block *sb) kfree(sbi); }
+static void set_default_mount_opts(struct eufs_sb_info *sbi) +{ +#ifdef CONFIG_EULER_FS_XATTR + set_opt(sbi->s_mount_opt, XATTR_USER); +#endif +} + static int eufs_fill_super(struct super_block *sb, void *data, int silent) { struct eufs_super_block __pmem *super; @@ -438,6 +463,8 @@ static int eufs_fill_super(struct super_block *sb, void *data, int silent) mutex_init(&sbi->gather_mutex); mutex_init(&sbi->sync_mutex);
+ set_default_mount_opts(sbi); + err = eufs_parse_options(data, sbi, 0); if (err) goto out; diff --git a/fs/eulerfs/xattr.c b/fs/eulerfs/xattr.c index 3dfa582156e8..6053477bcd23 100644 --- a/fs/eulerfs/xattr.c +++ b/fs/eulerfs/xattr.c @@ -87,8 +87,14 @@ eufs_xattr_cmp_entry(int name_index, size_t name_len, const char *name, return cmp; }
-const struct xattr_handler *eufs_xattr_handlers[] = { NULL }; -static const struct xattr_handler *eufs_xattr_handler_map[] = {}; +const struct xattr_handler *eufs_xattr_handlers[] = { + &eufs_xattr_user_handler, + NULL +}; + +static const struct xattr_handler *eufs_xattr_handler_map[] = { + [EUFS_XATTR_INDEX_USER] = &eufs_xattr_user_handler, +};
static inline const struct xattr_handler *eufs_xattr_handler(int name_index) diff --git a/fs/eulerfs/xattr.h b/fs/eulerfs/xattr.h index 935fce3acb68..c4ec5b57a208 100644 --- a/fs/eulerfs/xattr.h +++ b/fs/eulerfs/xattr.h @@ -59,6 +59,7 @@ struct eufs_xattr_entry {
#ifdef CONFIG_EULER_FS_XATTR
+extern const struct xattr_handler eufs_xattr_user_handler; extern const struct xattr_handler *eufs_xattr_handlers[];
extern int eufs_xattr_get(struct inode *inode, int name_index, diff --git a/fs/eulerfs/xattr_user.c b/fs/eulerfs/xattr_user.c new file mode 100644 index 000000000000..82b3d7ff83b0 --- /dev/null +++ b/fs/eulerfs/xattr_user.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Handler for extended user attributes. + * + * Copyright (C) 2001 by Andreas Gruenbacher, a.gruenbacher@computer.org + * + * This file was modified by UnionTech Software Technology Co., Ltd. in + * 2022/07/05 by Gou Hao gouhao@uniontech.com + */ +#include "xattr.h" +#include "euler.h" + +static bool eufs_xattr_user_list(struct dentry *dentry) +{ + return test_opt(dentry->d_sb, XATTR_USER); +} + +static int eufs_xattr_user_get(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *buffer, size_t size) +{ + if (!test_opt(inode->i_sb, XATTR_USER)) + return -EOPNOTSUPP; + return eufs_xattr_get(inode, EUFS_XATTR_INDEX_USER, + name, buffer, size); +} + +static int eufs_xattr_user_set(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, const void *value, + size_t size, int flags) +{ + if (!test_opt(inode->i_sb, XATTR_USER)) + return -EOPNOTSUPP; + return eufs_xattr_set(inode, EUFS_XATTR_INDEX_USER, + name, value, size, flags); +} +const struct xattr_handler eufs_xattr_user_handler = { + .prefix = XATTR_USER_PREFIX, + .list = eufs_xattr_user_list, + .get = eufs_xattr_user_get, + .set = eufs_xattr_user_set +};