Syzkaller reports a null-ptr-deref in gpiolib_seq_stop() [1]
If the memory allocation for priv variable in gpiolib_seq_start() fails, then s->private remains uninitialized, which leads to a null pointer dereference to s->private in gpiolib_seq_stop().
[1] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 1 UID: 0 PID: 10120 Comm: gpio_seq_stop Not tainted 6.12.53 #4 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:gpiolib_seq_stop+0x4c/0xd0 Code: 48 c1 ea 03 80 3c 02 00 0f 85 95 00 00 00 48 8b 9b e0 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 8d 7b 04 48 89 fa 48 c1 ea 03 <0f> b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 04 84 d2 75 5d 8b RSP: 0018:ffffc90019f2fad8 EFLAGS: 00010247 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000400 RDX: 0000000000000000 RSI: ffffffff84c57bfe RDI: 0000000000000004 RBP: 0000000000000000 R08: 0000000000000dc0 R09: 00000000ffffffff R10: ffffffff8e3865b3 R11: 0000000000000001 R12: 0000000000000000 R13: ffffffff8bd9da80 R14: 0000000000010000 R15: 0000000000000000 FS: 00007fb9a07cf6c0(0000) GS:ffff888131600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000004c2018 CR3: 00000000264c6000 CR4: 00000000000006f0 Call Trace: <TASK> seq_read_iter+0x610/0x1290 seq_read+0x3a4/0x570 ? __pfx_seq_read+0x10/0x10 full_proxy_read+0x12a/0x1a0 ? __pfx_full_proxy_read+0x10/0x10 vfs_read+0x1e2/0xcf0 ? __fget_files+0x23a/0x3f0 ? __pfx_lock_release+0x10/0x10 ? fdget_pos+0x24c/0x360 ? __pfx_vfs_read+0x10/0x10 ? __pfx___mutex_lock+0x10/0x10 ? __fget_files+0x244/0x3f0 ksys_read+0x12f/0x260 ? __pfx_ksys_read+0x10/0x10 do_syscall_64+0xcd/0x230 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with Syzkaller
Fixes: e348544f7994 ("gpio: protect the list of GPIO devices with SRCU") Reported-by: syzbot+b95d0c98f01e7a95da72@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=b95d0c98f01e7a95da72 Cc: stable@vger.kernel.org # 6.9+ Signed-off-by: Ilia Gavrilov Ilia.Gavrilov@infotecs.ru --- drivers/gpio/gpiolib.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9952e412da50..13cf9f4bdc6d 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -5298,7 +5298,7 @@ static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos)
priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) - return NULL; + return ERR_PTR(-ENOMEM);
s->private = priv; if (*pos > 0) @@ -5331,8 +5331,11 @@ static void gpiolib_seq_stop(struct seq_file *s, void *v) { struct gpiolib_seq_priv *priv = s->private;
- srcu_read_unlock(&gpio_devices_srcu, priv->idx); - kfree(priv); + if (!IS_ERR(v)) { + srcu_read_unlock(&gpio_devices_srcu, priv->idx); + kfree(priv); + } + s->private = NULL; }
static int gpiolib_seq_show(struct seq_file *s, void *v)
linux-stable-mirror@lists.linaro.org