On Tue, Aug 18, 2026 at 20:23:10 +0200, Greg Kroah-Hartman wrote:
How was this found and tested?
Found by code inspection: gb_lights_channel_register() publishes the LED class device and its brightness callback before mutex_init(&light->channels[i].lock) runs, so a concurrent brightness update can take an uninitialized mutex.
Tested by reproducing that code shape in a minimal out-of-tree module under QEMU (kernel 6.1.66 with CONFIG_DEBUG_MUTEXES=y and CONFIG_DEBUG_LOCK_ALLOC=y), since the real driver needs greybus/LED hardware I don't have. The module kzalloc's a channel, registers (publishes) it, and runs the brightness callback, which takes the embedded mutex:
- before the fix, mutex_init() runs after register, so the callback locks the still-zeroed mutex and trips
DEBUG_LOCKS_WARN_ON(lock->magic != lock) WARNING: CPU: 1 PID: 188 at kernel/locking/mutex.c:582 __mutex_lock+0x712/0xd20
- after the fix, mutex_init() runs before register and the same trigger path produces no warning.
The real driver hits this as a race (a concurrent brightness update), whereas the reproducer runs the callback synchronously during registration to make it deterministic; both leave the callback observing an uninitialized lock.
Thanks, Runyu Xiao