mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] HID: intel-thc-hid: intel-quickspi: two DMA buffer overflows
@ 2026-08-20 11:15 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
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: HyeongJun An @ 2026-08-20 11:15 UTC (permalink / raw)
  To: Even Xu, Xinpeng Sun, Jiri Kosina, Benjamin Tissoires
  Cc: linux-input, linux-kernel, stable, HyeongJun An

Two heap overflows on the QuickSPI receive path, both from a controller
that declares one length and sends another.

The first is the DMA landing buffer, sized from the device descriptor while
the THC DMA rounds its packet size up to 4K.  The second is the GET REPORT
response, whose length is checked against what the DMA delivered and never
against report_buf.  Each has a sibling in-tree that already gets it right,
named in the patch.

Neither was reproduced on hardware.  Both turned up while working on
commit 035ec4a71cb8 ("HID: intel-thc-hid: intel-quickspi: bound GET_REPORT
response to the caller buffer"), which covers neither.

A fuller fix for the first would give thc_rxdma_read() a capacity argument,
but that changes a shared API and touches intel-quicki2c, so this keeps to
the driver.

HyeongJun An (2):
  HID: intel-thc-hid: intel-quickspi: size the input buffer for the DMA
  HID: intel-thc-hid: intel-quickspi: bound the GET REPORT response to
    report_buf

 .../hid/intel-thc-hid/intel-quickspi/pci-quickspi.c  |  9 +++++++--
 .../intel-thc-hid/intel-quickspi/quickspi-protocol.c | 12 ++++++++++--
 2 files changed, 17 insertions(+), 4 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] HID: intel-thc-hid: intel-quickspi: size the input buffer for the DMA
  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 ` HyeongJun An
  2026-09-14  0:58   ` Xu, Even
  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-09-11 16:08 ` [PATCH 0/2] HID: intel-thc-hid: intel-quickspi: two DMA buffer overflows Jiri Kosina
  2 siblings, 1 reply; 8+ messages in thread
From: HyeongJun An @ 2026-08-20 11:15 UTC (permalink / raw)
  To: Even Xu, Xinpeng Sun, Jiri Kosina, Benjamin Tissoires
  Cc: linux-input, linux-kernel, stable, HyeongJun An

quickspi_alloc_report_buf() sizes input_buf from max_input_len, but the
RXDMA2 channel it feeds is programmed with ALIGN(max_input_len, SZ_4K):
quickspi_dma_init() passes the raw value and dma_set_max_packet_size()
rounds it up.  setup_dma_buffers() maps that rounded size and
read_dma_buffer() bounds the message against it, so a controller
reporting max_input_len 64 and rep_desc_len 600 gets a 600 byte buffer
behind a 4096 byte DMA.  thc_rxdma_read() has no capacity argument, so
nothing downstream can catch it.

The intel-quicki2c sibling floors its input buffer at SZ_4K for this
reason, with the comment "give default 4K buffer to avoid DMA buffer
overrun".  Round up the same way the DMA does.

Fixes: 4138f21115ae ("HID: intel-thc-hid: intel-quickspi: Complete THC QuickSPI driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
---
 drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
index 89226f5ce45e..9ef33574c202 100644
--- a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
+++ b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/irqreturn.h>
 #include <linux/pci.h>
+#include <linux/sizes.h>
 #include <linux/pm_runtime.h>
 
 #include <linux/gpio/consumer.h>
@@ -549,8 +550,12 @@ static int quickspi_alloc_report_buf(struct quickspi_device *qsdev)
 	if (!qsdev->report_descriptor)
 		return -ENOMEM;
 
-	max_input_len = max(le16_to_cpu(qsdev->dev_desc.rep_desc_len),
-			    le16_to_cpu(qsdev->dev_desc.max_input_len));
+	/*
+	 * thc_dma_set_max_packet_sizes() rounds the RXDMA2 packet size up to
+	 * 4K, so the DMA can hand back more than max_input_len bytes.
+	 */
+	max_input_len = max_t(size_t, le16_to_cpu(qsdev->dev_desc.rep_desc_len),
+			      ALIGN(le16_to_cpu(qsdev->dev_desc.max_input_len), SZ_4K));
 
 	qsdev->input_buf = devm_kzalloc(qsdev->dev, max_input_len, GFP_KERNEL);
 	if (!qsdev->input_buf)
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the GET REPORT response to report_buf
  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:15 ` HyeongJun An
  2026-09-14  1:59   ` [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the " Xu, Even
  2026-09-11 16:08 ` [PATCH 0/2] HID: intel-thc-hid: intel-quickspi: two DMA buffer overflows Jiri Kosina
  2 siblings, 1 reply; 8+ messages in thread
