summaryrefslogtreecommitdiffstats
path: root/drivers/md/md.h
diff options
context:
space:
mode:
authorYu Kuai <yukuai3@huawei.com>2023-05-23 10:10:17 +0800
committerSong Liu <song@kernel.org>2023-06-13 15:25:39 -0700
commit4469315439827290923fce4f3f672599cabeb366 (patch)
tree83e7d30c4570cd28774226f0e9d36b110c823ff8 /drivers/md/md.h
parent4eeb6535cd51100460ec8873bb68addef17b3e81 (diff)
downloadlinux-4469315439827290923fce4f3f672599cabeb366.tar.gz
linux-4469315439827290923fce4f3f672599cabeb366.tar.bz2
linux-4469315439827290923fce4f3f672599cabeb366.zip
md: protect md_thread with rcu
Currently, there are many places that md_thread can be accessed without protection, following are known scenarios that can cause null-ptr-dereference or uaf: 1) sync_thread that is allocated and started from md_start_sync() 2) mddev->thread can be accessed directly from timeout_store() and md_bitmap_daemon_work() 3) md_unregister_thread() from action_store(). Currently, a global spinlock 'pers_lock' is borrowed to protect 'mddev->thread' in some places, this problem can be fixed likewise, however, use a global lock for all the cases is not good. Fix this problem by protecting all md_thread with rcu. Signed-off-by: Yu Kuai <yukuai3@huawei.com> Signed-off-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20230523021017.3048783-6-yukuai1@huaweicloud.com
Diffstat (limited to 'drivers/md/md.h')
-rw-r--r--drivers/md/md.h8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 7156fc05f834..a50122165fa1 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -365,8 +365,8 @@ struct mddev {
int new_chunk_sectors;
int reshape_backwards;
- struct md_thread *thread; /* management thread */
- struct md_thread *sync_thread; /* doing resync or reconstruct */
+ struct md_thread __rcu *thread; /* management thread */
+ struct md_thread __rcu *sync_thread; /* doing resync or reconstruct */
/* 'last_sync_action' is initialized to "none". It is set when a
* sync operation (i.e "data-check", "requested-resync", "resync",
@@ -758,8 +758,8 @@ extern struct md_thread *md_register_thread(
void (*run)(struct md_thread *thread),
struct mddev *mddev,
const char *name);
-extern void md_unregister_thread(struct md_thread **threadp);
-extern void md_wakeup_thread(struct md_thread *thread);
+extern void md_unregister_thread(struct md_thread __rcu **threadp);
+extern void md_wakeup_thread(struct md_thread __rcu *thread);
extern void md_check_recovery(struct mddev *mddev);
extern void md_reap_sync_thread(struct mddev *mddev);
extern int mddev_init_writes_pending(struct mddev *mddev);