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

CVE-2026-45879

CVE-2026-45879

Description

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

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

Use-after-free in bq25980 power-supply driver due to devm_ IRQ request before power_supply registration, causing race on removal or probe.

Vulnerability

In the Linux kernel's bq25980 power-supply driver, a use-after-free vulnerability exists because the driver uses the devm_ managed-resource API to request the interrupt line *before* allocating and registering the power_supply structure. Since devm_ releases resources in reverse order of allocation, the power_supply handle is freed *before* the interrupt handler is unregistered during driver removal. This creates a race window where an interrupt can fire after the power_supply has been freed but before the IRQ handler is torn down. The affected driver versions are those prior to the commit that reorders the registration, introduced in the Linux kernel and backported to stable. The description references commit 5f0b1cb41906e86b64bf69f5ededb83b0d757c27 as the fix [1].

Exploitation

An attacker needs no special privileges or user interaction to trigger the race. The driver is typically used on systems with a compatible battery charger IC. During normal driver removal (rmmod, system shutdown, or device unbind), the race window opens between the freeing of the power_supply handle and the actual unregistration of the IRQ. If a hardware interrupt from the charging IC arrives precisely in that window, the handler calls power_supply_changed() with a dangling pointer. Additionally, during probe, an interrupt arriving *before* the power_supply is registered would use an uninitialized handle. Both scenarios are race conditions dependent on timing [1].

Impact

A successful exploit of the use-after-free leads to a kernel crash (system panic) or memory corruption. The attacker gains no elevated privileges or data disclosure; the impact is denial of service (system unavailability) due to the kernel dereferencing a freed power_supply structure. In the probe scenario, calling power_supply_changed() with an uninitialized handle could also cause undefined behavior [1].

Mitigation

The fix is to request the IRQ *after* successfully registering the power_supply device, as done in commit 5f0b1cb41906e86b64bf69f5ededb83b0d757c27 in the Linux kernel stable tree. Users should update to a kernel version containing this commit. As the vulnerability was disclosed in May 2026, the fix is available. There is no known workaround; systems must apply the kernel patch. The CVE is not listed on the CISA Known Exploited Vulnerabilities (KEV) catalog as of the publication date [1].

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
5f0b1cb41906

power: supply: bq25980: 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 · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 4f91fd1a3dec9d..44af3a0c92e54b 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1240,6 +1240,12 @@ static int bq25980_probe(struct i2c_client *client)
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1250,12 +1256,6 @@ static int bq25980_probe(struct i2c_client *client)
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
4aeaf03c1726

power: supply: bq25980: 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 · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 0c5e2938bb36d6..b3060df9449eb8 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client)
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client)
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
0de95d29d847

power: supply: bq25980: 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 · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index d8411722266f51..fd00f9e5335487 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client)
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client)
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
0560a4b09c92

power: supply: bq25980: 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 · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 9339f564928278..54f444776f1745 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client,
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client,
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
16875e3b7bc9

power: supply: bq25980: 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 · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 0008c229fd9c79..a93919c4ea275b 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client,
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client,
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
86f93dfb23f5

power: supply: bq25980: 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 · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index b94ecf814e4342..98950e4456c38f 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client,
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client,
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
03d1e4ee4e6a

power: supply: bq25980: 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 · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 723858d62d1414..73f06f09f134cd 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client)
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client)
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
abea607ff2f6

power: supply: bq25980: 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 · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 723858d62d1414..73f06f09f134cd 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client)
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client)
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
5f0b1cb41906

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

1 file changed · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 4f91fd1a3dec9d..44af3a0c92e54b 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1240,6 +1240,12 @@ static int bq25980_probe(struct i2c_client *client)
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1250,12 +1256,6 @@ static int bq25980_probe(struct i2c_client *client)
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
4aeaf03c1726

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

1 file changed · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 0c5e2938bb36d6..b3060df9449eb8 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client)
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client)
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
16875e3b7bc9

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

1 file changed · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 0008c229fd9c79..a93919c4ea275b 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client,
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client,
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
0560a4b09c92

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

1 file changed · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 9339f564928278..54f444776f1745 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client,
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client,
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
03d1e4ee4e6a

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

1 file changed · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 723858d62d1414..73f06f09f134cd 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client)
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client)
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
0de95d29d847

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

1 file changed · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index d8411722266f51..fd00f9e5335487 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client)
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client)
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
abea607ff2f6

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

1 file changed · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index 723858d62d1414..73f06f09f134cd 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client)
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client)
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    
86f93dfb23f5

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

1 file changed · +6 7
  • drivers/power/supply/bq25980_charger.c+6 7 modified
    diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c
    index b94ecf814e4342..98950e4456c38f 100644
    --- a/drivers/power/supply/bq25980_charger.c
    +++ b/drivers/power/supply/bq25980_charger.c
    @@ -1241,6 +1241,12 @@ static int bq25980_probe(struct i2c_client *client,
     		return ret;
     	}
     
    +	ret = bq25980_power_supply_init(bq, dev);
    +	if (ret) {
    +		dev_err(dev, "Failed to register power supply\n");
    +		return ret;
    +	}
    +
     	if (client->irq) {
     		ret = devm_request_threaded_irq(dev, client->irq, NULL,
     						bq25980_irq_handler_thread,
    @@ -1251,12 +1257,6 @@ static int bq25980_probe(struct i2c_client *client,
     			return ret;
     	}
     
    -	ret = bq25980_power_supply_init(bq, dev);
    -	if (ret) {
    -		dev_err(dev, "Failed to register power supply\n");
    -		return ret;
    -	}
    -
     	ret = bq25980_hw_init(bq);
     	if (ret) {
     		dev_err(dev, "Cannot initialize the chip.\n");
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Incorrect ordering of devm-managed resource allocation causes a use-after-free race where the power_supply handle is freed before the IRQ handler that references it is unregistered."

Attack vector

An attacker who can trigger a hardware interrupt on the BQ259xx charger chip (e.g. by manipulating charger input conditions) can race against driver removal or probe. During removal, `devm_` deallocates resources in reverse order, so the `power_supply` handle is freed before the IRQ handler is unregistered; an interrupt arriving in that window causes `bq25980_irq_handler_thread` to call `power_supply_changed()` on a freed pointer [patch_id=2661761]. During probe, an interrupt that fires before `bq25980_power_supply_init()` runs would call `power_supply_changed()` on an uninitialized handle [patch_id=2661761].

Affected code

The vulnerability is in `drivers/power/supply/bq25980_charger.c` in the `bq25980_probe()` function [patch_id=2661761]. The original code called `devm_request_threaded_irq()` (to register the IRQ handler) *before* calling `bq25980_power_supply_init()` (to register the `power_supply` handle).

What the fix does

The patch swaps the order of operations in `bq25980_probe()`: `bq25980_power_supply_init()` (which allocates/registers the `power_supply` handle) is now called *before* `devm_request_threaded_irq()` [patch_id=2661761]. Because `devm_` resources are torn down in reverse allocation order, the IRQ handler will now be unregistered *before* the `power_supply` handle is freed during removal, closing the use-after-free race. The probe-time race is also eliminated because the `power_supply` handle is fully initialized before the IRQ is requested.

Preconditions

  • configThe system must have a BQ25980-family charger chip connected via I2C with an interrupt line (client->irq) configured.
  • inputThe attacker must be able to cause a hardware interrupt to fire on the charger chip (e.g. by manipulating charger input voltage/current) during the driver removal or probe 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.