[PATCH] HID: roccat: free buffered reports when destroying device
raoxu <[email protected]> Fri, 31 Jul 2026 16:49:26 +0800
| Newsgroups | org.kernel.vger.linux-input,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
From: Xu Rao <[email protected]> roccat_report_event() duplicates each report with kmemdup() and stores the allocation in a circular-buffer slot. The allocation is released only when that slot is reused. The device destruction paths free struct roccat_device without releasing reports still stored in cbuf[]. This makes those allocations unreachable and leaks up to ROCCAT_CBUF_SIZE report buffers per device. Add a small destructor that frees every buffered report before freeing the device, and use it in both paths that can destroy a registered device. Fixes: 206f5f2fcb5f ("HID: roccat: propagate special events of roccat hardware to userspace") Cc: [email protected] Signed-off-by: Xu Rao <[email protected]> --- drivers/hid/hid-roccat.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index d6fff53d4ee7..4f15eb951039 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -70,6 +70,15 @@ static struct roccat_device *devices[ROCCAT_MAX_DEVICES]; /* protects modifications of devices array */ static DEFINE_MUTEX(devices_lock); +static void roccat_free_device(struct roccat_device *device) +{ + int i; + + for (i = 0; i < ROCCAT_CBUF_SIZE; i++) + kfree(device->cbuf[i].value); + kfree(device); +} + static ssize_t roccat_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { @@ -226,7 +235,7 @@ static int roccat_release(struct inode *inode, struct file *file) hid_hw_power(device->hid, PM_HINT_NORMAL); hid_hw_close(device->hid); } else { - kfree(device); + roccat_free_device(device); } } @@ -374,7 +383,7 @@ void roccat_disconnect(int minor) hid_hw_close(device->hid); wake_up_interruptible(&device->wait); } else { - kfree(device); + roccat_free_device(device); } } EXPORT_SYMBOL_GPL(roccat_disconnect); -- 2.50.1