lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <fde484b7-5e02-4999-a564-6e6072a8a4d5@electromag.com.au>
Date: Mon, 5 Jan 2026 11:16:11 +0800
From: Phil Reid <preid@...ctromag.com.au>
To: Waqar Hameed <waqar.hameed@...s.com>, Sebastian Reichel <sre@...nel.org>
Cc: kernel@...s.com, linux-pm@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH 11/11] power: supply: sbs-battery: Fix use-after-free in
 power_supply_changed()

On 21/12/2025 06:36, Waqar Hameed wrote:
> 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. Keep the old behavior of
> just printing a warning in case of any failures during the IRQ request
> and finishing the probe successfully.
> 
> Fixes: d2cec82c2880 ("power: sbs-battery: Request threaded irq and fix dev callback cookie")
> Signed-off-by: Waqar Hameed <waqar.hameed@...s.com>

Reviewed-by: Phil Reid <preid@...ctromag.com.au>


> ---
>   drivers/power/supply/sbs-battery.c | 36 +++++++++++++++---------------
>   1 file changed, 18 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c
> index 943c82ee978f4..43c48196c1674 100644
> --- a/drivers/power/supply/sbs-battery.c
> +++ b/drivers/power/supply/sbs-battery.c
> @@ -1174,24 +1174,6 @@ static int sbs_probe(struct i2c_client *client)
>   
>   	i2c_set_clientdata(client, chip);
>   
> -	if (!chip->gpio_detect)
> -		goto skip_gpio;
> -
> -	irq = gpiod_to_irq(chip->gpio_detect);
> -	if (irq <= 0) {
> -		dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
> -		goto skip_gpio;
> -	}
> -
> -	rc = devm_request_threaded_irq(&client->dev, irq, NULL, sbs_irq,
> -		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> -		dev_name(&client->dev), chip);
> -	if (rc) {
> -		dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
> -		goto skip_gpio;
> -	}
> -
> -skip_gpio:
>   	/*
>   	 * Before we register, we might need to make sure we can actually talk
>   	 * to the battery.
> @@ -1217,6 +1199,24 @@ static int sbs_probe(struct i2c_client *client)
>   		return dev_err_probe(&client->dev, PTR_ERR(chip->power_supply),
>   				     "Failed to register power supply\n");
>   
> +	if (!chip->gpio_detect)
> +		goto out;
> +
> +	irq = gpiod_to_irq(chip->gpio_detect);
> +	if (irq <= 0) {
> +		dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
> +		goto out;
> +	}
> +
> +	rc = devm_request_threaded_irq(&client->dev, irq, NULL, sbs_irq,
> +		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> +		dev_name(&client->dev), chip);
> +	if (rc) {
> +		dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
> +		goto out;
> +	}
> +
> +out:
>   	dev_info(&client->dev,
>   		"%s: battery gas gauge device registered\n", client->name);
>   


-- 
Regards
Phil Reid
  
ElectroMagnetic Imaging Technology Pty Ltd
Development of Geophysical Instrumentation & Software
www.electromag.com.au
  
23 Junction Parade, Midland WA 6056, AUSTRALIA
Ph: +61 8 9250 8100
Fax: +61 8 9250 7100

Email: preid@...ctromag.com.au

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