From 0a9b9822606f0a10864da9cb0a9881a1b3b7bfed Mon Sep 17 00:00:00 2001 From: waterwin Date: Tue, 8 Feb 2022 21:18:30 +0800 Subject: [PATCH] hmdfs: Introduce authority to hmdfs ohos inclusion category: feature issue: #I4SW8O CVE: NA ---------------------------------------------- hmdfs manage permission by configfs, bundle access its bundle directory but other directory. Signed-off-by: qianjiaxing --- fs/hmdfs/Makefile | 1 + fs/hmdfs/authority/authentication.c | 94 +++---- fs/hmdfs/authority/authentication.h | 38 ++- fs/hmdfs/authority/config.c | 377 ++++++++++++++++++++++++++++ fs/hmdfs/inode_local.c | 8 +- fs/hmdfs/main.c | 7 + 6 files changed, 451 insertions(+), 74 deletions(-) create mode 100644 fs/hmdfs/authority/config.c diff --git a/fs/hmdfs/Makefile b/fs/hmdfs/Makefile index 25c3eef3dd9d..6f38c843664e 100644 --- a/fs/hmdfs/Makefile +++ b/fs/hmdfs/Makefile @@ -11,5 +11,6 @@ hmdfs-y += comm/connection.o comm/socket_adapter.o comm/transport.o hmdfs-$(CONFIG_HMDFS_FS_ENCRYPTION) += comm/crypto.o hmdfs-$(CONFIG_HMDFS_FS_PERMISSION) += authority/authentication.o +hmdfs-$(CONFIG_HMDFS_FS_PERMISSION) += authority/config.o hmdfs-$(CONFIG_FS_FAULT_INJECTION) += comm/fault_inject.o diff --git a/fs/hmdfs/authority/authentication.c b/fs/hmdfs/authority/authentication.c index 97d842147050..85ac3c96c5b1 100644 --- a/fs/hmdfs/authority/authentication.c +++ b/fs/hmdfs/authority/authentication.c @@ -48,9 +48,8 @@ const struct cred *hmdfs_override_fsids(bool is_recv_thread) if (!cred) return NULL; - cred->fsuid = MEDIA_RW_UID; - cred->fsgid = is_recv_thread ? - KGIDT_INIT((gid_t)AID_EVERYBODY) : MEDIA_RW_GID; + cred->fsuid = is_recv_thread ? SYSTEM_UID : USER_DATA_RW_UID; + cred->fsgid = is_recv_thread ? SYSTEM_GID : USER_DATA_RW_GID; old_cred = override_creds(cred); @@ -73,7 +72,8 @@ const struct cred *hmdfs_override_dir_fsids(struct inode *dir, switch (level) { case HMDFS_PERM_MNT: /* system : media_rw */ - cred->fsuid = SYSTEM_UID; + cred->fsuid = USER_DATA_RW_UID; + cred->fsgid = USER_DATA_RW_GID; perm = (hii->perm & HMDFS_DIR_TYPE_MASK) | level; break; case HMDFS_PERM_DFS: @@ -83,15 +83,12 @@ const struct cred *hmdfs_override_dir_fsids(struct inode *dir, * other : media_rw : media_rw **/ if (!strcmp(dentry->d_name.name, PKG_ROOT_NAME)) { - cred->fsuid = SYSTEM_UID; perm = HMDFS_DIR_DATA | level; - } else if (!strcmp(dentry->d_name.name, SYSTEM_NAME)) { - cred->fsuid = SYSTEM_UID; - perm = AUTH_SYSTEM | HMDFS_DIR_SYSTEM | level; } else { - cred->fsuid = MEDIA_RW_UID; perm = HMDFS_DIR_PUBLIC | level; } + cred->fsuid = USER_DATA_RW_UID; + cred->fsgid = USER_DATA_RW_GID; break; case HMDFS_PERM_PKG: if (is_data_dir(hii->perm)) { @@ -102,20 +99,25 @@ const struct cred *hmdfs_override_dir_fsids(struct inode *dir, * local uninstall. * Set appid + media_rw for local install. */ - uid_t app_id = 0; + int bid = get_bid(dentry->d_name.name); - if (app_id != 0) - cred->fsuid = KUIDT_INIT(app_id); - else + if (bid != 0) { + cred->fsuid = KUIDT_INIT(bid); + cred->fsgid = KGIDT_INIT(bid); + } else { cred->fsuid = ROOT_UID; + cred->fsgid = ROOT_GID; + } perm = AUTH_PKG | HMDFS_DIR_PKG | level; } else { cred->fsuid = dir->i_uid; + cred->fsgid = dir->i_gid; perm = (hii->perm & AUTH_MASK) | HMDFS_DIR_DEFAULT | level; } break; case HMDFS_PERM_OTHER: cred->fsuid = dir->i_uid; + cred->fsgid = dir->i_gid; if (is_pkg_auth(hii->perm)) perm = AUTH_PKG | HMDFS_DIR_PKG_SUB | level; else @@ -127,7 +129,6 @@ const struct cred *hmdfs_override_dir_fsids(struct inode *dir, break; } - cred->fsgid = MEDIA_RW_GID; *_perm = perm; old_cred = override_creds(cred); @@ -312,27 +313,6 @@ static __u16 __inherit_perm_file(struct inode *parent) return perm; } -static void fixup_ownership(struct inode *child, struct dentry *lower_dentry, - uid_t uid) -{ - int err; - struct iattr newattrs; - - newattrs.ia_valid = ATTR_UID | ATTR_FORCE; - newattrs.ia_uid = KUIDT_INIT(uid); - if (!S_ISDIR(d_inode(lower_dentry)->i_mode)) - newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; - - inode_lock(d_inode(lower_dentry)); - err = notify_change(lower_dentry, &newattrs, NULL); - inode_unlock(d_inode(lower_dentry)); - - if (!err) - child->i_uid = KUIDT_INIT(uid); - else - hmdfs_err("update PKG uid failed, err = %d", err); -} - static void fixup_ownership_user_group(struct inode *child, struct dentry *lower_dentry, uid_t uid, gid_t gid) { @@ -371,7 +351,7 @@ __u16 hmdfs_perm_inherit(struct inode *parent_inode, struct inode *child) void check_and_fixup_ownership(struct inode *parent_inode, struct inode *child, struct dentry *lower_dentry, const char *name) { - uid_t appid; + int bid; struct hmdfs_inode_info *info = hmdfs_i(child); if (info->perm == HMDFS_ALL_MASK) @@ -379,25 +359,22 @@ void check_and_fixup_ownership(struct inode *parent_inode, struct inode *child, switch (info->perm & HMDFS_DIR_TYPE_MASK) { case HMDFS_DIR_PKG: - appid = 0; - if (appid != child->i_uid.val) - fixup_ownership(child, lower_dentry, appid); + bid = get_bid(name); + if (bid != child->i_uid.val || bid != child->i_gid.val) + fixup_ownership_user_group(child, lower_dentry, bid, bid); break; case HMDFS_DIR_DATA: case HMDFS_FILE_PKG_SUB: case HMDFS_DIR_DEFAULT: case HMDFS_FILE_DEFAULT: + case HMDFS_DIR_PUBLIC: if (parent_inode->i_uid.val != child->i_uid.val || parent_inode->i_gid.val != child->i_gid.val) fixup_ownership_user_group(child, lower_dentry, parent_inode->i_uid.val, parent_inode->i_gid.val); break; - case HMDFS_DIR_PUBLIC: - fixup_ownership(child, lower_dentry, (uid_t)AID_MEDIA_RW); - - break; default: break; } @@ -416,7 +393,8 @@ void check_and_fixup_ownership_remote(struct inode *dir, switch (level) { case HMDFS_PERM_MNT: /* system : media_rw */ - dinode->i_uid = SYSTEM_UID; + dinode->i_uid = USER_DATA_RW_UID; + dinode->i_gid = USER_DATA_RW_GID; perm = (hii->perm & HMDFS_DIR_TYPE_MASK) | level; break; case HMDFS_PERM_DFS: @@ -426,17 +404,12 @@ void check_and_fixup_ownership_remote(struct inode *dir, * other : media_rw : media_rw **/ if (!strcmp(dentry->d_name.name, PKG_ROOT_NAME)) { - // "data" - dinode->i_uid = SYSTEM_UID; perm = HMDFS_DIR_DATA | level; - } else if (!strcmp(dentry->d_name.name, SYSTEM_NAME)) { - // "system" - dinode->i_uid = SYSTEM_UID; - perm = AUTH_SYSTEM | HMDFS_DIR_SYSTEM | level; } else { - dinode->i_uid = MEDIA_RW_UID; perm = HMDFS_DIR_PUBLIC | level; } + dinode->i_uid = USER_DATA_RW_UID; + dinode->i_gid = USER_DATA_RW_GID; break; case HMDFS_PERM_PKG: if (is_data_dir(hii->perm)) { @@ -447,20 +420,24 @@ void check_and_fixup_ownership_remote(struct inode *dir, * local uninstall. * Set appid + media_rw for local install. */ - uid_t app_id = 0; - - if (app_id != 0) - dinode->i_uid = KUIDT_INIT(app_id); - else + int bid = get_bid(dentry->d_name.name); + if (bid != 0) { + dinode->i_uid = KUIDT_INIT(bid); + dinode->i_gid = KGIDT_INIT(bid); + } else { dinode->i_uid = ROOT_UID; + dinode->i_gid = ROOT_GID; + } perm = AUTH_PKG | HMDFS_DIR_PKG | level; } else { dinode->i_uid = dir->i_uid; + dinode->i_gid = dir->i_gid; perm = (hii->perm & AUTH_MASK) | HMDFS_DIR_DEFAULT | level; } break; case HMDFS_PERM_OTHER: dinode->i_uid = dir->i_uid; + dinode->i_gid = dir->i_gid; if (is_pkg_auth(hii->perm)) perm = AUTH_PKG | HMDFS_DIR_PKG_SUB | level; else @@ -472,7 +449,6 @@ void check_and_fixup_ownership_remote(struct inode *dir, break; } - dinode->i_gid = MEDIA_RW_GID; dinfo->perm = perm; } @@ -481,6 +457,6 @@ void hmdfs_root_inode_perm_init(struct inode *root_inode) struct hmdfs_inode_info *hii = hmdfs_i(root_inode); hii->perm = HMDFS_DIR_ROOT | HMDFS_PERM_MNT; - set_inode_uid(root_inode, SYSTEM_UID); - set_inode_gid(root_inode, MEDIA_RW_GID); + set_inode_uid(root_inode, USER_DATA_RW_UID); + set_inode_gid(root_inode, USER_DATA_RW_GID); } diff --git a/fs/hmdfs/authority/authentication.h b/fs/hmdfs/authority/authentication.h index e8b7bed53fb9..26838e2e8128 100644 --- a/fs/hmdfs/authority/authentication.h +++ b/fs/hmdfs/authority/authentication.h @@ -23,24 +23,22 @@ struct cache_fs_override { #ifdef CONFIG_HMDFS_FS_PERMISSION -#define AID_ROOT 0 -#define AID_SYSTEM 1000 -#define AID_SDCARD_RW 1015 -#define AID_MEDIA_RW 1023 -#define AID_EVERYBODY 9997 +#define OID_ROOT 0 +#define OID_SYSTEM 1000 +#define OID_USER_DATA_RW 1008 /* copied from sdcardfs/multiuser.h */ -#define AID_USER_OFFSET 100000 /* offset for uid ranges for each user */ +#define BASE_USER_RANGE 200000 /* offset for uid ranges for each user */ #define HMDFS_PERM_XATTR "user.hmdfs.perm" -#define ROOT_UID KUIDT_INIT(AID_ROOT) -#define SYSTEM_UID KUIDT_INIT(AID_SYSTEM) -#define MEDIA_RW_UID KUIDT_INIT(AID_MEDIA_RW) +#define ROOT_UID KUIDT_INIT(OID_ROOT) +#define SYSTEM_UID KUIDT_INIT(OID_SYSTEM) +#define USER_DATA_RW_UID KUIDT_INIT(OID_USER_DATA_RW) -#define SYSTEM_GID KGIDT_INIT((gid_t) AID_SYSTEM) -#define MEDIA_RW_GID KGIDT_INIT(AID_MEDIA_RW) -#define SDCARD_RW_GID KGIDT_INIT(AID_SDCARD_RW) +#define ROOT_GID KGIDT_INIT(OID_ROOT) +#define SYSTEM_GID KGIDT_INIT(OID_SYSTEM) +#define USER_DATA_RW_GID KGIDT_INIT(OID_USER_DATA_RW) #define PKG_ROOT_NAME "data" #define SYSTEM_NAME "system" @@ -89,7 +87,7 @@ static inline bool is_perm_other(__u16 perm) static inline void hmdfs_check_cred(const struct cred *cred) { - if (cred->fsuid.val != AID_SYSTEM || cred->fsgid.val != AID_SYSTEM) + if (cred->fsuid.val != OID_SYSTEM || cred->fsgid.val != OID_SYSTEM) hmdfs_warning("uid is %u, gid is %u", cred->fsuid.val, cred->fsgid.val); } @@ -176,6 +174,13 @@ static inline bool is_system_auth(__u16 perm) #define HMDFS_ALL_MASK (HMDFS_MOUNT_POINT_MASK | AUTH_MASK | HMDFS_DIR_TYPE_MASK | HMDFS_PERM_MASK) +static inline kuid_t get_bid_from_uid(kuid_t uid) +{ + kuid_t bid; + + bid.val = uid.val % BASE_USER_RANGE; + return bid; +} static inline void set_inode_gid(struct inode *inode, kgid_t gid) { @@ -250,6 +255,9 @@ int hmdfs_override_dir_id_fs(struct cache_fs_override *or, void hmdfs_revert_dir_id_fs(struct cache_fs_override *or); void check_and_fixup_ownership_remote(struct inode *dir, struct dentry *dentry); +extern int get_bid(const char *bname); +extern int __init hmdfs_init_configfs(void); +extern void hmdfs_exit_configfs(void); #else @@ -323,6 +331,10 @@ void hmdfs_check_cred(const struct cred *cred) { } +static inline int get_bid(const char *bname) { return 0; } +static inline int __init hmdfs_init_configfs(void) { return 0; } +static inline void hmdfs_exit_configfs(void) {} + #endif /* CONFIG_HMDFS_FS_PERMISSION */ #endif diff --git a/fs/hmdfs/authority/config.c b/fs/hmdfs/authority/config.c new file mode 100644 index 000000000000..2daadd40704e --- /dev/null +++ b/fs/hmdfs/authority/config.c @@ -0,0 +1,377 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * fs/hmdfs/comm/authority/config.c + * + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include "hmdfs.h" + +#define UID_ATTR_TYPE 0 +#define GID_ATTR_TYPE 1 + +static struct kmem_cache *hmdfs_bid_entry_cachep; + +struct hmdfs_bid_entry { + struct hlist_node node; + struct qstr str; + int id; +}; + +struct hmdfs_config_bitem { + struct config_item item; + struct qstr str; +}; + +static unsigned int make_hash(const char *name, unsigned int len) +{ + unsigned long hash; + + hash = init_name_hash(0); + while (len--) + hash = partial_name_hash(tolower(*name++), hash); + + return end_name_hash(hash); +} + +static struct qstr make_qstr(const char *name) +{ + struct qstr str; + str.name = name; + str.len = strlen(name); + str.hash = make_hash(str.name, str.len); + + return str; +} + +static struct hmdfs_bid_entry *alloc_bid_entry(const char *name, int id) +{ + struct hmdfs_bid_entry *bid_entry; + char *bid_entry_name; + + bid_entry = kmem_cache_alloc(hmdfs_bid_entry_cachep, GFP_KERNEL); + if (!bid_entry) { + bid_entry = ERR_PTR(-ENOMEM); + goto out; + } + + bid_entry_name = kstrdup(name, GFP_KERNEL); + if (!bid_entry_name) { + kmem_cache_free(hmdfs_bid_entry_cachep, bid_entry); + bid_entry = ERR_PTR(-ENOMEM); + goto out; + } + + INIT_HLIST_NODE(&bid_entry->node); + bid_entry->str = make_qstr(bid_entry_name); + bid_entry->id = id; +out: + return bid_entry; +} + +static void free_bid_entry(struct hmdfs_bid_entry *bid_entry) +{ + if (bid_entry == NULL) + return; + + kfree(bid_entry->str.name); + kmem_cache_free(hmdfs_bid_entry_cachep, bid_entry); +} + +static struct hmdfs_config_bitem *alloc_bitem(const char *name) +{ + struct hmdfs_config_bitem *bitem; + char *bitem_name; + + bitem = kzalloc(sizeof(*bitem), GFP_KERNEL); + if (!bitem) { + bitem = ERR_PTR(-ENOMEM); + goto out; + } + + bitem_name = kstrdup(name, GFP_KERNEL); + if (!bitem_name) { + kfree(bitem); + bitem = ERR_PTR(-ENOMEM); + goto out; + } + + bitem->str = make_qstr(bitem_name); +out: + return bitem; +} + +static void free_bitem(struct hmdfs_config_bitem *bitem) +{ + if (bitem == NULL) + return; + + kfree(bitem->str.name); + kfree(bitem); +} + +#define HMDFS_BUNDLE_ATTRIBUTE(_attr_) \ + \ +static DEFINE_HASHTABLE(hmdfs_##_attr_##_hash_table, 4); \ + \ +static DEFINE_MUTEX(hmdfs_##_attr_##_hash_mutex); \ + \ +static int query_##_attr_##_hash_entry(struct qstr *str) \ +{ \ + int id = 0; \ + struct hmdfs_bid_entry *bid_entry; \ + struct hlist_node *hash_node; \ + \ + mutex_lock(&hmdfs_##_attr_##_hash_mutex); \ + hash_for_each_possible_safe(hmdfs_##_attr_##_hash_table, \ + bid_entry, hash_node, node, str->hash) { \ + if (qstr_case_eq(str, &bid_entry->str)) { \ + id = bid_entry->id; \ + break; \ + } \ + } \ + mutex_unlock(&hmdfs_##_attr_##_hash_mutex); \ + \ + return id; \ +} \ + \ +static int insert_##_attr_##_hash_entry(struct qstr *str, int id) \ +{ \ + int err = 0; \ + struct hmdfs_bid_entry *bid_entry; \ + struct hlist_node *hash_node; \ + \ + hmdfs_info("insert name = %s", str->name); \ + \ + mutex_lock(&hmdfs_##_attr_##_hash_mutex); \ + hash_for_each_possible_safe(hmdfs_##_attr_##_hash_table, \ + bid_entry, hash_node, node, str->hash) { \ + if (qstr_case_eq(str, &bid_entry->str)) { \ + bid_entry->id = id; \ + mutex_unlock(&hmdfs_##_attr_##_hash_mutex); \ + goto out; \ + } \ + } \ + mutex_unlock(&hmdfs_##_attr_##_hash_mutex); \ + \ + bid_entry = alloc_bid_entry(str->name, id); \ + if (IS_ERR(bid_entry)) { \ + err = PTR_ERR(bid_entry); \ + goto out; \ + } \ + \ + hash_add_rcu(hmdfs_##_attr_##_hash_table, &bid_entry->node, \ + bid_entry->str.hash); \ +out: \ + return err; \ +} \ + \ +static void remove_##_attr_##_hash_entry(struct qstr *str) \ +{ \ + struct hmdfs_bid_entry *bid_entry; \ + struct hlist_node *hash_node; \ + \ + hmdfs_info("remove name = %s", str->name); \ + \ + mutex_lock(&hmdfs_##_attr_##_hash_mutex); \ + hash_for_each_possible_safe(hmdfs_##_attr_##_hash_table, \ + bid_entry, hash_node, node, str->hash) { \ + if (qstr_case_eq(str, &bid_entry->str)) { \ + hash_del_rcu(&bid_entry->node); \ + free_bid_entry(bid_entry); \ + break; \ + } \ + } \ + mutex_unlock(&hmdfs_##_attr_##_hash_mutex); \ +} \ + \ +static void clear_##_attr_##_hash_entry(void) \ +{ \ + int index; \ + struct hmdfs_bid_entry *bid_entry; \ + struct hlist_node *hash_node; \ + \ + hmdfs_info("clear bid entry"); \ + \ + mutex_lock(&hmdfs_##_attr_##_hash_mutex); \ + hash_for_each_safe(hmdfs_##_attr_##_hash_table, index, \ + hash_node, bid_entry, node) { \ + hash_del_rcu(&bid_entry->node); \ + kfree(bid_entry->str.name); \ + kmem_cache_free(hmdfs_bid_entry_cachep, bid_entry); \ + } \ + mutex_unlock(&hmdfs_##_attr_##_hash_mutex); \ +} \ + \ +static int hmdfs_##_attr_##_get(const char *bname) \ +{ \ + struct qstr str; \ + \ + str = make_qstr(bname); \ + return query_##_attr_##_hash_entry(&str); \ +} \ + \ +static ssize_t hmdfs_##_attr_##_show(struct config_item *item, \ + char *page) \ +{ \ + int id; \ + struct hmdfs_config_bitem *bitem; \ + \ + hmdfs_info("show bundle id"); \ + \ + bitem = container_of(item, struct hmdfs_config_bitem, item); \ + id = query_##_attr_##_hash_entry(&bitem->str); \ + \ + return scnprintf(page, PAGE_SIZE, "%u\n", id); \ +} \ + \ +static ssize_t hmdfs_##_attr_##_store(struct config_item *item, \ + const char *page, size_t count) \ +{ \ + int id; \ + int err; \ + size_t size; \ + struct hmdfs_config_bitem *bitem; \ + \ + hmdfs_info("store bundle id"); \ + \ + bitem = container_of(item, struct hmdfs_config_bitem, item); \ + \ + if (kstrtouint(page, 10, &id)) { \ + size = -EINVAL; \ + goto out; \ + } \ + \ + err = insert_##_attr_##_hash_entry(&bitem->str, id); \ + if (err) { \ + size = err; \ + goto out; \ + } \ + \ + size = count; \ +out: \ + return size; \ +} \ + \ +static struct configfs_attribute hmdfs_##_attr_##_attr = { \ + .ca_name = __stringify(_attr_), \ + .ca_mode = S_IRUGO | S_IWUGO, \ + .ca_owner = THIS_MODULE, \ + .show = hmdfs_##_attr_##_show, \ + .store = hmdfs_##_attr_##_store, \ +}; + +HMDFS_BUNDLE_ATTRIBUTE(bid) + +static struct configfs_attribute *hmdfs_battrs[] = { + &hmdfs_bid_attr, + NULL, +}; + +static void hmdfs_config_bitem_release(struct config_item *item) +{ + struct hmdfs_config_bitem *bitem; + + hmdfs_info("release bundle item"); + + bitem = container_of(item, struct hmdfs_config_bitem, item); + remove_bid_hash_entry(&bitem->str); + remove_bid_hash_entry(&bitem->str); + free_bitem(bitem); +} + +static struct configfs_item_operations hmdfs_config_bitem_ops = { + .release = hmdfs_config_bitem_release, +}; + +static struct config_item_type hmdfs_config_bitem_type = { + .ct_item_ops = &hmdfs_config_bitem_ops, + .ct_attrs = hmdfs_battrs, + .ct_owner = THIS_MODULE, +}; + +static struct config_item *hmdfs_make_bitem(struct config_group *group, + const char *name) +{ + struct config_item *item; + struct hmdfs_config_bitem *bitem; + + hmdfs_info("make bundle item = %s", name); + + bitem = alloc_bitem(name); + if (IS_ERR(bitem)) { + item = ERR_PTR(-ENOMEM); + goto out; + } + + config_item_init_type_name(&bitem->item, name, + &hmdfs_config_bitem_type); + item = &bitem->item; +out: + return item; +} + +static struct configfs_group_operations hmdfs_group_ops = { + .make_item = hmdfs_make_bitem, +}; + +static struct config_item_type hmdfs_group_type = { + .ct_group_ops = &hmdfs_group_ops, + .ct_owner = THIS_MODULE, +}; + +static struct configfs_subsystem hmdfs_subsystem = { + .su_group = { + .cg_item = { + .ci_namebuf = "hmdfs", + .ci_type = &hmdfs_group_type, + }, + }, +}; + +int get_bid(const char *bname) +{ + return hmdfs_bid_get(bname); +} + +int __init hmdfs_init_configfs(void) +{ + int err; + struct configfs_subsystem *subsys; + + hmdfs_info("init configfs"); + + hmdfs_bid_entry_cachep = kmem_cache_create("hmdfs_bid_entry_cachep", + sizeof(struct hmdfs_bid_entry), 0, 0, NULL); + if (!hmdfs_bid_entry_cachep) { + hmdfs_err("failed to create bid entry cachep"); + err = -ENOMEM; + goto out; + } + + subsys = &hmdfs_subsystem; + config_group_init(&subsys->su_group); + mutex_init(&subsys->su_mutex); + + err = configfs_register_subsystem(subsys); + if (err) + hmdfs_err("failed to register subsystem"); + +out: + return err; +} + +void hmdfs_exit_configfs(void) +{ + hmdfs_info("hmdfs exit configfs"); + + configfs_unregister_subsystem(&hmdfs_subsystem); + clear_bid_hash_entry(); + + kmem_cache_destroy(hmdfs_bid_entry_cachep); +} \ No newline at end of file diff --git a/fs/hmdfs/inode_local.c b/fs/hmdfs/inode_local.c index d34b765ab65d..7afab9d98ada 100644 --- a/fs/hmdfs/inode_local.c +++ b/fs/hmdfs/inode_local.c @@ -872,6 +872,8 @@ static int hmdfs_getattr_local(const struct path *path, struct kstat *stat, hmdfs_get_lower_path(path->dentry, &lower_path); ret = vfs_getattr(&lower_path, stat, request_mask, flags); stat->ino = d_inode(path->dentry)->i_ino; + stat->uid = d_inode(path->dentry)->i_uid; + stat->gid = d_inode(path->dentry)->i_gid; hmdfs_put_lower_path(&lower_path); return ret; @@ -892,10 +894,12 @@ int hmdfs_permission(struct inode *inode, int mask) } else if (in_group_p(inode->i_gid)) { mode >>= 3; } else if (is_pkg_auth(hii->perm)) { - if (uid_eq(cur_uid, inode->i_uid)) + kuid_t bid = get_bid_from_uid(cur_uid); + + if (uid_eq(bid, inode->i_uid)) return 0; } else if (is_system_auth(hii->perm)) { - if (in_group_p(MEDIA_RW_GID)) + if (in_group_p(USER_DATA_RW_GID)) return 0; } diff --git a/fs/hmdfs/main.c b/fs/hmdfs/main.c index c9b28e8cb9f1..0456a247caf6 100644 --- a/fs/hmdfs/main.c +++ b/fs/hmdfs/main.c @@ -1034,6 +1034,11 @@ static int __init hmdfs_init(void) hmdfs_err("hmdfs register failed!"); goto out_err; } + + err = hmdfs_init_configfs(); + if (err) + goto out_err; + err = hmdfs_sysfs_init(); if (err) goto out_err; @@ -1043,6 +1048,7 @@ static int __init hmdfs_init(void) return 0; out_err: hmdfs_sysfs_exit(); + hmdfs_exit_configfs(); unregister_filesystem(&hmdfs_fs_type); hmdfs_destroy_caches(); hmdfs_err("hmdfs init failed!"); @@ -1053,6 +1059,7 @@ static void __exit hmdfs_exit(void) { hmdfs_destroy_debugfs_root(); hmdfs_sysfs_exit(); + hmdfs_exit_configfs(); unregister_filesystem(&hmdfs_fs_type); ida_destroy(&hmdfs_sb_seq); hmdfs_destroy_caches(); -- Gitee