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

CVE-2026-45906

CVE-2026-45906

Description

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

power: supply: pf1550: 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

4
1bdefeed904f

power: supply: pf1550: 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
2 files changed · +32 34
  • drivers/power/supply/pf1550-charger.c+16 17 modified
    diff --git a/drivers/power/supply/pf1550-charger.c b/drivers/power/supply/pf1550-charger.c
    index 98f1ee8eca3bc8..a457862ef46108 100644
    --- a/drivers/power/supply/pf1550-charger.c
    +++ b/drivers/power/supply/pf1550-charger.c
    @@ -584,22 +584,6 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(chg->dev, ret,
     				     "failed to add battery sense work\n");
     
    -	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    -		irq = platform_get_irq(pdev, i);
    -		if (irq < 0)
    -			return irq;
    -
    -		chg->virqs[i] = irq;
    -
    -		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    -						pf1550_charger_irq_handler,
    -						IRQF_NO_SUSPEND,
    -						"pf1550-charger", chg);
    -		if (ret)
    -			return dev_err_probe(&pdev->dev, ret,
    -					     "failed irq request\n");
    -	}
    -
     	psy_cfg.drv_data = chg;
     
     	chg->charger = devm_power_supply_register(&pdev->dev,
    @@ -616,6 +600,22 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
     				     "failed: power supply register\n");
     
    +	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    +		irq = platform_get_irq(pdev, i);
    +		if (irq < 0)
    +			return irq;
    +
    +		chg->virqs[i] = irq;
    +
    +		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    +						pf1550_charger_irq_handler,
    +						IRQF_NO_SUSPEND,
    +						"pf1550-charger", chg);
    +		if (ret)
    +			return dev_err_probe(&pdev->dev, ret,
    +					     "failed irq request\n");
    +	}
    +
     	pf1550_dt_parse_dev_info(chg);
     
     	return pf1550_reg_init(chg);
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/power/supply/pf1550-charger.c+16 17 modified
    diff --git a/drivers/power/supply/pf1550-charger.c b/drivers/power/supply/pf1550-charger.c
    index 98f1ee8eca3bc8..a457862ef46108 100644
    --- a/drivers/power/supply/pf1550-charger.c
    +++ b/drivers/power/supply/pf1550-charger.c
    @@ -584,22 +584,6 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(chg->dev, ret,
     				     "failed to add battery sense work\n");
     
    -	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    -		irq = platform_get_irq(pdev, i);
    -		if (irq < 0)
    -			return irq;
    -
    -		chg->virqs[i] = irq;
    -
    -		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    -						pf1550_charger_irq_handler,
    -						IRQF_NO_SUSPEND,
    -						"pf1550-charger", chg);
    -		if (ret)
    -			return dev_err_probe(&pdev->dev, ret,
    -					     "failed irq request\n");
    -	}
    -
     	psy_cfg.drv_data = chg;
     
     	chg->charger = devm_power_supply_register(&pdev->dev,
    @@ -616,6 +600,22 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
     				     "failed: power supply register\n");
     
    +	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    +		irq = platform_get_irq(pdev, i);
    +		if (irq < 0)
    +			return irq;
    +
    +		chg->virqs[i] = irq;
    +
    +		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    +						pf1550_charger_irq_handler,
    +						IRQF_NO_SUSPEND,
    +						"pf1550-charger", chg);
    +		if (ret)
    +			return dev_err_probe(&pdev->dev, ret,
    +					     "failed irq request\n");
    +	}
    +
     	pf1550_dt_parse_dev_info(chg);
     
     	return pf1550_reg_init(chg);
    -- 
    cgit 1.3-korg
    
    
    
838767f50747

power: supply: pf1550: 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
2 files changed · +32 34
  • drivers/power/supply/pf1550-charger.c+16 17 modified
    diff --git a/drivers/power/supply/pf1550-charger.c b/drivers/power/supply/pf1550-charger.c
    index 98f1ee8eca3bc8..a457862ef46108 100644
    --- a/drivers/power/supply/pf1550-charger.c
    +++ b/drivers/power/supply/pf1550-charger.c
    @@ -584,22 +584,6 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(chg->dev, ret,
     				     "failed to add battery sense work\n");
     
    -	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    -		irq = platform_get_irq(pdev, i);
    -		if (irq < 0)
    -			return irq;
    -
    -		chg->virqs[i] = irq;
    -
    -		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    -						pf1550_charger_irq_handler,
    -						IRQF_NO_SUSPEND,
    -						"pf1550-charger", chg);
    -		if (ret)
    -			return dev_err_probe(&pdev->dev, ret,
    -					     "failed irq request\n");
    -	}
    -
     	psy_cfg.drv_data = chg;
     
     	chg->charger = devm_power_supply_register(&pdev->dev,
    @@ -616,6 +600,22 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
     				     "failed: power supply register\n");
     
    +	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    +		irq = platform_get_irq(pdev, i);
    +		if (irq < 0)
    +			return irq;
    +
    +		chg->virqs[i] = irq;
    +
    +		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    +						pf1550_charger_irq_handler,
    +						IRQF_NO_SUSPEND,
    +						"pf1550-charger", chg);
    +		if (ret)
    +			return dev_err_probe(&pdev->dev, ret,
    +					     "failed irq request\n");
    +	}
    +
     	pf1550_dt_parse_dev_info(chg);
     
     	return pf1550_reg_init(chg);
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/power/supply/pf1550-charger.c+16 17 modified
    diff --git a/drivers/power/supply/pf1550-charger.c b/drivers/power/supply/pf1550-charger.c
    index 98f1ee8eca3bc8..a457862ef46108 100644
    --- a/drivers/power/supply/pf1550-charger.c
    +++ b/drivers/power/supply/pf1550-charger.c
    @@ -584,22 +584,6 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(chg->dev, ret,
     				     "failed to add battery sense work\n");
     
    -	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    -		irq = platform_get_irq(pdev, i);
    -		if (irq < 0)
    -			return irq;
    -
    -		chg->virqs[i] = irq;
    -
    -		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    -						pf1550_charger_irq_handler,
    -						IRQF_NO_SUSPEND,
    -						"pf1550-charger", chg);
    -		if (ret)
    -			return dev_err_probe(&pdev->dev, ret,
    -					     "failed irq request\n");
    -	}
    -
     	psy_cfg.drv_data = chg;
     
     	chg->charger = devm_power_supply_register(&pdev->dev,
    @@ -616,6 +600,22 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
     				     "failed: power supply register\n");
     
    +	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    +		irq = platform_get_irq(pdev, i);
    +		if (irq < 0)
    +			return irq;
    +
    +		chg->virqs[i] = irq;
    +
    +		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    +						pf1550_charger_irq_handler,
    +						IRQF_NO_SUSPEND,
    +						"pf1550-charger", chg);
    +		if (ret)
    +			return dev_err_probe(&pdev->dev, ret,
    +					     "failed irq request\n");
    +	}
    +
     	pf1550_dt_parse_dev_info(chg);
     
     	return pf1550_reg_init(chg);
    -- 
    cgit 1.3-korg
    
    
    
1bdefeed904f

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

