Linux Input/HID development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Yousef Alhouseen" <alhouseenyousef@gmail.com>
Cc: linux-input@vger.kernel.org, dmitry.torokhov@gmail.com
Subject: Re: [PATCH 1/6] HID: roccat-koneplus: reject short button reports
Date: Sun, 28 Jun 2026 17:01:03 +0000	[thread overview]
Message-ID: <20260628170104.6F80E1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260628164611.17467-1-alhouseenyousef@gmail.com>

Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Use-After-Free during device teardown due to incorrect removal ordering.
- [High] Incomplete Fix: Out-of-bounds read via short USB reports in the savu driver.
- [High] Memory leak of `struct roccat_reader` and `struct roccat_device` on hot-unplug.
- [High] Sleeping in atomic context due to mutex_lock in the raw_event path.
- [High] Lockless Access and Data Race on the `devices` array causing NULL pointer dereference or UAF.
- [High] Kernel information leak via sysfs attributes due to uninitialized memory copying and ignored errors.
- [Low] Unsynchronized access to `actual_profile` between process and interrupt context.
--

commit d5a3862120a746721ced4fff1b161538d9d1d57c
Author: Yousef Alhouseen <alhouseenyousef@gmail.com>

HID: roccat-koneplus: reject short button reports

The Koneplus raw-event path casts button reports to an eight-byte
structure before updating profile state and forwarding an event. A
malformed USB device can identify a shorter report as a button report
and trigger out-of-bounds reads.

Require the complete button report before either consumer sees it.

Fixes: 47dbdbffe15b ("HID: roccat: Add support for Roccat Kone[+] v2")
Cc: stable@vger.kernel.org
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>

> diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c
> index f80a60539a967..e0f35251e81a9 100644
> --- a/drivers/hid/hid-roccat-koneplus.c
> +++ b/drivers/hid/hid-roccat-koneplus.c
> @@ -523,6 +523,10 @@ static int koneplus_raw_event(struct hid_device *hdev,
>  	if (koneplus == NULL)
>  		return 0;
>  
> +	if (data[0] == KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON &&
> +	    size < sizeof(struct koneplus_mouse_report_button))
> +		return 0;
> +

[Severity: High]
This is a pre-existing issue, but does the savu driver also need a similar
check?

It looks like the savu driver lacks length validation. savu_raw_event()
forwards reports to savu_report_to_chrdev(), which casts the buffer:

drivers/hid/hid-roccat-savu.c:savu_report_to_chrdev() {
    ...
    roccat_report.type = special_report->type;
    roccat_report.data[0] = special_report->data[0];
    roccat_report.data[1] = special_report->data[1];
    ...
}

If a malicious USB device sends a 1-byte report to the savu driver, could
these accesses read out-of-bounds of the heap buffer and leak information
to userspace via the character device?

>  	koneplus_keep_values_up_to_date(koneplus, data);

[Severity: Low]
This isn't a bug introduced by this patch, but is it safe to update the
profile state here without synchronization?

koneplus->actual_profile is updated from sysfs in process context under
koneplus_lock, but it is also updated here in interrupt context via
koneplus_keep_values_up_to_date() without acquiring any locks:

drivers/hid/hid-roccat-koneplus.c:koneplus_keep_values_up_to_date() {
    ...
    koneplus_profile_activated(koneplus, button_report->data1 - 1);
    ...
}

Could this data race cause stale profile values to be read if sysfs
attributes are accessed concurrently with profile-changing USB events?

>  
>  	if (koneplus->roccat_claimed)

[Severity: High]
This is a pre-existing issue, but can this path sleep in atomic context?

koneplus_raw_event() runs in atomic interrupt context from the USB URB
completion handler. If roccat_claimed is true, it calls
koneplus_report_to_chrdev(), which eventually calls roccat_report_event():

drivers/hid/hid-roccat.c:roccat_report_event() {
    ...
    mutex_lock(&device->readers_lock);
    mutex_lock(&device->cbuf_lock);
    ...
}

Would acquiring these mutexes inside the raw_event path trigger a
scheduling-while-atomic bug upon receiving valid input events?

[Severity: High]
This is another pre-existing issue, but does roccat_report_event() have a
data race with device removal?

drivers/hid/hid-roccat.c:roccat_report_event() {
    ...
    device = devices[minor];
    
    new_value = kmemdup(data, device->report_size, GFP_ATOMIC);
    ...
}

If roccat_disconnect() runs concurrently, takes devices_lock, and sets
devices[minor] = NULL, could roccat_report_event() fetch a NULL or freed
device pointer locklessly, leading to a crash or use-after-free when
accessing device->report_size?

I also noticed a few other pre-existing issues in the ROCCAT subsystem
that might be worth addressing:

[Severity: Critical]
This is a pre-existing issue, but could there be a use-after-free during
device teardown?

In koneplus_remove(), the driver state is freed before the hardware is
stopped:

drivers/hid/hid-roccat-koneplus.c:koneplus_remove() {
    ...
    koneplus_remove_specials(hdev);
    hid_hw_stop(hdev);
    ...
}

If a USB event arrives exactly during this window before hid_hw_stop()
halts the in-flight USB URBs, koneplus_raw_event() will fetch the
freed driver data:

drivers/hid/hid-roccat-koneplus.c:koneplus_raw_event() {
    struct koneplus_device *koneplus = hid_get_drvdata(hdev);
    ...
    koneplus_keep_values_up_to_date(koneplus, data);
    ...
}

Would this dereference the freed koneplus pointer?

[Severity: High]
This is a pre-existing issue, but does hot-unplugging the device while it
is held open by userspace cause a memory leak?

When a ROCCAT device is unplugged, roccat_disconnect() clears the array slot:

drivers/hid/hid-roccat.c:roccat_disconnect() {
    ...
    devices[minor] = NULL;
    ...
}

If a user-space process holds the char device open, the memory isn't freed
immediately. When the process later closes the file descriptor,
roccat_release() checks the array:

drivers/hid/hid-roccat.c:roccat_release() {
    ...
    device = devices[minor];
    if (!device) {
        mutex_unlock(&devices_lock);
        pr_emerg("roccat device with minor %d doesn't exist\n", minor);
        return -ENODEV;
    }
    ...
}

Since the device was set to NULL during disconnect, it returns early and
bypasses freeing the reader and device structures. Are these structures
leaked permanently?

[Severity: High]
This is a pre-existing issue, but can sysfs attributes leak uninitialized
heap memory to userspace?

In roccat_common2_receive(), a buffer is allocated via kmalloc() without
GFP_ZERO. If usb_control_msg() fails, it still executes memcpy():

drivers/hid/hid-roccat-common.c:roccat_common2_receive() {
    ...
    len = usb_control_msg(...);
    
    memcpy(data, buf, size);
    ...
}

Sysfs show handlers ignore the return value and emit the potentially
uninitialized data:

drivers/hid/hid-roccat-koneplus.c:koneplus_sysfs_show_firmware_version() {
    ...
    roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO,
                    &info, KONEPLUS_SIZE_INFO);
    ...
    return sysfs_emit(buf, "%d\n", info.firmware_version);
}

If the USB transfer fails, does this expose uninitialized memory to any
local user able to read the sysfs files?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260628164611.17467-1-alhouseenyousef@gmail.com?part=1

      parent reply	other threads:[~2026-06-28 17:01 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-28 16:46 [PATCH 1/6] HID: roccat-koneplus: reject short button reports Yousef Alhouseen
2026-06-28 16:46 ` [PATCH 2/6] HID: roccat-isku: " Yousef Alhouseen
2026-06-28 16:59   ` sashiko-bot
2026-06-28 16:46 ` [PATCH 3/6] HID: roccat-pyra: " Yousef Alhouseen
2026-06-28 16:59   ` sashiko-bot
2026-06-28 16:46 ` [PATCH 4/6] HID: roccat-kovaplus: " Yousef Alhouseen
2026-06-28 16:58   ` sashiko-bot
2026-06-28 16:46 ` [PATCH 5/6] HID: roccat-konepure: " Yousef Alhouseen
2026-06-28 16:59   ` sashiko-bot
2026-06-28 16:46 ` [PATCH 6/6] HID: roccat-ryos: reject short special reports Yousef Alhouseen
2026-06-28 17:01   ` sashiko-bot
2026-06-28 17:01 ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260628170104.6F80E1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=alhouseenyousef@gmail.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox