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

CVE-2026-45867

CVE-2026-45867

Description

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

power: supply: act8945a: 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.

AI Insight

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

A use-after-free in the Linux kernel's act8945a charger driver occurs due to devm IRQ request before power supply registration, potentially leading to system crash or memory corruption.

Vulnerability

A use-after-free vulnerability exists in the Linux kernel's act8945a power supply charger driver. The driver requests the interrupt handler using the devm_ (managed) API *before* allocating and registering the power_supply device. During device removal, devm_ releases resources in reverse order, so the power_supply handle is freed before the IRQ handler is unregistered. A race window allows an interrupt to fire after the power_supply handle has been freed but before the IRQ handler is removed, causing the handler to call power_supply_changed() with a freed pointer. The same ordering flaw also causes a potential use of an uninitialized handle if an interrupt fires during probe, before registration. Affected versions include all Linux kernel trees before the commit f27eb76def5c07e4d7cc468b40741f19dafc83ce was applied [1].

Exploitation

An attacker does not need special privileges. The vulnerability is triggered during normal device removal (unbind or module unload) or during probe if an interrupt arrives before the power_supply is registered. The attacker must have the ability to cause the driver to remove (e.g., via hot-unplug of the hardware) and to generate a racing interrupt, which may happen naturally depending on hardware behavior. No authentication is required; the race is purely a timing issue at the kernel driver level.

Impact

Successful exploitation leads to a use-after-free condition in the interrupt handler, which calls power_supply_changed() on a freed or uninitialized power_supply structure. This can crash the system (kernel panic) or silently corrupt memory, potentially leading to privilege escalation or information disclosure depending on system state. The vulnerability is rated with a high severity due to the likelihood of a crash and the possibility of memory corruption.

Mitigation

The fix is to ensure the IRQ is requested *after* the power_supply handle is registered. The commit f27eb76def5c07e4d7cc468b40741f19dafc83ce resolves the issue by reordering the initialization in the driver. Users should apply the corresponding kernel update from their Linux distribution. No workaround is available if the patch is not applied, as the issue is inherent in the driver's lifecycle management. The vulnerability is not known to be listed in CISA's Known Exploited Vulnerabilities (KEV) catalog.

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

16
83c1bd466c51

power: supply: act8945a: 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 · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index 3901a02f326a55..9dec4486b1439a 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
f2a0777b1e5a

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

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitWaqar HameedDec 20, 2025Fixed in 5.10.252via kernel-cna
1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index 5f3eb6941d0586..a12cbfeca11238 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
0768e8525a46

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

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitWaqar HameedDec 20, 2025Fixed in 5.15.202via kernel-cna
1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index e9b5f42837729f..e9cb06daecea90 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
697bb5dc0cb4

power: supply: act8945a: 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.6.128via kernel-cna
1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index e9b5f42837729f..e9cb06daecea90 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
f27eb76def5c

power: supply: act8945a: 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 · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index 3901a02f326a55..9dec4486b1439a 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
3291c51d4684

power: supply: act8945a: 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 · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index 3901a02f326a55..9dec4486b1439a 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
76a42ba547a9

power: supply: act8945a: 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 · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index 51122bfbf196c9..699030bfa296ac 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
d023ef9f748b

power: supply: act8945a: 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.1.165via kernel-cna
1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index e9b5f42837729f..e9cb06daecea90 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
0768e8525a46

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

1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index e9b5f42837729f..e9cb06daecea90 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
76a42ba547a9

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

1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index 51122bfbf196c9..699030bfa296ac 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
83c1bd466c51

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

1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index 3901a02f326a55..9dec4486b1439a 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
d023ef9f748b

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

1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index e9b5f42837729f..e9cb06daecea90 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
f2a0777b1e5a

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

1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index 5f3eb6941d0586..a12cbfeca11238 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
f27eb76def5c

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

1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index 3901a02f326a55..9dec4486b1439a 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
3291c51d4684

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

1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index 3901a02f326a55..9dec4486b1439a 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    
697bb5dc0cb4

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

1 file changed · +8 9
  • drivers/power/supply/act8945a_charger.c+8 9 modified
    diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
    index e9b5f42837729f..e9cb06daecea90 100644
    --- a/drivers/power/supply/act8945a_charger.c
    +++ b/drivers/power/supply/act8945a_charger.c
    @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return irq ?: -ENXIO;
     	}
     
    -	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    -			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    -			       charger);
    -	if (ret) {
    -		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    -		return ret;
    -	}
    -
     	charger->desc.name = "act8945a-charger";
     	charger->desc.get_property = act8945a_charger_get_property;
     	charger->desc.properties = act8945a_charger_props;
    @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
     		return PTR_ERR(charger->psy);
     	}
     
    +	ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
    +			       IRQF_TRIGGER_FALLING, "act8945a_interrupt",
    +			       charger);
    +	if (ret) {
    +		dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
    +		return ret;
    +	}
    +
     	platform_set_drvdata(pdev, charger);
     
     	INIT_WORK(&charger->work, act8945a_work);
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Incorrect ordering of devm-managed resource allocation: IRQ requested before power_supply registration, causing use-after-free during teardown due to reverse deallocation order."

Attack vector

An attacker who can trigger a hardware interrupt on the ACT8945A charger's nIRQ pin during driver removal can cause a use-after-free. Because `devm_request_irq()` was called before `devm_power_supply_register()`, the `power_supply` handle is freed first during teardown (reverse allocation order), but the IRQ handler is unregistered afterward. A race window exists where an interrupt fires after the `power_supply` handle is freed but before the IRQ is unregistered, causing `act8945a_status_changed` to call `power_supply_changed()` on freed memory [patch_id=2661917]. A similar race exists during probe: an interrupt arriving before `power_supply_register()` would cause `power_supply_changed()` to use an uninitialized handle [patch_id=2661917].

Affected code

The bug is in `drivers/power/supply/act8945a_charger.c` in the `act8945a_charger_probe()` function [patch_id=2661917]. The original code called `devm_request_irq()` (lines ~597-603) before `devm_power_supply_register()` (line ~625), creating a reverse-teardown ordering problem.

What the fix does

The patch moves the `devm_request_irq()` call to after `devm_power_supply_register()` in `act8945a_charger_probe()` [patch_id=2661917]. This ensures the IRQ is registered last, so during teardown the IRQ handler is unregistered first (reverse order), preventing any interrupt from firing after the `power_supply` handle is freed. It also prevents interrupts during probe from reaching an unregistered `power_supply` handle.

Preconditions

  • configThe ACT8945A charger driver must be loaded and the hardware must be capable of generating interrupts on the nIRQ pin.
  • inputThe attacker must be able to trigger a hardware interrupt (e.g., by manipulating charger state) during the driver removal race window.

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

References

8

News mentions

0

No linked articles in our index yet.