All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Shevchenko <andriy.shevchenko@intel.com>
To: George Stark <gnstark@salutedevices.com>
Cc: pavel@ucw.cz, lee@kernel.org, vadimp@nvidia.com,
	mpe@ellerman.id.au, npiggin@gmail.com,
	christophe.leroy@csgroup.eu, linux-leds@vger.kernel.org,
	linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	kernel@sberdevices.ru
Subject: Re: [PATCH 0/8] devm_led_classdev_register() usage problem
Date: Fri, 24 Nov 2023 17:28:57 +0200	[thread overview]
Message-ID: <ZWDBOfpsC5AVT8bX@smile.fi.intel.com> (raw)
In-Reply-To: <20231025130737.2015468-1-gnstark@salutedevices.com>

On Wed, Oct 25, 2023 at 04:07:29PM +0300, George Stark wrote:
> Lots of drivers use devm_led_classdev_register() to register their led objects
> and let the kernel free those leds at the driver's remove stage.
> It can lead to a problem due to led_classdev_unregister()
> implementation calls led_set_brightness() to turn off the led.
> led_set_brightness() may call one of the module's brightness_set callbacks.
> If that callback uses module's resources allocated without using devm funcs()
> then those resources will be already freed at module's remove() callback and
> we may have use-after-free situation.
> 
> Here is an example:
> 
> module_probe()
> {
>     devm_led_classdev_register(module_brightness_set_cb);
>     mutex_init(&mutex);
> }
> 
> module_brightness_set_cb()
> {
>     mutex_lock(&mutex);
>     do_set_brightness();
>     mutex_unlock(&mutex);
> }
> 
> module_remove()
> {
>     mutex_destroy(&mutex);
> }
> 
> at rmmod:
> module_remove()
>     ->mutex_destroy(&mutex);
> devres_release_all()
>     ->led_classdev_unregister();
>         ->led_set_brightness();
>             ->module_brightness_set_cb();
>                  ->mutex_lock(&mutex);  /* use-after-free */
> 
> I think it's an architectural issue and should be discussed thoroughly.
> Some thoughts about fixing it as a start:
> 1) drivers can use devm_led_classdev_unregister() to explicitly free leds before
> dependend resources are freed. devm_led_classdev_register() remains being useful
> to simplify probe implementation.
> As a proof of concept I examined all drivers from drivers/leds and prepared
> patches where it's needed. Sometimes it was not as clean as just calling
> devm_led_classdev_unregister() because several drivers do not track
> their leds object at all - they can call devm_led_classdev_register() and drop the
> returned pointer. In that case I used devres group API.
> 
> Drivers outside drivers/leds should be checked too after discussion.
> 
> 2) remove led_set_brightness from led_classdev_unregister() and force the drivers
> to turn leds off at shutdown. May be add check that led's brightness is 0
> at led_classdev_unregister() and put a warning to dmesg if it's not.
> Actually in many cases it doesn't really need to turn off the leds manually one-by-one
> if driver shutdowns whole led controller. For the last case to disable the warning
> new flag can be brought in e.g LED_AUTO_OFF_AT_SHUTDOWN (similar to LED_RETAIN_AT_SHUTDOWN).

NAK.

Just fix the drivers by wrapping mutex_destroy() into devm, There are many
doing so. You may be brave enough to introduce devm_mutex_init() somewhere
in include/linux/device*

-- 
With Best Regards,
Andy Shevchenko



WARNING: multiple messages have this Message-ID (diff)
From: Andy Shevchenko <andriy.shevchenko@intel.com>
To: George Stark <gnstark@salutedevices.com>
Cc: vadimp@nvidia.com, lee@kernel.org, linux-kernel@vger.kernel.org,
	npiggin@gmail.com, pavel@ucw.cz, kernel@sberdevices.ru,
	linuxppc-dev@lists.ozlabs.org, linux-leds@vger.kernel.org
Subject: Re: [PATCH 0/8] devm_led_classdev_register() usage problem
Date: Fri, 24 Nov 2023 17:28:57 +0200	[thread overview]
Message-ID: <ZWDBOfpsC5AVT8bX@smile.fi.intel.com> (raw)
In-Reply-To: <20231025130737.2015468-1-gnstark@salutedevices.com>

On Wed, Oct 25, 2023 at 04:07:29PM +0300, George Stark wrote:
> Lots of drivers use devm_led_classdev_register() to register their led objects
> and let the kernel free those leds at the driver's remove stage.
> It can lead to a problem due to led_classdev_unregister()
> implementation calls led_set_brightness() to turn off the led.
> led_set_brightness() may call one of the module's brightness_set callbacks.
> If that callback uses module's resources allocated without using devm funcs()
> then those resources will be already freed at module's remove() callback and
> we may have use-after-free situation.
> 
> Here is an example:
> 
> module_probe()
> {
>     devm_led_classdev_register(module_brightness_set_cb);
>     mutex_init(&mutex);
> }
> 
> module_brightness_set_cb()
> {
>     mutex_lock(&mutex);
>     do_set_brightness();
>     mutex_unlock(&mutex);
> }
> 
> module_remove()
> {
>     mutex_destroy(&mutex);
> }
> 
> at rmmod:
> module_remove()
>     ->mutex_destroy(&mutex);
> devres_release_all()
>     ->led_classdev_unregister();
>         ->led_set_brightness();
>             ->module_brightness_set_cb();
>                  ->mutex_lock(&mutex);  /* use-after-free */
> 
> I think it's an architectural issue and should be discussed thoroughly.
> Some thoughts about fixing it as a start:
> 1) drivers can use devm_led_classdev_unregister() to explicitly free leds before
> dependend resources are freed. devm_led_classdev_register() remains being useful
> to simplify probe implementation.
> As a proof of concept I examined all drivers from drivers/leds and prepared
> patches where it's needed. Sometimes it was not as clean as just calling
> devm_led_classdev_unregister() because several drivers do not track
> their leds object at all - they can call devm_led_classdev_register() and drop the
> returned pointer. In that case I used devres group API.
> 
> Drivers outside drivers/leds should be checked too after discussion.
> 
> 2) remove led_set_brightness from led_classdev_unregister() and force the drivers
> to turn leds off at shutdown. May be add check that led's brightness is 0
> at led_classdev_unregister() and put a warning to dmesg if it's not.
> Actually in many cases it doesn't really need to turn off the leds manually one-by-one
> if driver shutdowns whole led controller. For the last case to disable the warning
> new flag can be brought in e.g LED_AUTO_OFF_AT_SHUTDOWN (similar to LED_RETAIN_AT_SHUTDOWN).

NAK.

Just fix the drivers by wrapping mutex_destroy() into devm, There are many
doing so. You may be brave enough to introduce devm_mutex_init() somewhere
in include/linux/device*

-- 
With Best Regards,
Andy Shevchenko



  parent reply	other threads:[~2023-11-24 15:29 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-25 13:07 [PATCH 0/8] devm_led_classdev_register() usage problem George Stark
2023-10-25 13:07 ` George Stark
2023-10-25 13:07 ` [PATCH 1/8] leds: powernv: explicitly unregister LEDs at module's shutdown George Stark
2023-10-25 13:07   ` George Stark
2023-10-25 13:07 ` [PATCH 2/8] leds: nic78bx: " George Stark
2023-10-25 13:07   ` George Stark
2023-11-06  8:13   ` Christophe Leroy
2023-11-06  8:13     ` Christophe Leroy
2023-11-09 23:28     ` George Stark
2023-11-09 23:28       ` George Stark
2023-10-25 13:07 ` [PATCH 3/8] leds: an30259a: " George Stark
2023-10-25 13:07   ` George Stark
2023-10-25 13:07 ` [PATCH 4/8] leds: mlxreg: " George Stark
2023-10-25 13:07   ` George Stark
2023-10-25 13:07 ` [PATCH 5/8] leds: aw200xx: " George Stark
2023-10-25 13:07   ` George Stark
2023-10-25 13:07 ` [PATCH 6/8] leds: aw2013: " George Stark
2023-10-25 13:07   ` George Stark
2023-10-25 13:07 ` [PATCH 7/8] leds: lp3952: " George Stark
2023-10-25 13:07   ` George Stark
2023-11-04  7:18 ` [PATCH 0/8] devm_led_classdev_register() usage problem George Stark
2023-11-04  7:18   ` George Stark
2023-11-24 15:30   ` Andy Shevchenko
2023-11-24 15:30     ` Andy Shevchenko
2023-11-06  8:11 ` Christophe Leroy
2023-11-06  8:11   ` Christophe Leroy
2023-11-24 15:28 ` Andy Shevchenko [this message]
2023-11-24 15:28   ` Andy Shevchenko
2023-11-25  0:47   ` George Stark
2023-11-25  0:47     ` George Stark
2023-11-25 11:04     ` Jonathan Cameron
2023-11-25 11:04       ` Jonathan Cameron
2023-11-27 12:41     ` Andy Shevchenko
2023-11-27 12:41       ` Andy Shevchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZWDBOfpsC5AVT8bX@smile.fi.intel.com \
    --to=andriy.shevchenko@intel.com \
    --cc=christophe.leroy@csgroup.eu \
    --cc=gnstark@salutedevices.com \
    --cc=kernel@sberdevices.ru \
    --cc=lee@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=npiggin@gmail.com \
    --cc=pavel@ucw.cz \
    --cc=vadimp@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.