[PATCH v3 3/3] md/raid5: fix NULL pointer dereference in raid5_free_percpu

From: ghuicao

Date: Thu Aug 27 2026 - 02:38:35 EST


From: Cao Guanghui <caoguanghui@xxxxxxxxxx>

If cpuhp_state_add_instance() fails in raid5_alloc_percpu() (e.g., the
startup callback raid456_cpu_up_prepare fails due to an allocation
failure), conf->node is never added to the cpuhp instance list and
its pprev remains NULL (from kzalloc initialization).

When setup_conf() then jumps to abort, free_conf() calls
raid5_free_percpu(), which checks conf->percpu (non-NULL, since it was
allocated before the cpuhp failure) and proceeds to call
cpuhp_state_remove_instance(). This calls hlist_del() on the unhashed
node, which dereferences node->pprev (NULL), causing a kernel panic.

Guard the removal with hlist_unhashed_lockless() so that the cpuhp
instance is only removed if it was actually added. The lockless variant
uses READ_ONCE() for the pprev read, which is safe here because the
actual removal is synchronized by cpuhp_state_mutex inside
cpuhp_state_remove_instance().

Fixes: 29c6d1bbd7a2 ("md/raid5: Convert to hotplug state machine")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Cao Guanghui <caoguanghui@xxxxxxxxxx>
---

Changes in v2:
- Use hlist_unhashed_lockless() instead of hlist_unhashed() to avoid
a KCSAN data race warning when another array is concurrently added
to the same cpuhp instance list (Sashiko)

drivers/md/raid5.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -7539,7 +7539,8 @@ static void raid5_free_percpu(struct r5conf *conf)
{
if (!conf->percpu)
return;

- cpuhp_state_remove_instance(CPUHP_MD_RAID5_PREPARE, &conf->node);
+ if (!hlist_unhashed_lockless(&conf->node))
+ cpuhp_state_remove_instance(CPUHP_MD_RAID5_PREPARE, &conf->node);
free_percpu(conf->percpu);
}
--
2.34.1