[BUG] gpio: sloppy-logic-analyzer: trigger buffer leak and capture OOB race
From: Qingyu Zhang
Date: Tue Sep 01 2026 - 22:14:24 EST
Hello,
gpio-sloppy-logic-analyzer's debugfs "trigger" file has two defects in
trigger_write(): it leaks the previous trigger buffer on every overwrite,
and it races with fops_capture_set() so a shorter rewrite can cause a
slab out-of-bounds read. One patch fixes both.
Type: memory leak + out-of-bounds read (same function, same lock)
* Summary (leak)
trigger_write() does:
buf = memdup_user(ubuf, count);
priv->trig_data = buf; /* previous buffer leaked */
priv->trig_len = count;
There is no kfree of the old trig_data. capture later kfree's it only
if capture actually runs.
* Summary (OOB race)
Capture waits for trigger pairs with IRQs off:
for (i = 0; i < priv->trig_len; i += 2) {
do {
...
} while ((state & priv->trig_data[i]) != priv->trig_data[i + 1]);
}
trigger_write() assigns a new trig_data / trig_len with no lock.
A 2048-byte trigger (1023 instant-match pairs + one never-match)
then a 2-byte rewrite while capture sits at i=2046 reads past the
new 2-byte object.
blob_lock is already held for the whole capture, including that wait.
trigger_write() just never takes it.
* Affected
Introduced in 7828b7bbbf20. Still present after 44f3468a0aef (unbind
UAF) and 7a7baebd9f23 (probe leak). Reproduced on 08dbfad3f504.
Needs CONFIG_GPIO_SLOPPY_LOGIC_ANALYZER, CONFIG_DEBUG_FS, kmemleak
(leak) and KASAN (OOB). No real analyzer hardware: a dummy gpiochip
binder is enough (see poc/).
* Reproduction (leak)
1. insmod gpio-sloppy-logic-analyzer.ko and a dummy gpiochip binder.
2. echo clear > /sys/kernel/debug/kmemleak
3. Write to debugfs trigger twice without starting capture:
printf 'AB' > $DIR/trigger
printf 'CD' > $DIR/trigger
4. echo scan > /sys/kernel/debug/kmemleak
kmemleak shows unreferenced objects from memdup_user in trigger_write.
* Reproduction (OOB)
dd if=/dev/zero bs=2046 count=1 of=/tmp/trig
printf '\x01\x01' >> /tmp/trig
cat /tmp/trig > $DIR/trigger
echo 1 > $DIR/capture &
sleep 1
printf '\x01\x01' > $DIR/trigger
KASAN: slab-out-of-bounds in fops_capture_set.
PoC: poc/run.sh (both halves). poc/bind.c provides the dummy gpiochip.
* Expected
trigger_write() frees the old buffer and takes blob_lock around the
swap, same as capture.
* Actual
Leaked trig_data buffers; KASAN slab-out-of-bounds on concurrent
shorter trigger write.
Please apply the suggested patch.
Thanks.
Suggested patch:
```
diff --git a/drivers/gpio/gpio-sloppy-logic-analyzer.c
b/drivers/gpio/gpio-sloppy-logic-analyzer.c
index 044d81e7cafb..a0fa0755368a 100644
--- a/drivers/gpio/gpio-sloppy-logic-analyzer.c
+++ b/drivers/gpio/gpio-sloppy-logic-analyzer.c
@@ -213,8 +213,11 @@ static ssize_t trigger_write(struct file *file,
const char __user *ubuf,
if (IS_ERR(buf))
return PTR_ERR(buf);
+ mutex_lock(&priv->blob_lock);
+ kfree(priv->trig_data);
priv->trig_data = buf;
priv->trig_len = count;
+ mutex_unlock(&priv->blob_lock);
return count;
}
```