From 83d9000051629b148647d49f9017183db5ffa6a3 Mon Sep 17 00:00:00 2001 From: linqiheng Date: Tue, 10 Jan 2023 15:13:53 +0000 Subject: [PATCH 1/3] hmdfs: avoid recv_task racing when concurrently handle cmds When CMD_UPDATE_SOCKET and CMD_OFF_LINE operate on the same fd concurrently, there is no lock protection after acquiring the same connect_handle, which is released and emptied by tcp_close_socket() before the wake_up_process() call. Signed-off-by: linqiheng --- fs/hmdfs/comm/device_node.c | 2 ++ fs/hmdfs/hmdfs.h | 1 + fs/hmdfs/main.c | 1 + 3 files changed, 4 insertions(+) diff --git a/fs/hmdfs/comm/device_node.c b/fs/hmdfs/comm/device_node.c index 7c2bac914bb4..0f2585de61fe 100644 --- a/fs/hmdfs/comm/device_node.c +++ b/fs/hmdfs/comm/device_node.c @@ -232,9 +232,11 @@ static ssize_t sbi_cmd_store(struct kobject *kobj, struct sbi_attribute *attr, hmdfs_err("Illegal cmd : cmd = %d", cmd); return len; } + mutex_lock(&sbi->cmd_handler_mutex); hmdfs_info("Recved cmd: %s", cmd2str(cmd)); if (cmd_handler[cmd]) cmd_handler[cmd](buf, len, sbi); + mutex_unlock(&sbi->cmd_handler_mutex); return len; } diff --git a/fs/hmdfs/hmdfs.h b/fs/hmdfs/hmdfs.h index 9157c55ba392..45fcf9f9b3f3 100644 --- a/fs/hmdfs/hmdfs.h +++ b/fs/hmdfs/hmdfs.h @@ -169,6 +169,7 @@ struct hmdfs_sb_info { /* To bridge the userspace utils */ struct kfifo notify_fifo; spinlock_t notify_fifo_lock; + struct mutex cmd_handler_mutex; /* For reboot detect */ uint64_t boot_cookie; diff --git a/fs/hmdfs/main.c b/fs/hmdfs/main.c index 53d698917969..8075fe4bc5c9 100644 --- a/fs/hmdfs/main.c +++ b/fs/hmdfs/main.c @@ -692,6 +692,7 @@ static int hmdfs_init_sbi(struct hmdfs_sb_info *sbi) ret = 0; spin_lock_init(&sbi->notify_fifo_lock); + mutex_init(&sbi->cmd_handler_mutex); sbi->s_case_sensitive = false; sbi->s_features = HMDFS_FEATURE_READPAGES | HMDFS_FEATURE_READPAGES_OPEN | -- Gitee From 63b48ca603fd1e4dcf3d0352080652ab9886375c Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Tue, 17 Jan 2023 11:46:07 +0800 Subject: [PATCH 2/3] hmdfs: fix UAF of mdi(or d_fsdata) merge_lookup_async() adds the lookup works, and merge_lookup_work_func() consumes the works. The mdi->work_lock should protect the mdi->work_count to avoid d_release_merge free the mdi(or d_fsdata). Signed-off-by: Qiheng Lin Change-Id: I31a688940ee710467a6350a51f986ad40bb615cb --- fs/hmdfs/inode_merge.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/hmdfs/inode_merge.c b/fs/hmdfs/inode_merge.c index c020c8c201fa..c5cd7bdc4905 100644 --- a/fs/hmdfs/inode_merge.c +++ b/fs/hmdfs/inode_merge.c @@ -408,6 +408,7 @@ static void merge_lookup_work_func(struct work_struct *work) comrade = merge_lookup_comrade(ml_work->sbi, ml_work->name, ml_work->devid, ml_work->flags); if (IS_ERR(comrade)) { + mutex_lock(&mdi->work_lock); goto out; } @@ -504,6 +505,7 @@ static int lookup_merge_normal(struct dentry *dentry, unsigned int flags) goto out_ppath; } + mutex_lock(&mdi->work_lock); mutex_lock(&sbi->connections.node_lock); if (mdi->type != DT_REG || devid == 0) { snprintf(cpath, PATH_MAX, "device_view/local%s/%s", ppath, @@ -524,6 +526,7 @@ static int lookup_merge_normal(struct dentry *dentry, unsigned int flags) hmdfs_err("failed to create remote lookup work"); } mutex_unlock(&sbi->connections.node_lock); + mutex_unlock(&mdi->work_lock); wait_event(mdi->wait_queue, is_merge_lookup_end(mdi)); -- Gitee From eb9c6f5946ec208e984be8c0e67968427af625ac Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Tue, 17 Jan 2023 16:52:07 +0800 Subject: [PATCH 3/3] hmdfs: fix client readdir dentry file leak Signed-off-by: Qiheng Lin Change-Id: I34b7de075e891f7bcc8669f99a7fbc67c6a49a7d --- fs/hmdfs/comm/socket_adapter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/hmdfs/comm/socket_adapter.c b/fs/hmdfs/comm/socket_adapter.c index 7005303e3735..0404c2a79d3a 100644 --- a/fs/hmdfs/comm/socket_adapter.c +++ b/fs/hmdfs/comm/socket_adapter.c @@ -439,13 +439,13 @@ int hmdfs_sendmessage_request(struct hmdfs_peer *con, msg_wq = kzalloc(sizeof(*msg_wq), GFP_KERNEL); if (!msg_wq) { ret = -ENOMEM; - goto free; + goto free_filp; } ret = msg_init(con, msg_wq); if (ret) { kfree(msg_wq); msg_wq = NULL; - goto free; + goto free_filp; } dec = true; head->msg_id = cpu_to_le32(msg_wq->head.msg_id); @@ -513,6 +513,7 @@ int hmdfs_sendmessage_request(struct hmdfs_peer *con, free_filp: if (sm->local_filp) fput(sm->local_filp); + kfree(head); return ret; } -- Gitee