[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;
}
```