Linux Input/HID development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "HyeongJun An" <sammiee5311@gmail.com>
Cc: dmitry.torokhov@gmail.com, linux-input@vger.kernel.org
Subject: Re: [PATCH v2] HID: intel-thc-hid: intel-quickspi: bound GET_REPORT response to the caller buffer
Date: Thu, 06 Aug 2026 14:45:33 +0000	[thread overview]
Message-ID: <20260806144534.3721B1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260806142321.3383353-1-sammiee5311@gmail.com>

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

New issues:
- [Medium] Missing READ_ONCE() in TOCTOU fix allows compiler to reload value, bypassing the bounds check.

Pre-existing issues:
- [Critical] Missing bounds check on user-supplied `buf_len` in `quickspi_set_report` causes a heap buffer overflow.
- [High] Lack of driver-level serialization allows concurrent IOCTLs and IRQs to corrupt shared DMA buffers.
- [High] Asymmetric teardown in remove function leads to Use-After-Free of HID device in IRQ handler.
- [High] Heap buffer overflow in `read_dma_buffer` due to copying 4K-aligned packet sizes into undersized input buffer.
- [Medium] Failing to reset waitqueue completion flags on timeout causes state machine desynchronization.
--

--- Patch [1]: [PATCH v2] HID: intel-thc-hid: intel-quickspi: bound GET_REPORT response to the caller buffer ---
commit 0324df489da12163fd70da0bf173d44cda181192
Author: HyeongJun An <sammiee5311@gmail.com>

HID: intel-thc-hid: intel-quickspi: bound GET_REPORT response to the caller buffer

This commit fixes an out-of-bounds write where the device-supplied response
is copied into the hidraw buffer without checking the buffer's length. It
updates quickspi_get_report() to take the buffer length and validate the
device's report size against it.

Link: https://lore.kernel.org/all/20260806133838.3378362-1-sammiee5311@gmail.com/

