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

CVE-2026-45882

CVE-2026-45882

Description

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

power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()

Using the devm_ variant for requesting IRQ _before_ the devm_ variant for allocating/registering the power_supply handle, means that the power_supply handle will be deallocated/unregistered _before_ the interrupt handler (since devm_ naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the power_supply handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run.

This will lead to the IRQ handler calling power_supply_changed() with a freed power_supply handle. Which usually crashes the system or otherwise silently corrupts the memory...

Note that there is a similar situation which can also happen during probe(); the possibility of an interrupt firing _before_ registering the power_supply handle. This would then lead to the nasty situation of using the power_supply handle *uninitialized* in power_supply_changed().

Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the power_supply handle.

Affected products

1

Patches

8
62914959b35e

power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitWaqar HameedDec 20, 2025Fixed in 7.0via kernel-cna
1 file changed · +9 10
  • drivers/power/supply/pm8916_bms_vm.c+9 10 modified
    diff --git a/drivers/power/supply/pm8916_bms_vm.c b/drivers/power/supply/pm8916_bms_vm.c
    index 5120be086e6ffc..de5d571c03e212 100644
    --- a/drivers/power/supply/pm8916_bms_vm.c
    +++ b/drivers/power/supply/pm8916_bms_vm.c
    @@ -167,15 +167,6 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret < 0)
     		return -EINVAL;
     
    -	irq = platform_get_irq_byname(pdev, "fifo");
    -	if (irq < 0)
    -		return irq;
    -
    -	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    -					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    -	if (ret)
    -		return ret;
    -
     	ret = regmap_bulk_read(bat->regmap, bat->reg + PM8916_PERPH_TYPE, &tmp, 2);
     	if (ret)
     		goto comm_error;
    @@ -220,6 +211,15 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret)
     		return dev_err_probe(dev, ret, "Unable to get battery info\n");
     
    +	irq = platform_get_irq_byname(pdev, "fifo");
    +	if (irq < 0)
    +		return irq;
    +
    +	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    +					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    +	if (ret)
    +		return ret;
    +
     	platform_set_drvdata(pdev, bat);
     
     	return 0;
    -- 
    cgit 1.3-korg
    
    
    
17db6b3abd82

power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitWaqar HameedDec 20, 2025Fixed in 6.19.4via kernel-cna
1 file changed · +9 10
  • drivers/power/supply/pm8916_bms_vm.c+9 10 modified
    diff --git a/drivers/power/supply/pm8916_bms_vm.c b/drivers/power/supply/pm8916_bms_vm.c
    index 5120be086e6ffc..de5d571c03e212 100644
    --- a/drivers/power/supply/pm8916_bms_vm.c
    +++ b/drivers/power/supply/pm8916_bms_vm.c
    @@ -167,15 +167,6 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret < 0)
     		return -EINVAL;
     
    -	irq = platform_get_irq_byname(pdev, "fifo");
    -	if (irq < 0)
    -		return irq;
    -
    -	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    -					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    -	if (ret)
    -		return ret;
    -
     	ret = regmap_bulk_read(bat->regmap, bat->reg + PM8916_PERPH_TYPE, &tmp, 2);
     	if (ret)
     		goto comm_error;
    @@ -220,6 +211,15 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret)
     		return dev_err_probe(dev, ret, "Unable to get battery info\n");
     
    +	irq = platform_get_irq_byname(pdev, "fifo");
    +	if (irq < 0)
    +		return irq;
    +
    +	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    +					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    +	if (ret)
    +		return ret;
    +
     	platform_set_drvdata(pdev, bat);
     
     	return 0;
    -- 
    cgit 1.3-korg
    
    
    
a8b7117ae3a7

power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitWaqar HameedDec 20, 2025Fixed in 6.18.14via kernel-cna
1 file changed · +9 10
  • drivers/power/supply/pm8916_bms_vm.c+9 10 modified
    diff --git a/drivers/power/supply/pm8916_bms_vm.c b/drivers/power/supply/pm8916_bms_vm.c
    index 5120be086e6ffc..de5d571c03e212 100644
    --- a/drivers/power/supply/pm8916_bms_vm.c
    +++ b/drivers/power/supply/pm8916_bms_vm.c
    @@ -167,15 +167,6 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret < 0)
     		return -EINVAL;
     
    -	irq = platform_get_irq_byname(pdev, "fifo");
    -	if (irq < 0)
    -		return irq;
    -
    -	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    -					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    -	if (ret)
    -		return ret;
    -
     	ret = regmap_bulk_read(bat->regmap, bat->reg + PM8916_PERPH_TYPE, &tmp, 2);
     	if (ret)
     		goto comm_error;
    @@ -220,6 +211,15 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret)
     		return dev_err_probe(dev, ret, "Unable to get battery info\n");
     
    +	irq = platform_get_irq_byname(pdev, "fifo");
    +	if (irq < 0)
    +		return irq;
    +
    +	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    +					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    +	if (ret)
    +		return ret;
    +
     	platform_set_drvdata(pdev, bat);
     
     	return 0;
    -- 
    cgit 1.3-korg
    
    
    