2 files changed · +32 34
  • drivers/power/supply/pf1550-charger.c+16 17 modified
    diff --git a/drivers/power/supply/pf1550-charger.c b/drivers/power/supply/pf1550-charger.c
    index 98f1ee8eca3bc8..a457862ef46108 100644
    --- a/drivers/power/supply/pf1550-charger.c
    +++ b/drivers/power/supply/pf1550-charger.c
    @@ -584,22 +584,6 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(chg->dev, ret,
     				     "failed to add battery sense work\n");
     
    -	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    -		irq = platform_get_irq(pdev, i);
    -		if (irq < 0)
    -			return irq;
    -
    -		chg->virqs[i] = irq;
    -
    -		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    -						pf1550_charger_irq_handler,
    -						IRQF_NO_SUSPEND,
    -						"pf1550-charger", chg);
    -		if (ret)
    -			return dev_err_probe(&pdev->dev, ret,
    -					     "failed irq request\n");
    -	}
    -
     	psy_cfg.drv_data = chg;
     
     	chg->charger = devm_power_supply_register(&pdev->dev,
    @@ -616,6 +600,22 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
     				     "failed: power supply register\n");
     
    +	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    +		irq = platform_get_irq(pdev, i);
    +		if (irq < 0)
    +			return irq;
    +
    +		chg->virqs[i] = irq;
    +
    +		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    +						pf1550_charger_irq_handler,
    +						IRQF_NO_SUSPEND,
    +						"pf1550-charger", chg);
    +		if (ret)
    +			return dev_err_probe(&pdev->dev, ret,
    +					     "failed irq request\n");
    +	}
    +
     	pf1550_dt_parse_dev_info(chg);
     
     	return pf1550_reg_init(chg);
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/power/supply/pf1550-charger.c+16 17 modified
    diff --git a/drivers/power/supply/pf1550-charger.c b/drivers/power/supply/pf1550-charger.c
    index 98f1ee8eca3bc8..a457862ef46108 100644
    --- a/drivers/power/supply/pf1550-charger.c
    +++ b/drivers/power/supply/pf1550-charger.c
    @@ -584,22 +584,6 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(chg->dev, ret,
     				     "failed to add battery sense work\n");
     
    -	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    -		irq = platform_get_irq(pdev, i);
    -		if (irq < 0)
    -			return irq;
    -
    -		chg->virqs[i] = irq;
    -
    -		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    -						pf1550_charger_irq_handler,
    -						IRQF_NO_SUSPEND,
    -						"pf1550-charger", chg);
    -		if (ret)
    -			return dev_err_probe(&pdev->dev, ret,
    -					     "failed irq request\n");
    -	}
    -
     	psy_cfg.drv_data = chg;
     
     	chg->charger = devm_power_supply_register(&pdev->dev,
    @@ -616,6 +600,22 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
     				     "failed: power supply register\n");
     
    +	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    +		irq = platform_get_irq(pdev, i);
    +		if (irq < 0)
    +			return irq;
    +
    +		chg->virqs[i] = irq;
    +
    +		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    +						pf1550_charger_irq_handler,
    +						IRQF_NO_SUSPEND,
    +						"pf1550-charger", chg);
    +		if (ret)
    +			return dev_err_probe(&pdev->dev, ret,
    +					     "failed irq request\n");
    +	}
    +
     	pf1550_dt_parse_dev_info(chg);
     
     	return pf1550_reg_init(chg);
    -- 
    cgit 1.3-korg
    
    
    
838767f50747

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