diff --git a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.c b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.c
index 91d5807b4a830..a60a0a7f16aad 100644
--- a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.c
+++ b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.c
[ ... ]
@@ -61,7 +61,7 @@ static int quickspi_hid_raw_request(struct hid_device *hid,
 
 	switch (reqtype) {
 	case HID_REQ_GET_REPORT:
-		ret = quickspi_get_report(qsdev, rtype, reportnum, buf);
+		ret = quickspi_get_report(qsdev, rtype, reportnum, buf, len);
 		break;
 	case HID_REQ_SET_REPORT:
 		ret = quickspi_set_report(qsdev, rtype, reportnum, buf, len);

[Severity: Critical]
This is a pre-existing issue, but are we missing a bounds check on the
user-supplied len in quickspi_set_report()?

When len (which can be up to HID_MAX_BUFFER_SIZE) is passed down to
write_cmd_to_txdma() in drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c:

quickspi_set_report()
   ret = write_cmd_to_txdma(qsdev, rep_type, report_id, buf + 1, buf_len - 1);

Could this unconditionally copy a large user input into the driver's internal
buffer, causing a heap buffer overflow?

>  		break;
[ ... ]
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 cb19057f1191b..10b06dea39612 100644
--- a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
+++ b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
[ ... ]
@@ -372,9 +374,16 @@ int quickspi_get_report(struct quickspi_device *qsdev,
 	}

[Severity: Medium]
This is a pre-existing issue, but could this timeout error path leave the
completion flag in a desynchronized state?

If wait_event_interruptible_timeout() returns -ETIMEDOUT but the device
later responds, a delayed interrupt could set qsdev->get_report_cmpl to true.
Would the next IOCTL then bypass the wait queue and consume a stale response?

>  	qsdev->get_report_cmpl = false;
>  
> -	memcpy(buf, qsdev->report_buf, qsdev->report_len);
> +	report_len = qsdev->report_len;
> +	if (report_len > buf_len) {
> +		dev_err_once(qsdev->dev, "Get report response too big, %u vs %u\n",
> +			     report_len, buf_len);
> +		return -EINVAL;
> +	}
> +
> +	memcpy(buf, qsdev->report_buf, report_len);

[Severity: Medium]
Is it possible for the compiler to optimize away the local report_len variable
and reload qsdev->report_len directly from memory during the memcpy() call?

If an interrupt updates qsdev->report_len to a larger size after the bounds
check but before the copy, could it bypass the check and overflow the caller's
buffer? Should this use READ_ONCE() to prevent reloading?

> -	return qsdev->report_len;
> +	return report_len;
>  }

[Severity: High]
This is a pre-existing issue, but is there a lack of driver-level serialization
that allows concurrent IOCTLs and IRQs to corrupt shared DMA buffers?

User space threads concurrently calling HIDIOCGFEATURE or HIDIOCSFEATURE via
hidraw only acquire a shared read lock (minors_rwsem). Both
quickspi_get_report() and quickspi_set_report() call write_cmd_to_txdma(),
which writes directly into the shared buffer locklessly:

drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c:write_cmd_to_txdma() {
    ...
    if (report_buf)
        memcpy(write_buf->report_bdy, report_buf, report_buf_len);
    ...
}

Furthermore, the threaded IRQ handler concurrently writes device responses into
the exact same buffer:

drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c:quickspi_handle_input_data() {
    ...
    memcpy(qsdev->report_buf, input_report, qsdev->report_len);
    ...
}

Can multiple threads and IRQs entering these paths simultaneously cause data
corruption or information leaks?

[Severity: High]
This is a pre-existing issue, but could the asymmetric teardown in
quickspi_remove() lead to a Use-After-Free of the HID device?

quickspi_remove() destroys and frees the hid_dev before hardware interrupts
are disabled:

drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c:quickspi_remove() {
    ...
    quickspi_hid_remove(qsdev);
    quickspi_dma_deinit(qsdev);

    pm_runtime_get_noresume(qsdev->dev);

    quickspi_dev_deinit(qsdev);
    ...
}

If the device is unbound via sysfs while hardware is actively sending
interrupts, could an interrupt fire in this window and cause
quickspi_handle_input_data() to invoke quickspi_hid_send_report(),
accessing the already freed qsdev->hid_dev?

[Severity: High]
This is a pre-existing issue, but is there a heap buffer overflow risk in
read_dma_buffer() due to copying 4K-aligned packet sizes into an undersized
input buffer?

The input_buf is allocated to the exact max_input_len:

drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c:quickspi_alloc_report_buf() {
    ...
    qsdev->input_buf = devm_kzalloc(qsdev->dev, max_input_len, GFP_KERNEL);
    ...
}

However, the bounds check in read_dma_buffer() uses the 4K-aligned
max_packet_size:

drivers/hid/intel-thc-hid/intel-thc/intel-thc-dma.c:read_dma_buffer() {
    ...
    if (mes_len > read_config->max_packet_size) {
        ...
    }
    ret = sg_copy_to_buffer(sg, nent, read_buff, mes_len);
    ...
}

If a malfunctioning or malicious hardware device sends a packet larger than
max_input_len but within the 4K alignment, will it bypass the bounds check
and overflow the smaller heap allocation?

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

  reply	other threads:[~2026-08-06 14:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-06 13:38 [PATCH] HID: intel-thc-hid: intel-quickspi: bound GET_REPORT response to the caller buffer HyeongJun An
2026-08-06 14:11 ` sashiko-bot
2026-08-06 14:23 ` [PATCH v2] " HyeongJun An
2026-08-06 14:45   ` sashiko-bot [this message]
2026-08-06 14:56   ` [PATCH v3] " HyeongJun An
2026-08-06 15:40     ` sashiko-bot
2026-08-10  6:29     ` Xu, Even

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=20260806144534.3721B1F000E9@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox