CVE-2026-45888
Description
In the Linux kernel, the following vulnerability has been resolved:
md/raid1: fix memory leak in raid1_run()
raid1_run() calls setup_conf() which registers a thread via md_register_thread(). If raid1_set_limits() fails, the previously registered thread is not unregistered, resulting in a memory leak of the md_thread structure and the thread resource itself.
Add md_unregister_thread() to the error path to properly cleanup the thread, which aligns with the error handling logic of other paths in this function.
Compile tested only. Issue found using a prototype static analysis tool and code review.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A memory leak in Linux kernel md/raid1's raid1_run() function occurs when setup_conf() fails after registering a thread, leaving the md_thread structure and resource unreleased.
Vulnerability
In the Linux kernel, raid1_run() in the md/raid1 driver calls setup_conf(), which registers a kernel thread via md_register_thread(). If the subsequent call to raid1_set_limits() fails, the previously registered thread is not unregistered. This results in a memory leak of the md_thread structure and the associated thread resource. The issue affects the stable kernel tree versions where this code path exists; the fix was applied to the kernel stable branch as commit c94fd6e8a71e [1].
Exploitation
An attacker would need to trigger the failure of raid1_set_limits() after setup_conf() has successfully registered a thread. This requires local access to the system with sufficient privileges to manipulate RAID array configuration (e.g., via mdadm or direct ioctl) such that the limits setup fails, but the registration has already occurred. No user interaction is needed beyond administrative actions that cause the error condition.
Impact
On successful exploitation, the kernel leaks memory associated with the md_thread structure and thread resource. Repeated exploitation can lead to resource exhaustion, potentially causing system instability or denial of service. The vulnerability does not provide privilege escalation or data corruption; it is a denial-of-service issue due to memory leak.
Mitigation
The fix is applied in the Linux kernel stable commit c94fd6e8a71e [1]. Users should update to a kernel version containing this commit. There is no workaround available other than avoiding the error condition that triggers the leak; the proper remediation is to apply the kernel patch. The CVE is not listed on the CISA Known Exploited Vulnerabilities (KEV) catalog as of publication.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
86abc7d5dcf0emd/raid1: fix memory leak in raid1_run()
1 file changed · +1 −1
drivers/md/raid1.c+1 −1 modifieddiff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 79faec11b79ea8..867db18bc3ba1b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3236,6 +3236,7 @@ static int raid1_run(struct mddev *mddev) if (!mddev_is_dm(mddev)) { ret = raid1_set_limits(mddev); if (ret) { + md_unregister_thread(mddev, &conf->thread); if (!mddev->private) raid1_free(mddev, conf); return ret; -- cgit 1.3-korg
c94fd6e8a71emd/raid1: fix memory leak in raid1_run()
1 file changed · +1 −1
drivers/md/raid1.c+1 −1 modifieddiff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index f9c18ade06f15a..093b04e6be6755 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3247,6 +3247,7 @@ static int raid1_run(struct mddev *mddev) if (!mddev_is_dm(mddev)) { ret = raid1_set_limits(mddev); if (ret) { + md_unregister_thread(mddev, &conf->thread); if (!mddev->private) raid1_free(mddev, conf); return ret; -- cgit 1.3-korg
b37588b0282amd/raid1: fix memory leak in raid1_run()
1 file changed · +1 −1
drivers/md/raid1.c+1 −1 modifieddiff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 57d50465eed1b7..cc9914bd15c197 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3254,6 +3254,7 @@ static int raid1_run(struct mddev *mddev) if (!mddev_is_dm(mddev)) { ret = raid1_set_limits(mddev); if (ret) { + md_unregister_thread(mddev, &conf->thread); if (!mddev->private) raid1_free(mddev, conf); return ret; -- cgit 1.3-korg
ec10e3dc9399md/raid1: fix memory leak in raid1_run()
1 file changed · +1 −1
drivers/md/raid1.c+1 −1 modifieddiff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 592a4023300474..ce7fd688695666 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3253,6 +3253,7 @@ static int raid1_run(struct mddev *mddev) if (!mddev_is_dm(mddev)) { ret = raid1_set_limits(mddev); if (ret) { + md_unregister_thread(mddev, &conf->thread); if (!mddev->private) raid1_free(mddev, conf); return ret; -- cgit 1.3-korg
ec10e3dc9399md/raid1: fix memory leak in raid1_run()
1 file changed · +1 −1
drivers/md/raid1.c+1 −1 modifieddiff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 592a4023300474..ce7fd688695666 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3253,6 +3253,7 @@ static int raid1_run(struct mddev *mddev) if (!mddev_is_dm(mddev)) { ret = raid1_set_limits(mddev); if (ret) { + md_unregister_thread(mddev, &conf->thread); if (!mddev->private) raid1_free(mddev, conf); return ret; -- cgit 1.3-korg
b37588b0282amd/raid1: fix memory leak in raid1_run()
1 file changed · +1 −1
drivers/md/raid1.c+1 −1 modifieddiff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 57d50465eed1b7..cc9914bd15c197 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3254,6 +3254,7 @@ static int raid1_run(struct mddev *mddev) if (!mddev_is_dm(mddev)) { ret = raid1_set_limits(mddev); if (ret) { + md_unregister_thread(mddev, &conf->thread); if (!mddev->private) raid1_free(mddev, conf); return ret; -- cgit 1.3-korg
6abc7d5dcf0emd/raid1: fix memory leak in raid1_run()
1 file changed · +1 −1
drivers/md/raid1.c+1 −1 modifieddiff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 79faec11b79ea8..867db18bc3ba1b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3236,6 +3236,7 @@ static int raid1_run(struct mddev *mddev) if (!mddev_is_dm(mddev)) { ret = raid1_set_limits(mddev); if (ret) { + md_unregister_thread(mddev, &conf->thread); if (!mddev->private) raid1_free(mddev, conf); return ret; -- cgit 1.3-korg
c94fd6e8a71emd/raid1: fix memory leak in raid1_run()
1 file changed · +1 −1
drivers/md/raid1.c+1 −1 modifieddiff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index f9c18ade06f15a..093b04e6be6755 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3247,6 +3247,7 @@ static int raid1_run(struct mddev *mddev) if (!mddev_is_dm(mddev)) { ret = raid1_set_limits(mddev); if (ret) { + md_unregister_thread(mddev, &conf->thread); if (!mddev->private) raid1_free(mddev, conf); return ret; -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing cleanup of a registered kernel thread in the error path of raid1_run() when raid1_set_limits() fails."
Attack vector
An attacker who can trigger a failure of `raid1_set_limits()` during RAID1 array setup (e.g., by providing device limits that cause the function to return an error) will cause the error path in `raid1_run()` to return without calling `md_unregister_thread()`. This leaks the `md_thread` structure and the associated kernel thread resource. The precondition is that the attacker can influence the RAID1 configuration such that `raid1_set_limits()` fails after `setup_conf()` has already registered the thread.
Affected code
The vulnerability is in the `raid1_run()` function in `drivers/md/raid1.c`. The error path after a failed `raid1_set_limits()` call was missing a call to `md_unregister_thread()` to clean up the thread registered earlier by `setup_conf()` via `md_register_thread()` [patch_id=2661655][patch_id=2661656][patch_id=2661657][patch_id=2661654][patch_id=2661651][patch_id=2661650][patch_id=2661652][patch_id=2661653].
What the fix does
The patch adds a single line — `md_unregister_thread(mddev, &conf->thread);` — to the error path in `raid1_run()` before the existing cleanup code that frees the `conf` structure [patch_id=2661655][patch_id=2661656][patch_id=2661657][patch_id=2661654][patch_id=2661651][patch_id=2661650][patch_id=2661652][patch_id=2661653]. This ensures that when `raid1_set_limits()` fails, the thread previously registered by `setup_conf()` via `md_register_thread()` is properly unregistered and its resources freed, preventing the memory leak. This aligns the error handling with other cleanup paths in the same function.
Preconditions
- inputThe attacker must be able to cause raid1_set_limits() to fail after setup_conf() has successfully registered a thread.
- configThe attacker must have the ability to configure or influence a RAID1 array setup (e.g., via mdadm or device-mapper).
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.