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

CVE-2026-45926

CVE-2026-45926

Description

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

rust: pwm: Fix potential memory leak on init error

When initializing a PWM chip using pwmchip_alloc(), the allocated device owns an initial reference that must be released on all error paths.

If __pinned_init() were to fail, the allocated pwm_chip would currently leak because the error path returns without calling pwmchip_put().

Affected products

1

Patches

4
a2633dc243c3

rust: pwm: Fix potential memory leak on init error

1 file changed · +5 2
  • rust/kernel/pwm.rs+5 2 modified
    diff --git a/rust/kernel/pwm.rs b/rust/kernel/pwm.rs
    index 2dd72a39acb5d0..4f683158fc0816 100644
    --- a/rust/kernel/pwm.rs
    +++ b/rust/kernel/pwm.rs
    @@ -607,7 +607,11 @@ impl<T: PwmOps> Chip<T> {
             let drvdata_ptr = unsafe { bindings::pwmchip_get_drvdata(c_chip_ptr) };
     
             // SAFETY: We construct the `T` object in-place in the allocated private memory.
    -        unsafe { data.__pinned_init(drvdata_ptr.cast())? };
    +        unsafe { data.__pinned_init(drvdata_ptr.cast()) }.inspect_err(|_| {
    +            // SAFETY: It is safe to call `pwmchip_put()` with a valid pointer obtained
    +            // from `pwmchip_alloc()`. We will not use pointer after this.
    +            unsafe { bindings::pwmchip_put(c_chip_ptr) }
    +        })?;
     
             // SAFETY: `c_chip_ptr` points to a valid chip.
             unsafe {
    -- 
    cgit 1.3-korg
    
    
    
baa8b7097d9c

rust: pwm: Fix potential memory leak on init error

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitKari ArgillanderFixed in 6.19.4via kernel-cna
1 file changed · +5 2
  • rust/kernel/pwm.rs+5 2 modified
    diff --git a/rust/kernel/pwm.rs b/rust/kernel/pwm.rs
    index cb00f8a8765c8e..2ba9cfd02bfdbe 100644
    --- a/rust/kernel/pwm.rs
    +++ b/rust/kernel/pwm.rs
    @@ -601,7 +601,11 @@ impl<T: PwmOps> Chip<T> {
             let drvdata_ptr = unsafe { bindings::pwmchip_get_drvdata(c_chip_ptr) };
     
             // SAFETY: We construct the `T` object in-place in the allocated private memory.
    -        unsafe { data.__pinned_init(drvdata_ptr.cast())? };
    +        unsafe { data.__pinned_init(drvdata_ptr.cast()) }.inspect_err(|_| {
    +            // SAFETY: It is safe to call `pwmchip_put()` with a valid pointer obtained
    +            // from `pwmchip_alloc()`. We will not use pointer after this.
    +            unsafe { bindings::pwmchip_put(c_chip_ptr) }
    +        })?;
     
             // SAFETY: `c_chip_ptr` points to a valid chip.
             unsafe {
    -- 
    cgit 1.3-korg
    
    
    
baa8b7097d9c

rust: pwm: Fix potential memory leak on init error

1 file changed · +5 2
  • rust/kernel/pwm.rs+5 2 modified
    diff --git a/rust/kernel/pwm.rs b/rust/kernel/pwm.rs
    index cb00f8a8765c8e..2ba9cfd02bfdbe 100644
    --- a/rust/kernel/pwm.rs
    +++ b/rust/kernel/pwm.rs
    @@ -601,7 +601,11 @@ impl<T: PwmOps> Chip<T> {
             let drvdata_ptr = unsafe { bindings::pwmchip_get_drvdata(c_chip_ptr) };
     
             // SAFETY: We construct the `T` object in-place in the allocated private memory.
    -        unsafe { data.__pinned_init(drvdata_ptr.cast())? };
    +        unsafe { data.__pinned_init(drvdata_ptr.cast()) }.inspect_err(|_| {
    +            // SAFETY: It is safe to call `pwmchip_put()` with a valid pointer obtained
    +            // from `pwmchip_alloc()`. We will not use pointer after this.
    +            unsafe { bindings::pwmchip_put(c_chip_ptr) }
    +        })?;
     
             // SAFETY: `c_chip_ptr` points to a valid chip.
             unsafe {
    -- 
    cgit 1.3-korg
    
    
    
a2633dc243c3

rust: pwm: Fix potential memory leak on init error

1 file changed · +5 2
  • rust/kernel/pwm.rs+5 2 modified
    diff --git a/rust/kernel/pwm.rs b/rust/kernel/pwm.rs
    index 2dd72a39acb5d0..4f683158fc0816 100644
    --- a/rust/kernel/pwm.rs
    +++ b/rust/kernel/pwm.rs
    @@ -607,7 +607,11 @@ impl<T: PwmOps> Chip<T> {
             let drvdata_ptr = unsafe { bindings::pwmchip_get_drvdata(c_chip_ptr) };
     
             // SAFETY: We construct the `T` object in-place in the allocated private memory.
    -        unsafe { data.__pinned_init(drvdata_ptr.cast())? };
    +        unsafe { data.__pinned_init(drvdata_ptr.cast()) }.inspect_err(|_| {
    +            // SAFETY: It is safe to call `pwmchip_put()` with a valid pointer obtained
    +            // from `pwmchip_alloc()`. We will not use pointer after this.
    +            unsafe { bindings::pwmchip_put(c_chip_ptr) }
    +        })?;
     
             // SAFETY: `c_chip_ptr` points to a valid chip.
             unsafe {
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing reference release on error path: when `__pinned_init()` fails, the initial reference obtained by `pwmchip_alloc()` is not released via `pwmchip_put()`, causing a memory leak."

Attack vector

An attacker would need to trigger a failure of the `__pinned_init()` call during PWM chip initialization in the Rust PWM subsystem. This could occur if the in-place construction of the `T` object (the driver's private data) fails, for example due to memory pressure or an invalid configuration. The bug is in the `Chip::<T>::new()` path in `rust/kernel/pwm.rs` [patch_id=2661267]. No special privileges or network access are required beyond the ability to load or probe a Rust-based PWM driver that uses this initialization path.

Affected code

The vulnerable code is in `rust/kernel/pwm.rs` in the `Chip::<T>` implementation, specifically the `new()` function that calls `pwmchip_alloc()` and then `data.__pinned_init()` [patch_id=2661267]. The error path after `__pinned_init()` failure was missing a `pwmchip_put()` call.

What the fix does

The patch wraps the `__pinned_init()` call with `.inspect_err(|_| { unsafe { bindings::pwmchip_put(c_chip_ptr) } })` [patch_id=2661267]. This ensures that if `__pinned_init()` returns an error, the initial reference obtained from `pwmchip_alloc()` is released before the error is propagated. The fix is minimal and follows the kernel's existing reference-counting discipline for `pwm_chip` objects.

Preconditions

  • configA Rust-based PWM driver must be loaded that uses the `Chip::::new()` initialization path in `rust/kernel/pwm.rs`.
  • inputThe `__pinned_init()` call must fail (e.g., due to memory allocation failure or invalid driver data).

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

References

2

News mentions

0

No linked articles in our index yet.