All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "HyeongJun An" <sammiee5311@gmail.com>
Cc: linux-input@vger.kernel.org, dmitry.torokhov@gmail.com
Subject: Re: [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the GET REPORT response to report_buf
Date: Thu, 20 Aug 2026 11:27:25 +0000	[thread overview]
Message-ID: <20260820112725.966F21F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260820111558.475304-3-sammiee5311@gmail.com>

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

Pre-existing issues:
- [High] State machine desynchronization in raw request handlers due to unreset completion flags.
- [High] Missing locking in raw request handlers allows concurrent requests to corrupt the shared command and response buffers.
- [High] Use-After-Free: DMA buffers are freed during driver remove() without synchronizing with the threaded IRQ handler.
- [Medium] Subsystem API Violation: The transport driver uses hid_input_report() instead of hid_safe_input_report().
- [Medium] Signal interruptions are incorrectly treated as timeouts in raw requests, breaking signal handling.
--

--- Patch [2]: [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the GET REPORT response to report_buf ---
commit c4e25ca5cbdc0b92b00b6a64c016c4b8ee39d40d
Author: HyeongJun An <sammiee5311@gmail.com>

HID: intel-thc-hid: intel-quickspi: bound the GET REPORT response to report_buf

This patch bounds the GET_FEATURE and GET_INPUT_REPORT response copy lengths
to qsdev->report_buf_size. It drops responses that exceed this size to prevent
overflowing the buffer with responses bounded only by the DMA packet size.

> diff --git a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
> index 847c5ec55569a..7d34cc22a11a8 100644
> --- a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
> +++ b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
[ ... ]
> @@ -210,10 +211,17 @@ void quickspi_handle_input_data(struct quickspi_device *qsdev, u32 buf_len)
>  
>  	case GET_FEATURE_RESPONSE:
>  	case GET_INPUT_REPORT_RESPONSE:
> -		qsdev->report_len = sizeof(body_hdr->content_id) + input_len;
> +		report_len = sizeof(body_hdr->content_id) + input_len;
> +		if (report_len > qsdev->report_buf_size) {
> +			dev_err_once(qsdev->dev, "Get report response too big: %u\n",
> +				     report_len);
> +			return;
> +		}
> +
> +		qsdev->report_len = report_len;
>  		input_report = input_body->content - sizeof(body_hdr->content_id);
>  
> -		memcpy(qsdev->report_buf, input_report, qsdev->report_len);
> +		memcpy(qsdev->report_buf, input_report, report_len);

[Severity: High]
This is a pre-existing issue, but missing locking in the raw request handlers 
appears to allow concurrent requests to corrupt qsdev->report_buf.

The HID core does not serialize raw_request callbacks. If multiple threads 
concurrently call quickspi_hid_raw_request(), they will both execute 
write_cmd_to_txdma(). 

This function writes the outgoing command into a single, unprotected shared 
buffer qsdev->report_buf:

quickspi_hid_raw_request() -> write_cmd_to_txdma() {
    ...
    write_buf = (struct output_report *)qsdev->report_buf;
    ...
    memcpy(write_buf->content, report_buf, report_buf_len);
}

Concurrently, the IRQ handler quickspi_handle_input_data() also writes the 
incoming response directly into the exact same qsdev->report_buf here.

Without a mutex protecting the request-response cycle and this buffer, could 
concurrent requests overwrite each other's outgoing commands, and could 
incoming responses overwrite commands being constructed?


[Severity: High]
This is a pre-existing issue, but can the state machine become desynchronized 
if a raw request times out?

If quickspi_get_report() times out, it returns -ETIMEDOUT without resetting 
the completion flag qsdev->get_report_cmpl:

quickspi_get_report() {
    ...
    ret = wait_event_interruptible_timeout(qsdev->get_report_cmpl_wq,
                                           qsdev->get_report_cmpl,
                                           QUICKSPI_ACK_WAIT_TIMEOUT * HZ);
    ...
}

If the hardware eventually sends a delayed response, the IRQ handler will 
set the flag to true. When a subsequent raw request is issued, it will write 
the new command, but wait_event_interruptible_timeout() will return 
immediately because the flag is already true.

Would this cause the driver to return stale data from the previous request 
and lose synchronization with the device? 

The set_report_cmpl flag appears to suffer from the exact same 
desynchronization flaw in quickspi_set_report().


[Severity: Medium]
This is a pre-existing issue, but are signal interruptions incorrectly treated 
as timeouts in raw requests?

In quickspi_get_report() and quickspi_set_report(), the driver uses 
wait_event_interruptible_timeout(). If the wait is interrupted by a signal, 
the function returns a negative error code (such as -ERESTARTSYS).

The driver checks for ret <= 0 and unconditionally returns -ETIMEDOUT:

quickspi_get_report() {
    ...
    if (ret <= 0 || !qsdev->get_report_cmpl) {
        dev_err_once(qsdev->dev, "Wait Get Report Response timeout, ret:%d\n", ret);
        return -ETIMEDOUT;
    }
    ...
}

Does this swallow the actual signal error code, preventing userspace from 
correctly handling signals and breaking the syscall restart mechanism?


[Severity: Medium]
This is a pre-existing issue, but should the transport driver use 
hid_safe_input_report() instead of hid_input_report() here?

According to the HID subsystem documentation, transport drivers must prefer 
hid_safe_input_report() over hid_input_report() when feeding data from 
hardware interrupts to the HID core. 

This allows the core to perform strict boundary checks against the maximum 
allocated buffer size, preventing out-of-bounds reads if a device supplies 
a malicious report descriptor.

quickspi_hid_send_report() {
    ...
    ret = hid_input_report(qsdev->hid_dev, HID_INPUT_REPORT, data, data_len, 1);
    ...
}

Does using hid_input_report() expose the HID core to potential out-of-bounds 
reads?


[Severity: High]
This is a pre-existing issue, but could DMA buffers be freed during driver 
remove() without synchronizing with the threaded IRQ handler?

During driver removal, quickspi_remove() disables hardware interrupts and 
then calls quickspi_dma_deinit() which releases the DMA buffers:

quickspi_remove() {
    ...
    quickspi_dev_deinit(qsdev);
    quickspi_dma_deinit(qsdev);
    ...
}

However, it does not seem to synchronize with the devm-managed threaded IRQ 
handler (quickspi_irq_thread_handler), which might already be executing on 
another CPU. 

The threaded handler calls thc_rxdma_read(), which reads from the DMA 
buffers:

quickspi_irq_thread_handler() {
    ...
    ret = thc_rxdma_read(qsdev->thc_hw, THC_RXDMA2, qsdev->input_buf,
                         &input_len, &read_finished);
    ...
}

If thc_dma_release() frees these buffers while the threaded handler is 
concurrently executing, could this result in a Use-After-Free?

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

      reply	other threads:[~2026-08-20 11:27 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-20 11:15 [PATCH 0/2] HID: intel-thc-hid: intel-quickspi: two DMA buffer overflows HyeongJun An
2026-08-20 11:15 ` [PATCH 1/2] HID: intel-thc-hid: intel-quickspi: size the input buffer for the DMA HyeongJun An
2026-08-20 11:31   ` sashiko-bot
2026-08-20 11:15 ` [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the GET REPORT response to report_buf HyeongJun An
2026-08-20 11:27   ` 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=20260820112725.966F21F00A3A@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=sammiee5311@gmail.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.