b69bb88e20c6

power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitWaqar HameedDec 20, 2025Fixed in 6.12.75via kernel-cna
1 file changed · +9 10
  • drivers/power/supply/pm8916_bms_vm.c+9 10 modified
    diff --git a/drivers/power/supply/pm8916_bms_vm.c b/drivers/power/supply/pm8916_bms_vm.c
    index 5d0dd842509c4b..9b069af077be53 100644
    --- a/drivers/power/supply/pm8916_bms_vm.c
    +++ b/drivers/power/supply/pm8916_bms_vm.c
    @@ -167,15 +167,6 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret < 0)
     		return -EINVAL;
     
    -	irq = platform_get_irq_byname(pdev, "fifo");
    -	if (irq < 0)
    -		return irq;
    -
    -	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    -					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    -	if (ret)
    -		return ret;
    -
     	ret = regmap_bulk_read(bat->regmap, bat->reg + PM8916_PERPH_TYPE, &tmp, 2);
     	if (ret)
     		goto comm_error;
    @@ -220,6 +211,15 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret)
     		return dev_err_probe(dev, ret, "Unable to get battery info\n");
     
    +	irq = platform_get_irq_byname(pdev, "fifo");
    +	if (irq < 0)
    +		return irq;
    +
    +	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    +					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    +	if (ret)
    +		return ret;
    +
     	platform_set_drvdata(pdev, bat);
     
     	return 0;
    -- 
    cgit 1.3-korg
    
    
    
b69bb88e20c6

power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()

1 file changed · +9 10
  • drivers/power/supply/pm8916_bms_vm.c+9 10 modified
    diff --git a/drivers/power/supply/pm8916_bms_vm.c b/drivers/power/supply/pm8916_bms_vm.c
    index 5d0dd842509c4b..9b069af077be53 100644
    --- a/drivers/power/supply/pm8916_bms_vm.c
    +++ b/drivers/power/supply/pm8916_bms_vm.c
    @@ -167,15 +167,6 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret < 0)
     		return -EINVAL;
     
    -	irq = platform_get_irq_byname(pdev, "fifo");
    -	if (irq < 0)
    -		return irq;
    -
    -	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    -					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    -	if (ret)
    -		return ret;
    -
     	ret = regmap_bulk_read(bat->regmap, bat->reg + PM8916_PERPH_TYPE, &tmp, 2);
     	if (ret)
     		goto comm_error;
    @@ -220,6 +211,15 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret)
     		return dev_err_probe(dev, ret, "Unable to get battery info\n");
     
    +	irq = platform_get_irq_byname(pdev, "fifo");
    +	if (irq < 0)
    +		return irq;
    +
    +	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    +					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    +	if (ret)
    +		return ret;
    +
     	platform_set_drvdata(pdev, bat);
     
     	return 0;
    -- 
    cgit 1.3-korg
    
    
    
a8b7117ae3a7

power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()

1 file changed · +9 10
  • drivers/power/supply/pm8916_bms_vm.c+9 10 modified
    diff --git a/drivers/power/supply/pm8916_bms_vm.c b/drivers/power/supply/pm8916_bms_vm.c
    index 5120be086e6ffc..de5d571c03e212 100644
    --- a/drivers/power/supply/pm8916_bms_vm.c
    +++ b/drivers/power/supply/pm8916_bms_vm.c
    @@ -167,15 +167,6 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret < 0)
     		return -EINVAL;
     
    -	irq = platform_get_irq_byname(pdev, "fifo");
    -	if (irq < 0)
    -		return irq;
    -
    -	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    -					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    -	if (ret)
    -		return ret;
    -
     	ret = regmap_bulk_read(bat->regmap, bat->reg + PM8916_PERPH_TYPE, &tmp, 2);
     	if (ret)
     		goto comm_error;
    @@ -220,6 +211,15 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret)
     		return dev_err_probe(dev, ret, "Unable to get battery info\n");
     
    +	irq = platform_get_irq_byname(pdev, "fifo");
    +	if (irq < 0)
    +		return irq;
    +
    +	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    +					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    +	if (ret)
    +		return ret;
    +
     	platform_set_drvdata(pdev, bat);
     
     	return 0;
    -- 
    cgit 1.3-korg
    
    
    
62914959b35e

power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()

1 file changed · +9 10
  • drivers/power/supply/pm8916_bms_vm.c+9 10 modified
    diff --git a/drivers/power/supply/pm8916_bms_vm.c b/drivers/power/supply/pm8916_bms_vm.c
    index 5120be086e6ffc..de5d571c03e212 100644
    --- a/drivers/power/supply/pm8916_bms_vm.c
    +++ b/drivers/power/supply/pm8916_bms_vm.c
    @@ -167,15 +167,6 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret < 0)
     		return -EINVAL;
     
    -	irq = platform_get_irq_byname(pdev, "fifo");
    -	if (irq < 0)
    -		return irq;
    -
    -	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    -					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    -	if (ret)
    -		return ret;
    -
     	ret = regmap_bulk_read(bat->regmap, bat->reg + PM8916_PERPH_TYPE, &tmp, 2);
     	if (ret)
     		goto comm_error;
    @@ -220,6 +211,15 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret)
     		return dev_err_probe(dev, ret, "Unable to get battery info\n");
     
    +	irq = platform_get_irq_byname(pdev, "fifo");
    +	if (irq < 0)
    +		return irq;
    +
    +	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    +					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    +	if (ret)
    +		return ret;
    +
     	platform_set_drvdata(pdev, bat);
     
     	return 0;
    -- 
    cgit 1.3-korg
    
    
    
17db6b3abd82

power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()

1 file changed · +9 10
  • drivers/power/supply/pm8916_bms_vm.c+9 10 modified
    diff --git a/drivers/power/supply/pm8916_bms_vm.c b/drivers/power/supply/pm8916_bms_vm.c
    index 5120be086e6ffc..de5d571c03e212 100644
    --- a/drivers/power/supply/pm8916_bms_vm.c
    +++ b/drivers/power/supply/pm8916_bms_vm.c
    @@ -167,15 +167,6 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret < 0)
     		return -EINVAL;
     
    -	irq = platform_get_irq_byname(pdev, "fifo");
    -	if (irq < 0)
    -		return irq;
    -
    -	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    -					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    -	if (ret)
    -		return ret;
    -
     	ret = regmap_bulk_read(bat->regmap, bat->reg + PM8916_PERPH_TYPE, &tmp, 2);
     	if (ret)
     		goto comm_error;
    @@ -220,6 +211,15 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
     	if (ret)
     		return dev_err_probe(dev, ret, "Unable to get battery info\n");
     
    +	irq = platform_get_irq_byname(pdev, "fifo");
    +	if (irq < 0)
    +		return irq;
    +
    +	ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
    +					IRQF_ONESHOT, "pm8916_vm_bms", bat);
    +	if (ret)
    +		return ret;
    +
     	platform_set_drvdata(pdev, bat);
     
     	return 0;
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Incorrect ordering of devm-managed resource allocation: IRQ requested before power_supply registration, causing a use-after-free race during device removal and a use-of-uninitialized race during probe."

Attack vector

An attacker who can trigger device removal (e.g., unbinding the driver or hot-unplug) or cause an interrupt to fire during probe can exploit this race. During removal, the `power_supply` handle is freed first (reverse devm order), but the IRQ handler `pm8916_bms_vm_fifo_update_done_irq` may still fire and call `power_supply_changed()` on the freed handle. During probe, an interrupt arriving before `power_supply_register()` would cause `power_supply_changed()` to use an uninitialized handle. Both scenarios lead to a use-after-free or use of uninitialized memory, typically crashing the system [patch_id=2661723].

Affected code

The vulnerability is in `drivers/power/supply/pm8916_bms_vm.c` in the function `pm8916_bms_vm_battery_probe()`. The original code called `devm_request_threaded_irq()` (for the "fifo" IRQ) *before* the `power_supply` handle was allocated and registered via `devm_power_supply_register()`. Because devm-managed resources are freed in reverse allocation order, the `power_supply` handle is torn down before the IRQ handler is unregistered, creating a use-after-free race window [patch_id=2661723].

What the fix does

The patch moves the `platform_get_irq_byname()` and `devm_request_threaded_irq()` calls to *after* the `power_supply` handle has been allocated and registered via `devm_power_supply_register()`. This ensures that during removal, the IRQ handler is unregistered *before* the `power_supply` handle is freed, closing the use-after-free race. It also prevents the probe-time race where an interrupt could fire before the handle exists [patch_id=2661723].

Preconditions

  • configThe pm8916_bms_vm driver must be loaded and bound to a device
  • inputThe attacker must be able to trigger device removal (e.g., unbind via sysfs) or cause a 'fifo' interrupt to fire during the probe window

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

References

4

News mentions

0

No linked articles in our index yet.