2 files changed · +32 34
  • drivers/power/supply/pf1550-charger.c+16 17 modified
    diff --git a/drivers/power/supply/pf1550-charger.c b/drivers/power/supply/pf1550-charger.c
    index 98f1ee8eca3bc8..a457862ef46108 100644
    --- a/drivers/power/supply/pf1550-charger.c
    +++ b/drivers/power/supply/pf1550-charger.c
    @@ -584,22 +584,6 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(chg->dev, ret,
     				     "failed to add battery sense work\n");
     
    -	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    -		irq = platform_get_irq(pdev, i);
    -		if (irq < 0)
    -			return irq;
    -
    -		chg->virqs[i] = irq;
    -
    -		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    -						pf1550_charger_irq_handler,
    -						IRQF_NO_SUSPEND,
    -						"pf1550-charger", chg);
    -		if (ret)
    -			return dev_err_probe(&pdev->dev, ret,
    -					     "failed irq request\n");
    -	}
    -
     	psy_cfg.drv_data = chg;
     
     	chg->charger = devm_power_supply_register(&pdev->dev,
    @@ -616,6 +600,22 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
     				     "failed: power supply register\n");
     
    +	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    +		irq = platform_get_irq(pdev, i);
    +		if (irq < 0)
    +			return irq;
    +
    +		chg->virqs[i] = irq;
    +
    +		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    +						pf1550_charger_irq_handler,
    +						IRQF_NO_SUSPEND,
    +						"pf1550-charger", chg);
    +		if (ret)
    +			return dev_err_probe(&pdev->dev, ret,
    +					     "failed irq request\n");
    +	}
    +
     	pf1550_dt_parse_dev_info(chg);
     
     	return pf1550_reg_init(chg);
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/power/supply/pf1550-charger.c+16 17 modified
    diff --git a/drivers/power/supply/pf1550-charger.c b/drivers/power/supply/pf1550-charger.c
    index 98f1ee8eca3bc8..a457862ef46108 100644
    --- a/drivers/power/supply/pf1550-charger.c
    +++ b/drivers/power/supply/pf1550-charger.c
    @@ -584,22 +584,6 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(chg->dev, ret,
     				     "failed to add battery sense work\n");
     
    -	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    -		irq = platform_get_irq(pdev, i);
    -		if (irq < 0)
    -			return irq;
    -
    -		chg->virqs[i] = irq;
    -
    -		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    -						pf1550_charger_irq_handler,
    -						IRQF_NO_SUSPEND,
    -						"pf1550-charger", chg);
    -		if (ret)
    -			return dev_err_probe(&pdev->dev, ret,
    -					     "failed irq request\n");
    -	}
    -
     	psy_cfg.drv_data = chg;
     
     	chg->charger = devm_power_supply_register(&pdev->dev,
    @@ -616,6 +600,22 @@ static int pf1550_charger_probe(struct platform_device *pdev)
     		return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
     				     "failed: power supply register\n");
     
    +	for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
    +		irq = platform_get_irq(pdev, i);
    +		if (irq < 0)
    +			return irq;
    +
    +		chg->virqs[i] = irq;
    +
    +		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
    +						pf1550_charger_irq_handler,
    +						IRQF_NO_SUSPEND,
    +						"pf1550-charger", chg);
    +		if (ret)
    +			return dev_err_probe(&pdev->dev, ret,
    +					     "failed irq request\n");
    +	}
    +
     	pf1550_dt_parse_dev_info(chg);
     
     	return pf1550_reg_init(chg);
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Incorrect ordering of devm-managed resource allocations: IRQ handler registered before power_supply handle, causing use-after-free during driver teardown and uninitialized access during probe."

Attack vector

An attacker who can cause a hardware interrupt on the PF1550 charger IC (e.g., by triggering a charger status change) during driver removal or probe can exploit a use-after-free race. During removal, `devm` tears down resources in reverse allocation order: the `power_supply` handle is freed first, then the IRQ handler is unregistered. An interrupt arriving in that window calls `power_supply_changed()` with a freed handle, causing a crash or memory corruption. During probe, an interrupt arriving before `devm_power_supply_register()` runs would pass an uninitialized handle to `power_supply_changed()`.

Affected code

The vulnerability is in the `pf1550_charger_probe()` function in `drivers/power/supply/pf1550-charger.c` [patch_id=2661485]. The original code placed the `devm_request_threaded_irq()` loop (lines 587–601) *before* the `devm_power_supply_register()` calls (lines 610–623), creating a dangerous ordering of devm-managed resources.

What the fix does

The patch moves the entire IRQ-request loop (`devm_request_threaded_irq`) to execute *after* both `devm_power_supply_register()` calls for the charger and battery [patch_id=2661485]. Because `devm` releases resources in reverse allocation order, the IRQ handler is now unregistered *before* the `power_supply` handle is freed, closing both the removal-time use-after-free and the probe-time uninitialized-handle race. No other logic changes were needed.

Preconditions

  • inputThe attacker must be able to cause a hardware interrupt on the PF1550 charger IC (e.g., by manipulating charger state) during the driver removal or probe window.
  • configThe vulnerable driver must be loaded and either being removed (rmmod/unbind) or probed.

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.