From: HyeongJun An @ 2026-08-20 11:15 UTC (permalink / raw)
  To: Even Xu, Xinpeng Sun, Jiri Kosina, Benjamin Tissoires
  Cc: linux-input, linux-kernel, stable, HyeongJun An

quickspi_handle_input_data() copies a GET_FEATURE or GET_INPUT_REPORT
response into qsdev->report_buf using a length the controller supplied.
The only check it passes is against buf_len, the number of bytes the DMA
delivered, which says nothing about the destination.  report_buf holds
HIDSPI_OUTPUT_REPORT_SIZE(max(max_output_len, max_input_len)), 68 bytes
for a controller reporting 64 for both, while the copy is bounded only by
the 4K DMA packet.

The REPORT_DESCRIPTOR_RESPONSE case a few lines up validates against the
size of its own destination.  Do the same here and let the waiter in
quickspi_get_report() time out, as the other malformed-frame checks do.

Fixes: 9d8d51735a3a ("HID: intel-thc-hid: intel-quickspi: Add HIDSPI protocol implementation")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
---
This needs commit a59cf84441f9 ("HID: intel-thc-hid: intel-quickspi:
validate report size before copy") for qsdev->report_buf_size, which is in
hid.git for-next but not mainline yet.  Same Fixes: tag, so a stable
backport wants the two in that order.

 .../intel-thc-hid/intel-quickspi/quickspi-protocol.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

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 847c5ec55569..7d34cc22a11a 100644
--- a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
+++ b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
@@ -161,6 +161,7 @@ void quickspi_handle_input_data(struct quickspi_device *qsdev, u32 buf_len)
 	struct input_report_body *input_body;
 	u8 *input_report;
 	u32 input_len;
+	u32 report_len;
 	int ret = 0;
 
 	input_body = (struct input_report_body *)qsdev->input_buf;
@@ -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);
 
 		qsdev->get_report_cmpl = true;
 		wake_up_interruptible(&qsdev->get_report_cmpl_wq);
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] HID: intel-thc-hid: intel-quickspi: two DMA buffer overflows
  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:15 ` [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the GET REPORT response to report_buf HyeongJun An
@ 2026-09-11 16:08 ` Jiri Kosina
  2026-09-14  0:41   ` Xu, Even
  2 siblings, 1 reply; 8+ messages in thread
From: Jiri Kosina @ 2026-09-11 16:08 UTC (permalink / raw)
  To: HyeongJun An
  Cc: Even Xu, Xinpeng Sun, Benjamin Tissoires, linux-input,
	linux-kernel, stable

On Thu, 20 Aug 2026, HyeongJun An wrote:

> Two heap overflows on the QuickSPI receive path, both from a controller
> that declares one length and sends another.
> 
> The first is the DMA landing buffer, sized from the device descriptor while
> the THC DMA rounds its packet size up to 4K.  The second is the GET REPORT
> response, whose length is checked against what the DMA delivered and never
> against report_buf.  Each has a sibling in-tree that already gets it right,
> named in the patch.
> 
> Neither was reproduced on hardware.  Both turned up while working on
> commit 035ec4a71cb8 ("HID: intel-thc-hid: intel-quickspi: bound GET_REPORT
> response to the caller buffer"), which covers neither.
> 
> A fuller fix for the first would give thc_rxdma_read() a capacity argument,
> but that changes a shared API and touches intel-quicki2c, so this keeps to
> the driver.
> 
> HyeongJun An (2):
>   HID: intel-thc-hid: intel-quickspi: size the input buffer for the DMA
>   HID: intel-thc-hid: intel-quickspi: bound the GET REPORT response to
>     report_buf

Even Xu, can you please review this? Thanks,

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH 0/2] HID: intel-thc-hid: intel-quickspi: two DMA buffer overflows
  2026-09-11 16:08 ` [PATCH 0/2] HID: intel-thc-hid: intel-quickspi: two DMA buffer overflows Jiri Kosina
@ 2026-09-14  0:41   ` Xu, Even
  0 siblings, 0 replies; 8+ messages in thread
From: Xu, Even @ 2026-09-14  0:41 UTC (permalink / raw)
  To: Jiri Kosina, HyeongJun An
  Cc: Sun, Xinpeng, Benjamin Tissoires, linux-input, linux-kernel, stable

Sure, sorry for missing these.

Best Regards,
Even Xu

> -----Original Message-----
> From: Jiri Kosina <jikos@kernel.org>
> Sent: Saturday, September 12, 2026 12:09 AM
> To: HyeongJun An <sammiee5311@gmail.com>
> Cc: Xu, Even <even.xu@intel.com>; Sun, Xinpeng <xinpeng.sun@intel.com>;
> Benjamin Tissoires <bentiss@kernel.org>; linux-input@vger.kernel.org; linux-
> kernel@vger.kernel.org; stable@vger.kernel.org
> Subject: Re: [PATCH 0/2] HID: intel-thc-hid: intel-quickspi: two DMA buffer
> overflows
> 
> On Thu, 20 Aug 2026, HyeongJun An wrote:
> 
> > Two heap overflows on the QuickSPI receive path, both from a
> > controller that declares one length and sends another.
> >
> > The first is the DMA landing buffer, sized from the device descriptor
> > while the THC DMA rounds its packet size up to 4K.  The second is the
> > GET REPORT response, whose length is checked against what the DMA
> > delivered and never against report_buf.  Each has a sibling in-tree
> > that already gets it right, named in the patch.
> >
> > Neither was reproduced on hardware.  Both turned up while working on
> > commit 035ec4a71cb8 ("HID: intel-thc-hid: intel-quickspi: bound
> > GET_REPORT response to the caller buffer"), which covers neither.
> >
> > A fuller fix for the first would give thc_rxdma_read() a capacity
> > argument, but that changes a shared API and touches intel-quicki2c, so
> > this keeps to the driver.
> >
> > HyeongJun An (2):
> >   HID: intel-thc-hid: intel-quickspi: size the input buffer for the DMA
> >   HID: intel-thc-hid: intel-quickspi: bound the GET REPORT response to
> >     report_buf
> 
> Even Xu, can you please review this? Thanks,
> 
> --
> Jiri Kosina
> SUSE Labs


^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH 1/2] HID: intel-thc-hid: intel-quickspi: size the input buffer for the DMA
  2026-08-20 11:15 ` [PATCH 1/2] HID: intel-thc-hid: intel-quickspi: size the input buffer for the DMA HyeongJun An
@ 2026-09-14  0:58   ` Xu, Even
  0 siblings, 0 replies; 8+ messages in thread
From: Xu, Even @ 2026-09-14  0:58 UTC (permalink / raw)
  To: HyeongJun An, Sun, Xinpeng, Jiri Kosina, Benjamin Tissoires
  Cc: linux-input, linux-kernel, stable



> -----Original Message-----
> From: HyeongJun An <sammiee5311@gmail.com>
> Sent: Thursday, August 20, 2026 7:16 PM
> To: Xu, Even <even.xu@intel.com>; Sun, Xinpeng <xinpeng.sun@intel.com>; Jiri
> Kosina <jikos@kernel.org>; Benjamin Tissoires <bentiss@kernel.org>
> Cc: linux-input@vger.kernel.org; linux-kernel@vger.kernel.org;
> stable@vger.kernel.org; HyeongJun An <sammiee5311@gmail.com>
> Subject: [PATCH 1/2] HID: intel-thc-hid: intel-quickspi: size the input buffer for the
> DMA
> 
> quickspi_alloc_report_buf() sizes input_buf from max_input_len, but the
> RXDMA2 channel it feeds is programmed with ALIGN(max_input_len, SZ_4K):
> quickspi_dma_init() passes the raw value and dma_set_max_packet_size()
> rounds it up.  setup_dma_buffers() maps that rounded size and
> read_dma_buffer() bounds the message against it, so a controller reporting
> max_input_len 64 and rep_desc_len 600 gets a 600 byte buffer behind a 4096
> byte DMA.  thc_rxdma_read() has no capacity argument, so nothing downstream
> can catch it.
> 
> The intel-quicki2c sibling floors its input buffer at SZ_4K for this reason, with the
> comment "give default 4K buffer to avoid DMA buffer overrun".  Round up the
> same way the DMA does.
> 
> Fixes: 4138f21115ae ("HID: intel-thc-hid: intel-quickspi: Complete THC QuickSPI
> driver")
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-opus-5
> Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
> ---
>  drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> index 89226f5ce45e..9ef33574c202 100644
> --- a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> +++ b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> @@ -9,6 +9,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/irqreturn.h>
>  #include <linux/pci.h>
> +#include <linux/sizes.h>
>  #include <linux/pm_runtime.h>
> 
>  #include <linux/gpio/consumer.h>
> @@ -549,8 +550,12 @@ static int quickspi_alloc_report_buf(struct
> quickspi_device *qsdev)
>  	if (!qsdev->report_descriptor)
>  		return -ENOMEM;
> 
> -	max_input_len = max(le16_to_cpu(qsdev->dev_desc.rep_desc_len),
> -			    le16_to_cpu(qsdev->dev_desc.max_input_len));
> +	/*
> +	 * thc_dma_set_max_packet_sizes() rounds the RXDMA2 packet size up
> to
> +	 * 4K, so the DMA can hand back more than max_input_len bytes.
> +	 */
> +	max_input_len = max_t(size_t, le16_to_cpu(qsdev-
> >dev_desc.rep_desc_len),
> +			      ALIGN(le16_to_cpu(qsdev-
> >dev_desc.max_input_len), SZ_4K));

This is the same case I explained in quicki2c patch https://lore.kernel.org/linux-input/IA1PR11MB609867952C6FAA206ECDAE32F4AD2@IA1PR11MB6098.namprd11.prod.outlook.com/
It's not a real issue.

Best Regards,
Even Xu

> 
>  	qsdev->input_buf = devm_kzalloc(qsdev->dev, max_input_len,
> GFP_KERNEL);
>  	if (!qsdev->input_buf)
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the response to report_buf
  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-09-14  1:59   ` Xu, Even
  2026-09-20  2:27     ` Xu, Even
  0 siblings, 1 reply; 8+ messages in thread
From: Xu, Even @ 2026-09-14  1:59 UTC (permalink / raw)
  To: HyeongJun An, Sun, Xinpeng, Jiri Kosina, Benjamin Tissoires
  Cc: linux-input, linux-kernel, stable



> -----Original Message-----
> From: HyeongJun An <sammiee5311@gmail.com>
> Sent: Thursday, August 20, 2026 7:16 PM
> To: Xu, Even <even.xu@intel.com>; Sun, Xinpeng <xinpeng.sun@intel.com>; Jiri
> Kosina <jikos@kernel.org>; Benjamin Tissoires <bentiss@kernel.org>
> Cc: linux-input@vger.kernel.org; linux-kernel@vger.kernel.org;
> stable@vger.kernel.org; HyeongJun An <sammiee5311@gmail.com>
> Subject: [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the response to
> report_buf
> 
> quickspi_handle_input_data() copies a GET_FEATURE or GET_INPUT_REPORT
> response into qsdev->report_buf using a length the controller supplied.
> The only check it passes is against buf_len, the number of bytes the DMA
> delivered, which says nothing about the destination.  report_buf holds

This is a special capability of the THC hardware. At the hardware level, THC supports the HID-over-SPI protocol, which means it understands every HIDSPI message it receives. When THC initiates a DMA transfer to fetch data, it verifies whether the received data size, including both the packet size declared in the header and the actual size of the transmitted packet, complies with the MAX Packet Size requirement. The packet is accepted only if it does. If the size exceeds the limit, THC reports a DMA buffer overflow, and the packet is discarded.

This capability of handling software logic in hardware can greatly simplify the driver's processing logic and maximize data-transfer performance. This is also why Intel created the THC IP.

> HIDSPI_OUTPUT_REPORT_SIZE(max(max_output_len, max_input_len)), 68 bytes
> for a controller reporting 64 for both, while the copy is bounded only by the 4K
> DMA packet.
> 
> The REPORT_DESCRIPTOR_RESPONSE case a few lines up validates against the
> size of its own destination.  Do the same here and let the waiter in
> quickspi_get_report() time out, as the other malformed-frame checks do.
> 
> Fixes: 9d8d51735a3a ("HID: intel-thc-hid: intel-quickspi: Add HIDSPI protocol
> implementation")
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-opus-5
> Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
> ---
> This needs commit a59cf84441f9 ("HID: intel-thc-hid: intel-quickspi:
> validate report size before copy") for qsdev->report_buf_size, which is in hid.git
> for-next but not mainline yet.  Same Fixes: tag, so a stable backport wants the
> two in that order.
> 
>  .../intel-thc-hid/intel-quickspi/quickspi-protocol.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> 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 847c5ec55569..7d34cc22a11a 100644
> --- a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
> +++ b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
> @@ -161,6 +161,7 @@ void quickspi_handle_input_data(struct quickspi_device
> *qsdev, u32 buf_len)
>  	struct input_report_body *input_body;
>  	u8 *input_report;
>  	u32 input_len;
> +	u32 report_len;
>  	int ret = 0;
> 
>  	input_body = (struct input_report_body *)qsdev->input_buf; @@ -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);

According to above explanation, this logic checking isn't a problem, because THC hardware will check it and guarantee the safe size.

Thanks for your patch!

Best Regards,
Even Xu

> 
>  		qsdev->get_report_cmpl = true;
>  		wake_up_interruptible(&qsdev->get_report_cmpl_wq);
> --
> 2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the response to report_buf
  2026-09-14  1:59   ` [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the " Xu, Even
@ 2026-09-20  2:27     ` Xu, Even
  0 siblings, 0 replies; 8+ messages in thread
From: Xu, Even @ 2026-09-20  2:27 UTC (permalink / raw)
  To: HyeongJun An, Sun, Xinpeng, Jiri Kosina, Benjamin Tissoires
  Cc: linux-input, linux-kernel, stable



> -----Original Message-----
> From: Xu, Even
> Sent: Monday, September 14, 2026 10:00 AM
> To: 'HyeongJun An' <sammiee5311@gmail.com>; Sun, Xinpeng
> <Xinpeng.Sun@intel.com>; Jiri Kosina <jikos@kernel.org>; Benjamin Tissoires
> <bentiss@kernel.org>
> Cc: linux-input@vger.kernel.org; linux-kernel@vger.kernel.org;
> stable@vger.kernel.org
> Subject: RE: [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the response to
> report_buf
> 
> 
> 
> > -----Original Message-----
> > From: HyeongJun An <sammiee5311@gmail.com>
> > Sent: Thursday, August 20, 2026 7:16 PM
> > To: Xu, Even <even.xu@intel.com>; Sun, Xinpeng
> > <xinpeng.sun@intel.com>; Jiri Kosina <jikos@kernel.org>; Benjamin
> > Tissoires <bentiss@kernel.org>
> > Cc: linux-input@vger.kernel.org; linux-kernel@vger.kernel.org;
> > stable@vger.kernel.org; HyeongJun An <sammiee5311@gmail.com>
> > Subject: [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the
> > response to report_buf
> >
> > quickspi_handle_input_data() copies a GET_FEATURE or GET_INPUT_REPORT
> > response into qsdev->report_buf using a length the controller supplied.
> > The only check it passes is against buf_len, the number of bytes the
> > DMA delivered, which says nothing about the destination.  report_buf
> > holds
> 
> This is a special capability of the THC hardware. At the hardware level, THC
> supports the HID-over-SPI protocol, which means it understands every HIDSPI
> message it receives. When THC initiates a DMA transfer to fetch data, it verifies
> whether the received data size, including both the packet size declared in the
> header and the actual size of the transmitted packet, complies with the MAX
> Packet Size requirement. The packet is accepted only if it does. If the size
> exceeds the limit, THC reports a DMA buffer overflow, and the packet is
> discarded.
> 
> This capability of handling software logic in hardware can greatly simplify the
> driver's processing logic and maximize data-transfer performance. This is also
> why Intel created the THC IP.
> 
> > HIDSPI_OUTPUT_REPORT_SIZE(max(max_output_len, max_input_len)), 68
> > bytes for a controller reporting 64 for both, while the copy is
> > bounded only by the 4K DMA packet.
> >
> > The REPORT_DESCRIPTOR_RESPONSE case a few lines up validates against
> > the size of its own destination.  Do the same here and let the waiter
> > in
> > quickspi_get_report() time out, as the other malformed-frame checks do.
> >
> > Fixes: 9d8d51735a3a ("HID: intel-thc-hid: intel-quickspi: Add HIDSPI
> > protocol
> > implementation")
> > Cc: stable@vger.kernel.org
> > Assisted-by: Claude:claude-opus-5
> > Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
> > ---
> > This needs commit a59cf84441f9 ("HID: intel-thc-hid: intel-quickspi:
> > validate report size before copy") for qsdev->report_buf_size, which
> > is in hid.git for-next but not mainline yet.  Same Fixes: tag, so a
> > stable backport wants the two in that order.
> >
> >  .../intel-thc-hid/intel-quickspi/quickspi-protocol.c | 12
> > ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > 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 847c5ec55569..7d34cc22a11a 100644
> > --- a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
> > +++ b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
> > @@ -161,6 +161,7 @@ void quickspi_handle_input_data(struct
> > quickspi_device *qsdev, u32 buf_len)
> >  	struct input_report_body *input_body;
> >  	u8 *input_report;
> >  	u32 input_len;
> > +	u32 report_len;
> >  	int ret = 0;
> >
> >  	input_body = (struct input_report_body *)qsdev->input_buf; @@
> > -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);
> 
> According to above explanation, this logic checking isn't a problem, because THC
> hardware will check it and guarantee the safe size.
> 
> Thanks for your patch!
> 
> Best Regards,
> Even Xu

Recently, just realized a case:
THC hardware depends on touch controller's report length to determine the correct package length and buffer overflow.
If there is something wrong in the touch controller side, such as: touch controller's behavior is wrong, or data lost in bus transferring such as bus noise, THC hardware will receive wrong data.
We need to avoid this in software driver.
From that viewpoint, this patch is valuable.

Reviewed-by: Even Xu <even.xu@intel.com>

Hi, Jiri and Benjamin,

Could you help merge this patch?
Thank you very much!

Best Regards,
Even Xu

> 
> >
> >  		qsdev->get_report_cmpl = true;
> >  		wake_up_interruptible(&qsdev->get_report_cmpl_wq);
> > --
> > 2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-09-20  2:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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-09-14  0:58   ` Xu, Even
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-09-14  1:59   ` [PATCH 2/2] HID: intel-thc-hid: intel-quickspi: bound the " Xu, Even
2026-09-20  2:27     ` Xu, Even
2026-09-11 16:08 ` [PATCH 0/2] HID: intel-thc-hid: intel-quickspi: two DMA buffer overflows Jiri Kosina
2026-09-14  0:41   ` Xu, Even

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®