VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45955

CVE-2026-45955

Description

In the Linux kernel, the following vulnerability has been resolved:

md/md-llbitmap: fix percpu_ref not resurrected on suspend timeout

When llbitmap_suspend_timeout() times out waiting for percpu_ref to become zero, it returns -ETIMEDOUT without resurrecting the percpu_ref. The caller (md_llbitmap_daemon_fn) then continues to the next page without calling llbitmap_resume(), leaving the percpu_ref in a killed state permanently.

Fix this by resurrecting the percpu_ref before returning the error, ensuring the page control structure remains usable for subsequent operations.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A timeout in llbitmap_suspend_timeout() leaves percpu_ref killed permanently, causing a use-after-free or resource leak in Linux kernel md/llbitmap.

Vulnerability

In the Linux kernel's md/md-llbitmap subsystem, the function llbitmap_suspend_timeout() may return -ETIMEDOUT without calling percpu_ref_resurrect() when the wait for percpu_ref to become zero times out. This leaves the percpu_ref in a permanently killed state. The bug affects kernel versions prior to the commit 2446d099350185caeed19ab2c0270451a97296fb [1].

Exploitation

An attacker must be able to trigger a timeout in llbitmap_suspend_timeout(), for example by causing the percpu_ref count to remain nonzero through prolonged I/O operations or race conditions. When the timeout occurs, the function returns -ETIMEDOUT, and the caller md_llbitmap_daemon_fn proceeds to the next page without calling llbitmap_resume(). The percpu_ref is never resurrected, leaving the page control structure in an inconsistent state.

Impact

Once the percpu_ref is killed permanently, subsequent operations on the associated page control structure can result in use-after-free, resource leaks, or system instability. Depending on the context, an attacker may leverage this to escalate privileges or cause a denial of service.

Mitigation

The fix is included in Linux kernel stable commit 2446d099350185caeed19ab2c0270451a97296fb [1]. Users should apply this patch or update to a kernel version containing it. No workaround is available if the patch is not applied.

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

1

Patches

6
095417d6b669

md/md-llbitmap: fix percpu_ref not resurrected on suspend timeout

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYu KuaiJan 23, 2026Fixed in 6.18.14via kernel-cna
2 files changed · +6 4
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 1eb434306162a5..bcb6eae1c711f6 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 1eb434306162a5..bcb6eae1c711f6 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
2446d0993501

md/md-llbitmap: fix percpu_ref not resurrected on suspend timeout

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYu KuaiJan 23, 2026Fixed in 6.19.4via kernel-cna
2 files changed · +6 4
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 9c1ade19b7741e..cd713a7dc27064 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 9c1ade19b7741e..cd713a7dc27064 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
d119bd2e1643

md/md-llbitmap: fix percpu_ref not resurrected on suspend timeout

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYu KuaiJan 23, 2026Fixed in 7.0via kernel-cna
2 files changed · +6 4
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 9c1ade19b7741e..cd713a7dc27064 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 9c1ade19b7741e..cd713a7dc27064 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
095417d6b669

md/md-llbitmap: fix percpu_ref not resurrected on suspend timeout

2 files changed · +6 4
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 1eb434306162a5..bcb6eae1c711f6 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 1eb434306162a5..bcb6eae1c711f6 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
2446d0993501

md/md-llbitmap: fix percpu_ref not resurrected on suspend timeout

2 files changed · +6 4
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 9c1ade19b7741e..cd713a7dc27064 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 9c1ade19b7741e..cd713a7dc27064 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
d119bd2e1643

md/md-llbitmap: fix percpu_ref not resurrected on suspend timeout

2 files changed · +6 4
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 9c1ade19b7741e..cd713a7dc27064 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/md/md-llbitmap.c+3 2 modified
    diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
    index 9c1ade19b7741e..cd713a7dc27064 100644
    --- a/drivers/md/md-llbitmap.c
    +++ b/drivers/md/md-llbitmap.c
    @@ -712,8 +712,10 @@ static int llbitmap_suspend_timeout(struct llbitmap *llbitmap, int page_idx)
     	percpu_ref_kill(&pctl->active);
     
     	if (!wait_event_timeout(pctl->wait, percpu_ref_is_zero(&pctl->active),
    -			llbitmap->mddev->bitmap_info.daemon_sleep * HZ))
    +			llbitmap->mddev->bitmap_info.daemon_sleep * HZ)) {
    +		percpu_ref_resurrect(&pctl->active);
     		return -ETIMEDOUT;
    +	}
     
     	return 0;
     }
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing percpu_ref_resurrect() call on timeout in llbitmap_suspend_timeout() leaves the percpu_ref permanently killed."

Attack vector

An attacker or system condition that causes the percpu_ref to not reach zero within the `daemon_sleep` timeout window triggers this bug. The function `llbitmap_suspend_timeout()` kills the percpu_ref and waits; if the timeout fires, the ref is left killed. The caller `md_llbitmap_daemon_fn` then continues to the next page without calling `llbitmap_resume()`, so the page control structure (`pctl`) becomes permanently unusable for subsequent operations. No special network path or authentication is required — the bug manifests during normal md bitmap daemon operation when I/O holds the ref count elevated longer than expected.

Affected code

The bug is in `drivers/md/md-llbitmap.c` in the function `llbitmap_suspend_timeout()` [patch_id=2661023]. The function calls `percpu_ref_kill(&pctl->active)` and then waits for the reference count to reach zero. If the wait times out, the function returned -ETIMEDOUT without calling `percpu_ref_resurrect()`, leaving the percpu_ref in a permanently killed state.

What the fix does

The patch adds a call to `percpu_ref_resurrect(&pctl->active)` inside the timeout branch, before returning -ETIMEDOUT [patch_id=2661023]. This ensures that when the wait for the percpu_ref to reach zero times out, the reference count is resurrected (reversing the earlier `percpu_ref_kill`), so the page control structure remains in a usable state. The caller can then continue processing subsequent pages without the ref being permanently killed.

Preconditions

  • configThe md/llbitmap daemon must be running and processing bitmap pages
  • inputThe percpu_ref for a page control structure must not reach zero within the daemon_sleep timeout window

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

3

News mentions

0

No linked articles in our index yet.