* [syzbot] [input?] INFO: trying to register non-static key in roccat_open
@ 2026-09-06 2:07 syzbot
2026-09-07 22:44 ` [PATCH] HID: roccat: fully initialize device before publishing to devices[] Ivy Lopez
0 siblings, 1 reply; 4+ messages in thread
From: syzbot @ 2026-09-06 2:07 UTC (permalink / raw)
To: bentiss, erazor_de, jikos, linux-input, linux-kernel,
syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: bc35965f6940 Merge tag 'mm-hotfixes-stable-2026-09-03-17-4..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=1066ab49580000
kernel config: https://syzkaller.appspot.com/x/.config?x=b454dc6b1b7acd30
dashboard link: https://syzkaller.appspot.com/bug?extid=9f7405999979761b6cfc
compiler: Debian clang version 22.1.8 (++20260613092233+e80beda6e255-1~exp1~20260613092250.77), Debian LLD 22.1.8
Unfortunately, I don't have any reproducer for this issue yet.
Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/8cbf7acceedb/disk-bc35965f.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/203c0c282c1c/vmlinux-bc35965f.xz
kernel image: https://storage.googleapis.com/syzbot-assets/de1170205619/bzImage-bc35965f.xz
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+9f7405999979761b6cfc@syzkaller.appspotmail.com
INFO: trying to register non-static key.
The code is fine but needs lockdep annotation, or maybe
you didn't initialize this object before use?
turning off the locking correctness validator.
CPU: 1 UID: 0 PID: 7946 Comm: syz.4.562 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
assign_lock_key+0x133/0x150 kernel/locking/lockdep.c:1000
register_lock_class+0xcc/0x2e0 kernel/locking/lockdep.c:1315
__lock_acquire+0xaf/0x2e40 kernel/locking/lockdep.c:5128
lock_acquire+0x115/0x350 kernel/locking/lockdep.c:5908
__mutex_lock_common kernel/locking/rtmutex_api.c:559 [inline]
mutex_lock_nested+0x5a/0x1d0 kernel/locking/rtmutex_api.c:578
roccat_open+0xf6/0x5d0 drivers/hid/hid-roccat.c:178
chrdev_open+0x4dc/0x600 fs/char_dev.c:411
do_dentry_open+0x849/0x1420 fs/open.c:996
vfs_open+0x3b/0x350 fs/open.c:1101
do_open fs/namei.c:4837 [inline]
path_openat+0x1448/0x1d60 fs/namei.c:5000
do_file_open+0x23e/0x4a0 fs/namei.c:5029
do_sys_openat2+0x115/0x200 fs/open.c:1417
do_sys_open fs/open.c:1423 [inline]
__do_sys_openat fs/open.c:1439 [inline]
__se_sys_openat fs/open.c:1434 [inline]
__x64_sys_openat+0x138/0x170 fs/open.c:1434
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fde12ede159
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fde11136028 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 00007fde13165fa0 RCX: 00007fde12ede159
RDX: 0000000000000002 RSI: 0000200000000100 RDI: ffffffffffffff9c
RBP: 00007fde12f75024 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fde13166038 R14: 00007fde13165fa0 R15: 00007ffe150b2898
</TASK>
---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title
If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)
If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report
If you want to undo deduplication, reply with:
#syz undup
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH] HID: roccat: fully initialize device before publishing to devices[] 2026-09-06 2:07 [syzbot] [input?] INFO: trying to register non-static key in roccat_open syzbot @ 2026-09-07 22:44 ` Ivy Lopez 2026-09-07 22:58 ` sashiko-bot 0 siblings, 1 reply; 4+ messages in thread From: Ivy Lopez @ 2026-09-07 22:44 UTC (permalink / raw) To: erazor_de, jikos, bentiss Cc: linux-input, linux-kernel, syzbot+9f7405999979761b6cfc, Ivy Lopez roccat_connect() published the new device into the global devices[] array, then released devices_lock, before initializing readers_lock, cbuf_lock, the wait queue, the readers list, or setting hid/exist/ cbuf_end/report_size on the device. Since devices[] is checked (under devices_lock) by roccat_open() to decide whether a device is available to open, a concurrent open() racing against roccat_connect() could look up the device, then lock readers_lock before mutex_init() has run on it, or read device->hid while it is still NULL from kzalloc, once devices_lock is released but before the remaining fields are set. Move all initialization of the device's own private state ahead of the point where it is inserted into devices[], so the object is fully constructed before it becomes visible to any other reader. Reported-by: syzbot+9f7405999979761b6cfc@syzkaller.appspotmail.com Signed-off-by: Ivy Lopez <skunkolee@gmail.com> --- drivers/hid/hid-roccat.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index d6fff53d4ee7..53358297e96c 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -307,26 +307,32 @@ int roccat_connect(const struct class *klass, struct hid_device *hid, int report if (!device) return -ENOMEM; - mutex_lock(&devices_lock); + init_waitqueue_head(&device->wait); + INIT_LIST_HEAD(&device->readers); + mutex_init(&device->readers_lock); + mutex_init(&device->cbuf_lock); + device->hid = hid; + device->exist = 1; + device->cbuf_end = 0; + device->report_size = report_size; + mutex_lock(&devices_lock); for (minor = 0; minor < ROCCAT_MAX_DEVICES; ++minor) { if (devices[minor]) continue; break; } - - if (minor < ROCCAT_MAX_DEVICES) { - devices[minor] = device; - } else { + if (minor >= ROCCAT_MAX_DEVICES) { mutex_unlock(&devices_lock); kfree(device); return -EINVAL; } + device->minor = minor; + devices[minor] = device; device->dev = device_create(klass, &hid->dev, MKDEV(roccat_major, minor), NULL, "%s%s%d", "roccat", hid->driver->name, minor); - if (IS_ERR(device->dev)) { devices[minor] = NULL; mutex_unlock(&devices_lock); @@ -334,19 +340,8 @@ int roccat_connect(const struct class *klass, struct hid_device *hid, int report kfree(device); return temp; } - mutex_unlock(&devices_lock); - init_waitqueue_head(&device->wait); - INIT_LIST_HEAD(&device->readers); - mutex_init(&device->readers_lock); - mutex_init(&device->cbuf_lock); - device->minor = minor; - device->hid = hid; - device->exist = 1; - device->cbuf_end = 0; - device->report_size = report_size; - return minor; } EXPORT_SYMBOL_GPL(roccat_connect); -- 2.55.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] HID: roccat: fully initialize device before publishing to devices[] 2026-09-07 22:44 ` [PATCH] HID: roccat: fully initialize device before publishing to devices[] Ivy Lopez @ 2026-09-07 22:58 ` sashiko-bot 2026-09-07 23:31 ` [PATCH] HID: roccat: use reader->device instead of re-deriving from devices[] Ivy Lopez 0 siblings, 1 reply; 4+ messages in thread From: sashiko-bot @ 2026-09-07 22:58 UTC (permalink / raw) To: Ivy Lopez; +Cc: dmitry.torokhov, linux-input Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: Pre-existing issues: - [Critical] `roccat_release()` leaks memory and corrupts state by looking up the device from the global array instead of the reader struct when handling hot-unplug. - [High] `roccat_report_event()` calls sleepable `mutex_lock()` from within a hardirq/atomic context. - [High] A race between `roccat_disconnect()` and `roccat_release()` causes a Use-After-Free of the `roccat_device` structure. -- commit 46468883b2be9805a5a149d03c123b3d8fe1868c Author: Ivy Lopez <skunkolee@gmail.com> HID: roccat: fully initialize device before publishing to devices[] The patch moves the initialization of a roccat device's private state ahead of the point where it is inserted into the global devices array. This ensures the object is fully constructed before it becomes visible to concurrent readers. Reported-by: syzbot+9f7405999979761b6cfc@syzkaller.appspotmail.com Signed-off-by: Ivy Lopez <skunkolee@gmail.com> > diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c > index 4f15eb9510396..2d8b0da6fbb21 100644 > --- a/drivers/hid/hid-roccat.c > +++ b/drivers/hid/hid-roccat.c > @@ -316,26 +316,32 @@ int roccat_connect(const struct class *klass, struct hid_device *hid, int report > if (!device) > return -ENOMEM; > > - mutex_lock(&devices_lock); > + init_waitqueue_head(&device->wait); > + INIT_LIST_HEAD(&device->readers); > + mutex_init(&device->readers_lock); > + mutex_init(&device->cbuf_lock); > + device->hid = hid; > + device->exist = 1; > + device->cbuf_end = 0; > + device->report_size = report_size; > > + mutex_lock(&devices_lock); > for (minor = 0; minor < ROCCAT_MAX_DEVICES; ++minor) { > if (devices[minor]) > continue; > break; > } > - > - if (minor < ROCCAT_MAX_DEVICES) { > - devices[minor] = device; > - } else { > + if (minor >= ROCCAT_MAX_DEVICES) { > mutex_unlock(&devices_lock); > kfree(device); > return -EINVAL; > } > + device->minor = minor; > + devices[minor] = device; > > device->dev = device_create(klass, &hid->dev, > MKDEV(roccat_major, minor), NULL, > "%s%s%d", "roccat", hid->driver->name, minor); > - > if (IS_ERR(device->dev)) { > devices[minor] = NULL; > mutex_unlock(&devices_lock); > @@ -343,19 +349,8 @@ int roccat_connect(const struct class *klass, struct hid_device *hid, int report > kfree(device); > return temp; > } > - > mutex_unlock(&devices_lock); > > - init_waitqueue_head(&device->wait); > - INIT_LIST_HEAD(&device->readers); > - mutex_init(&device->readers_lock); > - mutex_init(&device->cbuf_lock); > - device->minor = minor; > - device->hid = hid; > - device->exist = 1; > - device->cbuf_end = 0; > - device->report_size = report_size; > - > return minor; > } > EXPORT_SYMBOL_GPL(roccat_connect); [Severity: Critical] This is a pre-existing issue, but does roccat_release() leak memory and corrupt state by looking up the device from the global array instead of the reader struct when handling hot-unplug? If the device is unplugged, roccat_disconnect() clears the global minor pointer: drivers/hid/hid-roccat.c:roccat_disconnect() { ... mutex_lock(&devices_lock); devices[minor] = NULL; mutex_unlock(&devices_lock); ... } If userspace later closes the file descriptor, roccat_release() retrieves the device from the global array rather than using the safe reader->device pointer: drivers/hid/hid-roccat.c:roccat_release() { ... mutex_lock(&devices_lock); device = devices[minor]; if (!device) { mutex_unlock(&devices_lock); pr_emerg("roccat device with minor %d doesn't exist\n", minor); return -ENODEV; } ... } Does this cause an early return that permanently leaks the device and reader structs? If a new Roccat device is plugged in before the file descriptor is closed, could it assume the old minor slot, causing roccat_release() to operate on the new device, prematurely decrementing its open count and potentially powering it down while the old device leaks? [Severity: High] This isn't a bug introduced by this patch, but does roccat_report_event() call sleepable mutex_lock() from within a hardirq/atomic context? The HID core triggers the raw_event callback (e.g., kone_raw_event) from an atomic context when the low-level transport driver completes an URB. This callback invokes roccat_report_event(), which acquires sleepable mutexes: drivers/hid/hid-roccat.c:roccat_report_event() { ... new_value = kmemdup(data, device->report_size, GFP_ATOMIC); if (!new_value) return -ENOMEM; mutex_lock(&device->readers_lock); mutex_lock(&device->cbuf_lock); ... } Can this lead to a scheduling while atomic panic or system deadlock upon receiving device events? [Severity: High] This is a pre-existing issue, but does a race between roccat_disconnect() and roccat_release() cause a Use-After-Free of the roccat_device structure? When roccat_disconnect() runs, it releases devices_lock before calling device_destroy(): drivers/hid/hid-roccat.c:roccat_disconnect() { ... mutex_lock(&devices_lock); device = devices[minor]; mutex_unlock(&devices_lock); device->exist = 0; device_destroy(device->dev->class, MKDEV(roccat_major, minor)); ... } If this is preempted after setting device->exist = 0, a concurrent roccat_release() can lock devices_lock, find devices[minor] is still non-NULL, decrement device->open to 0, and free the device because exist is 0: drivers/hid/hid-roccat.c:roccat_release() { ... if (!--device->open) { /* removing last reader */ if (device->exist) { ... } else { roccat_free_device(device); } } ... } When roccat_disconnect() resumes, is it possible that it calls device_destroy() using the freed device->dev pointer, causing a Use-After-Free? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260907224426.159104-1-skunkolee@gmail.com?part=1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH] HID: roccat: use reader->device instead of re-deriving from devices[] 2026-09-07 22:58 ` sashiko-bot @ 2026-09-07 23:31 ` Ivy Lopez 0 siblings, 0 replies; 4+ messages in thread From: Ivy Lopez @ 2026-09-07 23:31 UTC (permalink / raw) To: erazor_de, jikos, bentiss; +Cc: linux-input, linux-kernel, Ivy Lopez roccat_release() looked up the device via devices[minor] instead of using the reader's own reader->device pointer, which was already set at open() time and is guaranteed to reference the same device the reader was created against. This causes two problems on unplug-before-close: If a device is unplugged while a reader still has it open, roccat_disconnect() clears devices[minor] to NULL but leaves the device itself allocated (since device->open is still nonzero at that point). When the reader is later closed, roccat_release() looks up devices[minor], finds NULL, and returns -ENODEV immediately, leaking both the reader and the now-unreachable device without ever running list_del(), kfree(reader), or decrementing device->open. If a new device is connected before the old reader is closed, it can reuse the same minor, so devices[minor] instead points to the new device by the time the stale reader is released, causing release() to mutate the wrong device's readers list and open count. Use reader->device directly, matching the pattern already used by roccat_read() and roccat_poll() elsewhere in this file, so release() always operates on the device it was actually opened against. Fixes: 206f5f2fcb5f ("HID: roccat: propagate special events of roccat hardware to userspace") Signed-off-by: Ivy Lopez <skunkolee@gmail.com> --- Thanks to Sashiko AI review for flagging this on the prior patch to this file. --- drivers/hid/hid-roccat.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index 53358297e96c..bbaa782fb7da 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -202,19 +202,10 @@ static int roccat_open(struct inode *inode, struct file *file) static int roccat_release(struct inode *inode, struct file *file) { - unsigned int minor = iminor(inode); struct roccat_reader *reader = file->private_data; - struct roccat_device *device; + struct roccat_device *device = reader->device; mutex_lock(&devices_lock); - - device = devices[minor]; - if (!device) { - mutex_unlock(&devices_lock); - pr_emerg("roccat device with minor %d doesn't exist\n", minor); - return -ENODEV; - } - mutex_lock(&device->readers_lock); list_del(&reader->node); mutex_unlock(&device->readers_lock); @@ -229,9 +220,7 @@ static int roccat_release(struct inode *inode, struct file *file) kfree(device); } } - mutex_unlock(&devices_lock); - return 0; } -- 2.55.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-07 23:31 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-06 2:07 [syzbot] [input?] INFO: trying to register non-static key in roccat_open syzbot 2026-09-07 22:44 ` [PATCH] HID: roccat: fully initialize device before publishing to devices[] Ivy Lopez 2026-09-07 22:58 ` sashiko-bot 2026-09-07 23:31 ` [PATCH] HID: roccat: use reader->device instead of re-deriving from devices[] Ivy Lopez
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox