Linux LED subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Markus Probst" <markus.probst@posteo.de>
Cc: lee@kernel.org, ojeda@kernel.org, linux-pci@vger.kernel.org,
	linux-leds@vger.kernel.org
Subject: Re: [PATCH v24 3/4] rust: leds: add multicolor classdev abstractions
Date: Wed, 02 Sep 2026 23:15:44 +0000	[thread overview]
Message-ID: <20260902231544.8B2C71F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260903-rust_leds-v24-3-8d9e4c04db69@posteo.de>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Plain non-atomic reads of `intensity` and `brightness` from `UnsafeCell` in `MultiColorSubLed` cause a data race and Undefined Behavior with concurrent C subsystem modifications.
- [High] Calling `led_mc_calc_color_components` outside of the driver's locking creates a data race and TOCTOU vulnerability.
- [High] Casting concurrent pointers to `&mut usize` in `blink_set_callback` creates an aliasing violation (Undefined Behavior).
- [Low] The commit message description is not capitalized, violating the LED subsystem guidelines.
--

commit 0c1eb1680fe4ed1aa0ee60e6b95decec69575365
Author: Markus Probst <markus.probst@posteo.de>

rust: leds: add multicolor classdev abstractions

This commit introduces the necessary Rust abstractions to support multicolor
LED class devices. It provides wrappers around the C structures mc_subled
and led_classdev_mc, alongside integration with the LED device builder.

> rust: leds: add multicolor classdev abstractions
>
> Implement the abstractions needed for multicolor led class devices,

[Severity: Low]
This isn't a bug, but the LED subsystem guidelines require capitalizing the
description after the subsystem prefix. Should the subject be capitalized as
"Add multicolor classdev abstractions", and similarly the body text?

> diff --git a/rust/kernel/led/multicolor.rs b/rust/kernel/led/multicolor.rs
> new file mode 100644
> --- /dev/null
> +++ b/rust/kernel/led/multicolor.rs
[ ... ]
> +impl MultiColorSubLed {
[ ... ]
> +    pub const fn intensity(&self) -> u32 {
> +        // SAFETY:
> +        // - self.intensity.get() is a valid pointer to u32.
> +        // - We don't have exclusive or immutable access to self.intensity,
> +        //   but the alignment should prevent "load tearing".
> +        unsafe { *self.intensity.get() }
> +    }

[Severity: High]
Does this plain read cause Undefined Behavior under Rust's concurrency rules?

If a trigger from timer or interrupt context calls intensity() concurrently
while sysfs (via multi_intensity_store) modifies the memory under the
led_access mutex, this creates a data race.

Since plain non-atomic reads of concurrently mutated memory are considered
Undefined Behavior in Rust, should this use an atomic read or read_volatile
instead?

> +
> +    /// The brightness of the sub led.
> +    #[inline]
> +    pub const fn brightness(&self) -> u32 {
> +        // SAFETY:
> +        // - self.brightness.get() is a valid pointer to u32.
> +        // - We don't have exclusive or immutable access to self.brightness,
> +        //   but the alignment should prevent "load tearing".
> +        unsafe { *self.brightness.get() }
> +    }

[Severity: High]
Does this have the same data race and Undefined Behavior issue as the
intensity() read above?

[ ... ]
> +    unsafe extern "C" fn brightness_set_callback(
> +        led_cdev: *mut bindings::led_classdev,
> +        brightness: u32,
> +    ) {
[ ... ]
> +        // SAFETY: classdev.classdev.get() is guaranteed to be a pointer to a valid
> +        // led_classdev_mc.
> +        unsafe { bindings::led_mc_calc_color_components(classdev.classdev.get(), brightness) };
> +
> +        let _ = classdev.ops.brightness_set(parent, classdev, brightness);
> +    }

[Severity: High]
Can calling bindings::led_mc_calc_color_components() before the driver 
acquires its lock cause data corruption of the hardware state?

Concurrent calls to brightness_set_callback, for example from sysfs and a
hardware trigger, will execute bindings::led_mc_calc_color_components()
outside any locks, racing to overwrite the subled_info array. 

The driver's lock in classdev.ops.brightness_set is acquired too late to
prevent this corruption. Should C drivers invoke
bindings::led_mc_calc_color_components() while holding their own lock
instead?

[ ... ]
> +    unsafe extern "C" fn brightness_set_blocking_callback(
> +        led_cdev: *mut bindings::led_classdev,
> +        brightness: u32,
> +    ) -> i32 {
> +        from_result(|| {
[ ... ]
> +            // SAFETY: classdev.classdev.get() is guaranteed to be a pointer to a valid
> +            // led_classdev_mc.
> +            unsafe { bindings::led_mc_calc_color_components(classdev.classdev.get(), brightness) };
> +
> +            classdev.ops.brightness_set(parent, classdev, brightness)?;
> +            Ok(0)
> +        })
> +    }

[Severity: High]
Does this have the same data race vulnerability as brightness_set_callback()
above?

[ ... ]
> +    unsafe extern "C" fn blink_set_callback(
> +        led_cdev: *mut bindings::led_classdev,
> +        delay_on: *mut usize,
> +        delay_off: *mut usize,
> +    ) -> i32 {
> +        from_result(|| {
[ ... ]
> +            classdev.ops.blink_set(
> +                parent,
> +                classdev,
> +                // SAFETY: The function's contract guarantees that delay_on points to a usize
> +                // and is exclusive for the period of this function.
> +                unsafe { &mut *delay_on },
> +                // SAFETY: The function's contract guarantees that delay_off points to a usize
> +                // and is exclusive for the period of this function.
> +                unsafe { &mut *delay_off },
> +            )?;
> +            Ok(0)
> +        })
> +    }

[Severity: High]
Does casting these pointers to exclusive mutable references violate Rust's
aliasing rules and cause Undefined Behavior?

The C subsystem calls blink_set with pointers to led_cdev->blink_delay_on
and blink_delay_off. Concurrently, sysfs handlers like delay_on_store write
to these fields without taking a lock. 
    
Casting these shared, concurrently accessed pointers to exclusive mutable
references falsely asserts exclusive access.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260903-rust_leds-v24-0-8d9e4c04db69@posteo.de?part=3

  reply	other threads:[~2026-09-02 23:15 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02 23:01 [PATCH v24 0/4] rust: leds: add led classdev abstractions Markus Probst
2026-09-02 23:01 ` [PATCH v24 1/4] rust: leds: add basic " Markus Probst
2026-09-02 23:17   ` sashiko-bot
2026-09-04 13:03   ` Gary Guo
2026-09-04 13:15     ` Markus Probst
2026-09-04 13:32       ` Gary Guo
2026-09-04 14:04         ` Markus Probst
2026-09-02 23:01 ` [PATCH v24 2/4] rust: leds: add Mode trait Markus Probst
2026-09-02 23:08   ` sashiko-bot
2026-09-02 23:01 ` [PATCH v24 3/4] rust: leds: add multicolor classdev abstractions Markus Probst
2026-09-02 23:15   ` sashiko-bot [this message]
2026-09-02 23:01 ` [PATCH v24 4/4] MAINTAINERS: rust: leds: Add rust abstraction entry Markus Probst
2026-09-02 23:35 ` [PATCH v24 0/4] rust: leds: add led classdev abstractions Markus Probst

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=20260902231544.8B2C71F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=lee@kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=markus.probst@posteo.de \
    --cc=ojeda@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox