* [PATCH] HID: intel-thc-hid: validate ACPI buffer length before use
@ 2026-10-24 20:58 Tristan Madani
2026-10-24 21:35 ` sashiko-bot
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Tristan Madani @ 2026-10-24 20:58 UTC (permalink / raw)
To: Even Xu, Jiri Kosina, Benjamin Tissoires
Cc: Xinpeng Sun, linux-input, linux-kernel, stable, Tristan Madani
From: Tristan Madani <tristan@talencesecurity.com>
The QuickI2C and QuickSPI ACPI helpers copy firmware-returned buffers
into fixed-layout caller structs without checking the buffer length
against the destination size:
1. Buffer copies use the firmware-reported length without checking
it against the destination buffer size, allowing stack overflows
from oversized responses.
2. Undersized buffer responses leave caller struct fields
uninitialized, as fixed-layout structs like i2c_param and
i2c_config are consumed field-by-field after the call.
3. The QuickI2C DSD helper does not validate the returned ACPI
object type before accessing buffer-specific fields.
Add a buf_size parameter to all three helpers and enforce exact
buffer size matching for BUFFER type properties. Add type validation
in the DSD helper (the DSM helpers already receive type-checked
results from acpi_evaluate_dsm_typed()).
Fixes: 5282e45ccbfa ("HID: intel-thc-hid: intel-quicki2c: Add THC QuickI2C ACPI interfaces")
Fixes: 7cb06f08ef13 ("HID: intel-thc-hid: intel-quickspi: Add THC QuickSPI ACPI interfaces")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
.../intel-quicki2c/pci-quicki2c.c | 40 ++++++++++++++----
.../intel-quickspi/pci-quickspi.c | 41 ++++++++++++-------
2 files changed, 58 insertions(+), 23 deletions(-)
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
index 2537288b50261..a3d71f296b462 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
@@ -62,7 +62,8 @@ static const struct acpi_gpio_mapping quicki2c_gpios[] = {
* Return: 0 if success or ENODEV on failure.
*/
static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t *guid,
- u64 rev, u64 func, acpi_object_type type, void *prop_buf)
+ u64 rev, u64 func, acpi_object_type type,
+ void *prop_buf, size_t buf_size)
{
acpi_handle handle = acpi_device_handle(adev);
union acpi_object *obj;
@@ -75,10 +76,17 @@ static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t
return -ENODEV;
}
- if (type == ACPI_TYPE_INTEGER)
+ if (type == ACPI_TYPE_INTEGER) {
*(u32 *)prop_buf = (u32)obj->integer.value;
- else if (type == ACPI_TYPE_BUFFER)
+ } else if (type == ACPI_TYPE_BUFFER) {
+ if (buf_size > 0 && obj->buffer.length != buf_size) {
+ int err = obj->buffer.length > buf_size ? -ENOSPC : -EINVAL;
+
+ ACPI_FREE(obj);
+ return err;
+ }
memcpy(prop_buf, obj->buffer.pointer, obj->buffer.length);
+ }
ACPI_FREE(obj);
@@ -97,7 +105,8 @@ static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t
* Return: 0 if success or ENODEV on failed.
*/
static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string dsd_method_name,
- acpi_object_type type, void *prop_buf)
+ acpi_object_type type, void *prop_buf,
+ size_t buf_size)
{
acpi_handle handle = acpi_device_handle(adev);
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -113,7 +122,18 @@ static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string
ret_obj = buffer.pointer;
+ if (ret_obj->type != type) {
+ kfree(buffer.pointer);
+ return -EINVAL;
+ }
+ if (buf_size > 0 && ret_obj->buffer.length != buf_size) {
+ int err = ret_obj->buffer.length > buf_size ? -ENOSPC : -EINVAL;
+
+ kfree(buffer.pointer);
+ return err;
+ }
memcpy(prop_buf, ret_obj->buffer.pointer, ret_obj->buffer.length);
+ kfree(buffer.pointer);
return 0;
}
@@ -145,7 +165,7 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
QUICKI2C_ACPI_REVISION_NUM,
QUICKI2C_ACPI_FUNC_NUM_HID_DESC_ADDR,
ACPI_TYPE_INTEGER,
- &hid_desc_addr);
+ &hid_desc_addr, 0);
if (ret)
return ret;
@@ -155,7 +175,7 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
QUICKI2C_ACPI_REVISION_NUM,
QUICKI2C_ACPI_FUNC_NUM_ACTIVE_LTR_VAL,
ACPI_TYPE_INTEGER,
- &qcdev->active_ltr_val);
+ &qcdev->active_ltr_val, 0);
if (ret)
return ret;
@@ -163,12 +183,13 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
QUICKI2C_ACPI_REVISION_NUM,
QUICKI2C_ACPI_FUNC_NUM_LP_LTR_VAL,
ACPI_TYPE_INTEGER,
- &qcdev->low_power_ltr_val);
+ &qcdev->low_power_ltr_val, 0);
if (ret)
return ret;
ret = quicki2c_acpi_get_dsd_property(adev, QUICKI2C_ACPI_METHOD_NAME_ICRS,
- ACPI_TYPE_BUFFER, &i2c_param);
+ ACPI_TYPE_BUFFER, &i2c_param,
+ sizeof(i2c_param));
if (ret)
return ret;
@@ -180,7 +201,8 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
qcdev->i2c_config.target_addr = i2c_param.device_address;
ret = quicki2c_acpi_get_dsd_property(adev, QUICKI2C_ACPI_METHOD_NAME_ISUB,
- ACPI_TYPE_BUFFER, &i2c_config);
+ ACPI_TYPE_BUFFER, &i2c_config,
+ sizeof(i2c_config));
if (ret)
return ret;
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 ad676fde211b6..ec15ded2e91ea 100644
--- a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
+++ b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
@@ -81,7 +81,8 @@ static const struct acpi_gpio_mapping quickspi_gpios[] = {
* Return: 0 if successful or ENODEV on failed.
*/
static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid,
- u64 rev, u64 func, acpi_object_type type, void *prop_buf)
+ u64 rev, u64 func, acpi_object_type type,
+ void *prop_buf, size_t buf_size)
{
acpi_handle handle = acpi_device_handle(adev);
union acpi_object *obj;
@@ -94,10 +95,20 @@ static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid,
return -ENODEV;
}
- if (type == ACPI_TYPE_INTEGER)
+ if (type == ACPI_TYPE_INTEGER) {
*(u32 *)prop_buf = (u32)obj->integer.value;
- else if (type == ACPI_TYPE_BUFFER)
+ } else if (type == ACPI_TYPE_BUFFER) {
+ if (buf_size > 0 && obj->buffer.length != buf_size) {
+ int err = obj->buffer.length > buf_size ? -ENOSPC : -EINVAL;
+
+ acpi_handle_err(handle,
+ "_DSM buffer size mismatch: %llu vs %zu\n",
+ (unsigned long long)obj->buffer.length, buf_size);
+ ACPI_FREE(obj);
+ return err;
+ }
memcpy(prop_buf, obj->buffer.pointer, obj->buffer.length);
+ }
ACPI_FREE(obj);
@@ -129,7 +140,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_HDR_ADDR,
ACPI_TYPE_INTEGER,
- &qsdev->input_report_hdr_addr);
+ &qsdev->input_report_hdr_addr, 0);
if (ret)
return ret;
@@ -137,7 +148,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_BDY_ADDR,
ACPI_TYPE_INTEGER,
- &qsdev->input_report_bdy_addr);
+ &qsdev->input_report_bdy_addr, 0);
if (ret)
return ret;
@@ -145,7 +156,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_OUTPUT_REP_ADDR,
ACPI_TYPE_INTEGER,
- &qsdev->output_report_addr);
+ &qsdev->output_report_addr, 0);
if (ret)
return ret;
@@ -153,7 +164,8 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_READ_OPCODE,
ACPI_TYPE_BUFFER,
- &qsdev->spi_read_opcode);
+ &qsdev->spi_read_opcode,
+ sizeof(qsdev->spi_read_opcode));
if (ret)
return ret;
@@ -161,7 +173,8 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_WRITE_OPCODE,
ACPI_TYPE_BUFFER,
- &qsdev->spi_write_opcode);
+ &qsdev->spi_write_opcode,
+ sizeof(qsdev->spi_write_opcode));
if (ret)
return ret;
@@ -169,7 +182,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_IO_MODE,
ACPI_TYPE_INTEGER,
- &qsdev->spi_read_io_mode);
+ &qsdev->spi_read_io_mode, 0);
if (ret)
return ret;
@@ -184,7 +197,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_CONNECTION_SPEED,
ACPI_TYPE_INTEGER,
- &qsdev->spi_freq_val);
+ &qsdev->spi_freq_val, 0);
if (ret)
return ret;
@@ -192,7 +205,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_LIMIT_PACKET_SIZE,
ACPI_TYPE_INTEGER,
- &qsdev->limit_packet_size);
+ &qsdev->limit_packet_size, 0);
if (ret)
return ret;
@@ -205,7 +218,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_PERFORMANCE_LIMIT,
ACPI_TYPE_INTEGER,
- &qsdev->performance_limit);
+ &qsdev->performance_limit, 0);
if (ret)
return ret;
@@ -215,7 +228,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_ACTIVE_LTR,
ACPI_TYPE_INTEGER,
- &qsdev->active_ltr_val);
+ &qsdev->active_ltr_val, 0);
if (ret)
return ret;
@@ -223,7 +236,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_LP_LTR,
ACPI_TYPE_INTEGER,
- &qsdev->low_power_ltr_val);
+ &qsdev->low_power_ltr_val, 0);
if (ret)
return ret;
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] HID: intel-thc-hid: validate ACPI buffer length before use
2026-10-24 20:58 [PATCH] HID: intel-thc-hid: validate ACPI buffer length before use Tristan Madani
@ 2026-10-24 21:35 ` sashiko-bot
2026-10-25 10:49 ` kernel test robot
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-10-24 21:35 UTC (permalink / raw)
To: Tristan Madani; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] HID: intel-thc-hid: ISUB size check in quicki2c_acpi_get_dsd_property() fails
- [High] HID: intel-thc-hid: opcode size check in thc_acpi_get_property() fails probe
--
commit 7818ecd95e7c011bb989cd8c07a2ef782c095de2
Author: Tristan Madani <tristan@talencesecurity.com>
HID: intel-thc-hid: validate ACPI buffer length before use
This commit adds a buf_size parameter to the QuickI2C and QuickSPI ACPI
property helpers to enforce exact buffer length matching for buffer properties
and adds object type validation to the QuickI2C DSD helper.
> diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> index 7a913f717efaa..6f70b64f20105 100644
> --- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> +++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
[ ... ]
> @@ -97,7 +105,8 @@ static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t
> * Return: 0 if success or ENODEV on failed.
> */
> static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string dsd_method_name,
> - acpi_object_type type, void *prop_buf)
> + acpi_object_type type, void *prop_buf,
> + size_t buf_size)
> {
> acpi_handle handle = acpi_device_handle(adev);
> struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
> @@ -113,7 +122,18 @@ static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string
>
> ret_obj = buffer.pointer;
>
> + if (ret_obj->type != type) {
> + kfree(buffer.pointer);
> + return -EINVAL;
> + }
> + if (buf_size > 0 && ret_obj->buffer.length != buf_size) {
> + int err = ret_obj->buffer.length > buf_size ? -ENOSPC : -EINVAL;
> +
> + kfree(buffer.pointer);
> + return err;
> + }
> memcpy(prop_buf, ret_obj->buffer.pointer, ret_obj->buffer.length);
> + kfree(buffer.pointer);
>
> return 0;
> }
[ ... ]
> @@ -180,7 +201,8 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
> qcdev->i2c_config.target_addr = i2c_param.device_address;
>
> ret = quicki2c_acpi_get_dsd_property(adev, QUICKI2C_ACPI_METHOD_NAME_ISUB,
> - ACPI_TYPE_BUFFER, &i2c_config);
> + ACPI_TYPE_BUFFER, &i2c_config,
> + sizeof(i2c_config));
> if (ret)
> return ret;
[Severity: High]
Will requiring ret_obj->buffer.length to equal sizeof(i2c_config) in
quicki2c_get_acpi_resources() -> quicki2c_acpi_get_dsd_property() cause
QuickI2C probing to fail with -EINVAL?
In drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h,
struct quicki2c_subip_acpi_config is defined without __packed:
struct quicki2c_subip_acpi_config {
u64 SMHX;
...
u64 FSEN;
u64 FSVL;
u64 INDE;
u64 INDV;
u8 reserved;
};
With 22 u64 fields (176 bytes) followed by u8 reserved (1 byte), the compiler
adds 7 bytes of tail alignment padding on 64-bit architectures, making
sizeof(i2c_config) equal to 184 bytes.
Firmware ACPI buffers returned by the ISUB method do not include compiler tail
padding. Tables with the 4 advanced-feature u64 fields (FSEN, FSVL, INDE,
INDV, added in commit 0b1fca9dce44 ("HID: intel-thc-hid: intel-quicki2c:
Change ISUB table length")) are at most 177 bytes (0xB1), while Lunar Lake and
older BIOSes (as noted in commit 1db9df89a213 ("HID: intel-thc-hid:
intel-quicki2c: Update ACPI ISUB method support")) return 145 bytes (0x91).
Because ret_obj->buffer.length != buf_size rejects anything other than 184
bytes, won't every valid ISUB table be rejected? Also, if shorter 145-byte
ISUB buffers are accepted when qcdev->ddata is non-NULL, should i2c_config be
zero-initialized in quicki2c_get_acpi_resources() so that FSEN, FSVL, INDE,
and INDV are not read uninitialized from the stack?
> 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 53023e30cf8d4..29689f41f6bf0 100644
> --- a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> +++ b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> @@ -81,7 +81,8 @@ static const struct acpi_gpio_mapping quickspi_gpios[] = {
> * Return: 0 if successful or ENODEV on failed.
> */
> static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid,
> - u64 rev, u64 func, acpi_object_type type, void *prop_buf)
> + u64 rev, u64 func, acpi_object_type type,
> + void *prop_buf, size_t buf_size)
> {
> acpi_handle handle = acpi_device_handle(adev);
> union acpi_object *obj;
> @@ -94,10 +95,20 @@ static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid,
> return -ENODEV;
> }
>
> - if (type == ACPI_TYPE_INTEGER)
> + if (type == ACPI_TYPE_INTEGER) {
> *(u32 *)prop_buf = (u32)obj->integer.value;
> - else if (type == ACPI_TYPE_BUFFER)
> + } else if (type == ACPI_TYPE_BUFFER) {
> + if (buf_size > 0 && obj->buffer.length != buf_size) {
> + int err = obj->buffer.length > buf_size ? -ENOSPC : -EINVAL;
> +
> + acpi_handle_err(handle,
> + "_DSM buffer size mismatch: %llu vs %zu\n",
> + (unsigned long long)obj->buffer.length, buf_size);
> + ACPI_FREE(obj);
> + return err;
> + }
> memcpy(prop_buf, obj->buffer.pointer, obj->buffer.length);
> + }
>
> ACPI_FREE(obj);
>
> @@ -153,7 +164,8 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
> ACPI_QUICKSPI_FUNC_NUM_READ_OPCODE,
> ACPI_TYPE_BUFFER,
> - &qsdev->spi_read_opcode);
> + &qsdev->spi_read_opcode,
> + sizeof(qsdev->spi_read_opcode));
> if (ret)
> return ret;
>
> @@ -161,7 +173,8 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
> ACPI_QUICKSPI_FUNC_NUM_WRITE_OPCODE,
> ACPI_TYPE_BUFFER,
> - &qsdev->spi_write_opcode);
> + &qsdev->spi_write_opcode,
> + sizeof(qsdev->spi_write_opcode));
> if (ret)
> return ret;
[Severity: High]
Could passing sizeof(qsdev->spi_read_opcode) and
sizeof(qsdev->spi_write_opcode) to thc_acpi_get_property() break probing when
firmware returns 1-byte SPI opcode buffers?
In drivers/hid/intel-thc-hid/intel-quickspi/quickspi-dev.h, spi_read_opcode
and spi_write_opcode in struct quickspi_device are u32 (4 bytes):
u32 spi_read_opcode;
u32 spi_write_opcode;
However, per the HIDSPI _DSM specification (functions 4 and 5) and the
register configuration in drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
in thc_spi_read_config() and thc_spi_write_config():
if (io_mode == THC_QUAD_IO)
opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_QIO, opcode);
else if (io_mode == THC_DUAL_IO)
opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_DIO, opcode);
else
opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_SIO, opcode);
each SPI opcode is a single byte returned as a 1-byte ACPI buffer
(obj->buffer.length == 1) that was previously copied into the low byte of the
zero-allocated u32 field. With obj->buffer.length != buf_size checking against
4, won't thc_acpi_get_property() reject 1-byte opcode buffers with -EINVAL?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261024205850.4051206-1-tristmd@gmail.com?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] HID: intel-thc-hid: validate ACPI buffer length before use
2026-10-24 20:58 [PATCH] HID: intel-thc-hid: validate ACPI buffer length before use Tristan Madani
2026-10-24 21:35 ` sashiko-bot
@ 2026-10-25 10:49 ` kernel test robot
2026-10-25 15:47 ` [PATCH v2] HID: intel-thc-hid: validate ACPI buffer length before memcpy Tristan Madani
2026-10-25 21:40 ` [PATCH v3] " Tristan Madani
3 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2026-10-25 10:49 UTC (permalink / raw)
To: Tristan Madani, Even Xu, Jiri Kosina, Benjamin Tissoires
Cc: oe-kbuild-all, Xinpeng Sun, linux-input, linux-kernel, stable,
Tristan Madani
Hi Tristan,
kernel test robot noticed the following build warnings:
[auto build test WARNING on hid/for-next]
[also build test WARNING on linus/master v7.3 next-20261023]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Tristan-Madani/HID-intel-thc-hid-validate-ACPI-buffer-length-before-use/20261024-205850
base: https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
patch link: https://lore.kernel.org/r/20261024205850.4051206-1-tristmd%40gmail.com
patch subject: [PATCH] HID: intel-thc-hid: validate ACPI buffer length before use
config: x86_64-randconfig-1003-20261025 (https://download.01.org/0day-ci/archive/20261025/202610251809.9IHSydrI-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.4.0-5) 12.4.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261025/202610251809.9IHSydrI-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610251809.9IHSydrI-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> Warning: drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c:66 function parameter 'buf_size' not described in 'quicki2c_acpi_get_dsm_property'
>> Warning: drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c:109 function parameter 'buf_size' not described in 'quicki2c_acpi_get_dsd_property'
>> Warning: drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c:66 function parameter 'buf_size' not described in 'quicki2c_acpi_get_dsm_property'
>> Warning: drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c:109 function parameter 'buf_size' not described in 'quicki2c_acpi_get_dsd_property'
--
>> Warning: drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c:85 function parameter 'buf_size' not described in 'thc_acpi_get_property'
>> Warning: drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c:85 function parameter 'buf_size' not described in 'thc_acpi_get_property'
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2] HID: intel-thc-hid: validate ACPI buffer length before memcpy
2026-10-24 20:58 [PATCH] HID: intel-thc-hid: validate ACPI buffer length before use Tristan Madani
2026-10-24 21:35 ` sashiko-bot
2026-10-25 10:49 ` kernel test robot
@ 2026-10-25 15:47 ` Tristan Madani
2026-10-25 15:57 ` sashiko-bot
2026-10-26 2:02 ` Xu, Even
2026-10-25 21:40 ` [PATCH v3] " Tristan Madani
3 siblings, 2 replies; 7+ messages in thread
From: Tristan Madani @ 2026-10-25 15:47 UTC (permalink / raw)
To: even.xu, xinpeng.sun, jikos, bentiss
Cc: srinivas.pandruvada, mpearson-lenovo, linux-input, linux-kernel,
Tristan Madani, stable
From: Tristan Madani <tristan@talencesecurity.com>
The QuickI2C and QuickSPI ACPI helper functions copy firmware-returned
buffers into caller-provided structures without verifying the buffer
length. Malformed or short ACPI tables could cause an out-of-bounds
read from the firmware buffer, and oversized responses could overflow
the destination struct.
Additionally, quicki2c_acpi_get_dsd_property() does not validate the
returned ACPI object type before accessing buffer fields, and does not
free the allocated ACPI buffer on the success path, leaking memory on
every call.
Add a buf_size parameter to the ACPI helper functions and reject
responses larger than the destination buffer. Accept shorter responses
to handle firmware that returns buffers without struct tail padding
(e.g. ISUB tables returning 177 or 145 bytes for a 184-byte struct).
Zero-initialize caller stack structures so fields beyond the firmware
response length are deterministic. Add the missing type check and
kfree to the DSD helper.
Fixes: 5282e45ccbfa ("HID: intel-thc-hid: intel-quicki2c: Add THC QuickI2C ACPI interfaces")
Fixes: 7cb06f08ef13 ("HID: intel-thc-hid: intel-quickspi: Add THC QuickSPI ACPI interfaces")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
Changes in v2:
- Use overflow-only check (>) instead of exact-match (!=) so firmware
returning shorter buffers (e.g. 177 or 145 bytes for 184-byte ISUB
struct, or 1 byte for 4-byte SPI opcode) is accepted
- Zero-initialize caller stack structures for deterministic behavior
with short firmware responses
- Add missing type validation and kfree in DSD helper
- Add braces per coding style
.../intel-quicki2c/pci-quicki2c.c | 40 ++++++++++++++-----
.../intel-quickspi/pci-quickspi.c | 36 ++++++++++-------
2 files changed, 51 insertions(+), 25 deletions(-)
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
index 7a913f717efaad..dd21864d16b05b 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
@@ -62,7 +62,8 @@ static const struct acpi_gpio_mapping quicki2c_gpios[] = {
* Return: 0 if success or ENODEV on failure.
*/
static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t *guid,
- u64 rev, u64 func, acpi_object_type type, void *prop_buf)
+ u64 rev, u64 func, acpi_object_type type,
+ void *prop_buf, size_t buf_size)
{
acpi_handle handle = acpi_device_handle(adev);
union acpi_object *obj;
@@ -75,10 +76,15 @@ static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t
return -ENODEV;
}
- if (type == ACPI_TYPE_INTEGER)
+ if (type == ACPI_TYPE_INTEGER) {
*(u32 *)prop_buf = (u32)obj->integer.value;
- else if (type == ACPI_TYPE_BUFFER)
+ } else if (type == ACPI_TYPE_BUFFER) {
+ if (buf_size > 0 && obj->buffer.length > buf_size) {
+ ACPI_FREE(obj);
+ return -ENOSPC;
+ }
memcpy(prop_buf, obj->buffer.pointer, obj->buffer.length);
+ }
ACPI_FREE(obj);
@@ -97,7 +103,8 @@ static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t
* Return: 0 if success or ENODEV on failed.
*/
static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string dsd_method_name,
- acpi_object_type type, void *prop_buf)
+ acpi_object_type type, void *prop_buf,
+ size_t buf_size)
{
acpi_handle handle = acpi_device_handle(adev);
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -113,7 +120,16 @@ static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string
ret_obj = buffer.pointer;
+ if (ret_obj->type != type) {
+ kfree(buffer.pointer);
+ return -EINVAL;
+ }
+ if (buf_size > 0 && ret_obj->buffer.length > buf_size) {
+ kfree(buffer.pointer);
+ return -ENOSPC;
+ }
memcpy(prop_buf, ret_obj->buffer.pointer, ret_obj->buffer.length);
+ kfree(buffer.pointer);
return 0;
}
@@ -129,8 +145,8 @@ static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string
static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
{
struct acpi_device *adev = ACPI_COMPANION(qcdev->dev);
- struct quicki2c_subip_acpi_parameter i2c_param;
- struct quicki2c_subip_acpi_config i2c_config;
+ struct quicki2c_subip_acpi_parameter i2c_param = {};
+ struct quicki2c_subip_acpi_config i2c_config = {};
u32 hid_desc_addr;
int ret = -EINVAL;
@@ -145,7 +161,7 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
QUICKI2C_ACPI_REVISION_NUM,
QUICKI2C_ACPI_FUNC_NUM_HID_DESC_ADDR,
ACPI_TYPE_INTEGER,
- &hid_desc_addr);
+ &hid_desc_addr, 0);
if (ret)
return ret;
@@ -155,7 +171,7 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
QUICKI2C_ACPI_REVISION_NUM,
QUICKI2C_ACPI_FUNC_NUM_ACTIVE_LTR_VAL,
ACPI_TYPE_INTEGER,
- &qcdev->active_ltr_val);
+ &qcdev->active_ltr_val, 0);
if (ret)
return ret;
@@ -163,12 +179,13 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
QUICKI2C_ACPI_REVISION_NUM,
QUICKI2C_ACPI_FUNC_NUM_LP_LTR_VAL,
ACPI_TYPE_INTEGER,
- &qcdev->low_power_ltr_val);
+ &qcdev->low_power_ltr_val, 0);
if (ret)
return ret;
ret = quicki2c_acpi_get_dsd_property(adev, QUICKI2C_ACPI_METHOD_NAME_ICRS,
- ACPI_TYPE_BUFFER, &i2c_param);
+ ACPI_TYPE_BUFFER, &i2c_param,
+ sizeof(i2c_param));
if (ret)
return ret;
@@ -180,7 +197,8 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
qcdev->i2c_config.target_addr = i2c_param.device_address;
ret = quicki2c_acpi_get_dsd_property(adev, QUICKI2C_ACPI_METHOD_NAME_ISUB,
- ACPI_TYPE_BUFFER, &i2c_config);
+ ACPI_TYPE_BUFFER, &i2c_config,
+ sizeof(i2c_config));
if (ret)
return ret;
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 53023e30cf8d47..e4331ba4e503d9 100644
--- a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
+++ b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
@@ -81,7 +81,8 @@ static const struct acpi_gpio_mapping quickspi_gpios[] = {
* Return: 0 if successful or ENODEV on failed.
*/
static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid,
- u64 rev, u64 func, acpi_object_type type, void *prop_buf)
+ u64 rev, u64 func, acpi_object_type type,
+ void *prop_buf, size_t buf_size)
{
acpi_handle handle = acpi_device_handle(adev);
union acpi_object *obj;
@@ -94,10 +95,15 @@ static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid,
return -ENODEV;
}
- if (type == ACPI_TYPE_INTEGER)
+ if (type == ACPI_TYPE_INTEGER) {
*(u32 *)prop_buf = (u32)obj->integer.value;
- else if (type == ACPI_TYPE_BUFFER)
+ } else if (type == ACPI_TYPE_BUFFER) {
+ if (buf_size > 0 && obj->buffer.length > buf_size) {
+ ACPI_FREE(obj);
+ return -ENOSPC;
+ }
memcpy(prop_buf, obj->buffer.pointer, obj->buffer.length);
+ }
ACPI_FREE(obj);
@@ -129,7 +135,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_HDR_ADDR,
ACPI_TYPE_INTEGER,
- &qsdev->input_report_hdr_addr);
+ &qsdev->input_report_hdr_addr, 0);
if (ret)
return ret;
@@ -137,7 +143,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_BDY_ADDR,
ACPI_TYPE_INTEGER,
- &qsdev->input_report_bdy_addr);
+ &qsdev->input_report_bdy_addr, 0);
if (ret)
return ret;
@@ -145,7 +151,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_OUTPUT_REP_ADDR,
ACPI_TYPE_INTEGER,
- &qsdev->output_report_addr);
+ &qsdev->output_report_addr, 0);
if (ret)
return ret;
@@ -153,7 +159,8 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_READ_OPCODE,
ACPI_TYPE_BUFFER,
- &qsdev->spi_read_opcode);
+ &qsdev->spi_read_opcode,
+ sizeof(qsdev->spi_read_opcode));
if (ret)
return ret;
@@ -161,7 +168,8 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_WRITE_OPCODE,
ACPI_TYPE_BUFFER,
- &qsdev->spi_write_opcode);
+ &qsdev->spi_write_opcode,
+ sizeof(qsdev->spi_write_opcode));
if (ret)
return ret;
@@ -169,7 +177,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_IO_MODE,
ACPI_TYPE_INTEGER,
- &qsdev->spi_read_io_mode);
+ &qsdev->spi_read_io_mode, 0);
if (ret)
return ret;
@@ -184,7 +192,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_CONNECTION_SPEED,
ACPI_TYPE_INTEGER,
- &qsdev->spi_freq_val);
+ &qsdev->spi_freq_val, 0);
if (ret)
return ret;
@@ -192,7 +200,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_LIMIT_PACKET_SIZE,
ACPI_TYPE_INTEGER,
- &qsdev->limit_packet_size);
+ &qsdev->limit_packet_size, 0);
if (ret)
return ret;
@@ -205,7 +213,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_PERFORMANCE_LIMIT,
ACPI_TYPE_INTEGER,
- &qsdev->performance_limit);
+ &qsdev->performance_limit, 0);
if (ret)
return ret;
@@ -215,7 +223,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_ACTIVE_LTR,
ACPI_TYPE_INTEGER,
- &qsdev->active_ltr_val);
+ &qsdev->active_ltr_val, 0);
if (ret)
return ret;
@@ -223,7 +231,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_LP_LTR,
ACPI_TYPE_INTEGER,
- &qsdev->low_power_ltr_val);
+ &qsdev->low_power_ltr_val, 0);
if (ret)
return ret;
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2] HID: intel-thc-hid: validate ACPI buffer length before memcpy
2026-10-25 15:47 ` [PATCH v2] HID: intel-thc-hid: validate ACPI buffer length before memcpy Tristan Madani
@ 2026-10-25 15:57 ` sashiko-bot
2026-10-26 2:02 ` Xu, Even
1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-10-25 15:57 UTC (permalink / raw)
To: Tristan Madani; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] HID: intel-thc-hid: missing @buf_size kernel-doc in ACPI helpers
--
commit 43947a3c4aa80586265415752a6a772f3e74da02
Author: Tristan Madani <tristan@talencesecurity.com>
HID: intel-thc-hid: validate ACPI buffer length before memcpy
This commit adds a buf_size parameter to the QuickI2C and QuickSPI ACPI
helper functions to validate returned buffer lengths before copying them into
destination structures. It also adds missing ACPI object type validation and
memory cleanup in quicki2c_acpi_get_dsd_property(), and zero-initializes the
caller stack structures.
> diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> index 7a913f717efaa..dd21864d16b05 100644
> --- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> +++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> @@ -62,7 +62,8 @@ static const struct acpi_gpio_mapping quicki2c_gpios[] = {
> * Return: 0 if success or ENODEV on failure.
> */
> static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t *guid,
> - u64 rev, u64 func, acpi_object_type type, void *prop_buf)
> + u64 rev, u64 func, acpi_object_type type,
> + void *prop_buf, size_t buf_size)
> {
[ ... ]
> @@ -97,7 +103,8 @@ static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t
> * Return: 0 if success or ENODEV on failed.
> */
> static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string dsd_method_name,
> - acpi_object_type type, void *prop_buf)
> + acpi_object_type type, void *prop_buf,
> + size_t buf_size)
> {
[ ... ]
> 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 53023e30cf8d4..e4331ba4e503d 100644
> --- a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> +++ b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> @@ -81,7 +81,8 @@ static const struct acpi_gpio_mapping quickspi_gpios[] = {
> * Return: 0 if successful or ENODEV on failed.
> */
> static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid,
> - u64 rev, u64 func, acpi_object_type type, void *prop_buf)
> + u64 rev, u64 func, acpi_object_type type,
> + void *prop_buf, size_t buf_size)
> {
[Severity: Low]
Should the kernel-doc comments above quicki2c_acpi_get_dsm_property() and
quicki2c_acpi_get_dsd_property() in
drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c, as well as
thc_acpi_get_property() in
drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c, be updated to
describe the new @buf_size parameter?
Without @buf_size in those kernel-doc blocks, building with W=1 or running
scripts/kernel-doc triggers warnings that the function parameter buf_size is
not described.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261025154745.2734805-1-tristmd@gmail.com?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3] HID: intel-thc-hid: validate ACPI buffer length before memcpy
2026-10-24 20:58 [PATCH] HID: intel-thc-hid: validate ACPI buffer length before use Tristan Madani
` (2 preceding siblings ...)
2026-10-25 15:47 ` [PATCH v2] HID: intel-thc-hid: validate ACPI buffer length before memcpy Tristan Madani
@ 2026-10-25 21:40 ` Tristan Madani
3 siblings, 0 replies; 7+ messages in thread
From: Tristan Madani @ 2026-10-25 21:40 UTC (permalink / raw)
To: dmitry.torokhov, linux-input; +Cc: even.xu, xinpeng.sun, stable
The QuickI2C and QuickSPI ACPI helper functions copy firmware-returned
buffers into caller-provided structures without verifying the buffer
length. Malformed or short ACPI tables could cause an out-of-bounds
read from the firmware buffer, and oversized responses could overflow
the destination struct.
Additionally, quicki2c_acpi_get_dsd_property() does not validate the
returned ACPI object type before accessing buffer fields, and does not
free the allocated ACPI buffer on the success path, leaking memory on
every call.
Add a buf_size parameter to the ACPI helper functions and reject
responses larger than the destination buffer. Accept shorter responses
to handle firmware that returns buffers without struct tail padding
(e.g. ISUB tables returning 177 or 145 bytes for a 184-byte struct).
Zero-initialize caller stack structures so fields beyond the firmware
response length are deterministic. Add the missing type check and
kfree to the DSD helper.
Fixes: 5282e45ccbfa ("HID: intel-thc-hid: intel-quicki2c: Add THC QuickI2C ACPI interfaces")
Fixes: 7cb06f08ef13 ("HID: intel-thc-hid: intel-quickspi: Add THC QuickSPI ACPI interfaces")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
Changes in v3:
- Add missing @buf_size kernel-doc for all three ACPI helper functions
(quicki2c_acpi_get_dsm_property, quicki2c_acpi_get_dsd_property,
thc_acpi_get_property) to fix W=1 and scripts/kernel-doc warnings
Changes in v2:
- Use overflow-only check (>) instead of exact-match (!=) so firmware
returning shorter buffers (e.g. 177 or 145 bytes for 184-byte ISUB
struct, or 1 byte for 4-byte SPI opcode) is accepted
- Zero-initialize caller stack structures for deterministic behavior
with short firmware responses
- Add missing type validation and kfree in DSD helper
- Add braces per coding style
.../intel-quicki2c/pci-quicki2c.c | 42 ++++++++++++++-----
.../intel-quickspi/pci-quickspi.c | 37 +++++++++-------
2 files changed, 54 insertions(+), 25 deletions(-)
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
index 7a913f717efaad..b2246c6eaa98de 100644
--- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
+++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
@@ -56,13 +56,15 @@ static const struct acpi_gpio_mapping quicki2c_gpios[] = {
* @func: ACPI method's function number
* @type: ACPI parameter's data type
* @prop_buf: Point to return buffer
+ * @buf_size: Size of @prop_buf in bytes (0 to skip length check)
*
* This is a helper function for device to query its ACPI DSM parameters.
*
* Return: 0 if success or ENODEV on failure.
*/
static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t *guid,
- u64 rev, u64 func, acpi_object_type type, void *prop_buf)
+ u64 rev, u64 func, acpi_object_type type,
+ void *prop_buf, size_t buf_size)
{
acpi_handle handle = acpi_device_handle(adev);
union acpi_object *obj;
@@ -75,10 +77,15 @@ static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t
return -ENODEV;
}
- if (type == ACPI_TYPE_INTEGER)
+ if (type == ACPI_TYPE_INTEGER) {
*(u32 *)prop_buf = (u32)obj->integer.value;
- else if (type == ACPI_TYPE_BUFFER)
+ } else if (type == ACPI_TYPE_BUFFER) {
+ if (buf_size > 0 && obj->buffer.length > buf_size) {
+ ACPI_FREE(obj);
+ return -ENOSPC;
+ }
memcpy(prop_buf, obj->buffer.pointer, obj->buffer.length);
+ }
ACPI_FREE(obj);
@@ -91,13 +98,15 @@ static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const guid_t
* @dsd_method_name: ACPI method's property name
* @type: ACPI parameter's data type
* @prop_buf: Point to return buffer
+ * @buf_size: Size of @prop_buf in bytes (0 to skip length check)
*
* This is a helper function for device to query its ACPI DSD parameters.
*
* Return: 0 if success or ENODEV on failed.
*/
static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string dsd_method_name,
- acpi_object_type type, void *prop_buf)
+ acpi_object_type type, void *prop_buf,
+ size_t buf_size)
{
acpi_handle handle = acpi_device_handle(adev);
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -113,7 +122,16 @@ static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string
ret_obj = buffer.pointer;
+ if (ret_obj->type != type) {
+ kfree(buffer.pointer);
+ return -EINVAL;
+ }
+ if (buf_size > 0 && ret_obj->buffer.length > buf_size) {
+ kfree(buffer.pointer);
+ return -ENOSPC;
+ }
memcpy(prop_buf, ret_obj->buffer.pointer, ret_obj->buffer.length);
+ kfree(buffer.pointer);
return 0;
}
@@ -129,8 +147,8 @@ static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string
static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
{
struct acpi_device *adev = ACPI_COMPANION(qcdev->dev);
- struct quicki2c_subip_acpi_parameter i2c_param;
- struct quicki2c_subip_acpi_config i2c_config;
+ struct quicki2c_subip_acpi_parameter i2c_param = {};
+ struct quicki2c_subip_acpi_config i2c_config = {};
u32 hid_desc_addr;
int ret = -EINVAL;
@@ -145,7 +163,7 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
QUICKI2C_ACPI_REVISION_NUM,
QUICKI2C_ACPI_FUNC_NUM_HID_DESC_ADDR,
ACPI_TYPE_INTEGER,
- &hid_desc_addr);
+ &hid_desc_addr, 0);
if (ret)
return ret;
@@ -155,7 +173,7 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
QUICKI2C_ACPI_REVISION_NUM,
QUICKI2C_ACPI_FUNC_NUM_ACTIVE_LTR_VAL,
ACPI_TYPE_INTEGER,
- &qcdev->active_ltr_val);
+ &qcdev->active_ltr_val, 0);
if (ret)
return ret;
@@ -163,12 +181,13 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
QUICKI2C_ACPI_REVISION_NUM,
QUICKI2C_ACPI_FUNC_NUM_LP_LTR_VAL,
ACPI_TYPE_INTEGER,
- &qcdev->low_power_ltr_val);
+ &qcdev->low_power_ltr_val, 0);
if (ret)
return ret;
ret = quicki2c_acpi_get_dsd_property(adev, QUICKI2C_ACPI_METHOD_NAME_ICRS,
- ACPI_TYPE_BUFFER, &i2c_param);
+ ACPI_TYPE_BUFFER, &i2c_param,
+ sizeof(i2c_param));
if (ret)
return ret;
@@ -180,7 +199,8 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
qcdev->i2c_config.target_addr = i2c_param.device_address;
ret = quicki2c_acpi_get_dsd_property(adev, QUICKI2C_ACPI_METHOD_NAME_ISUB,
- ACPI_TYPE_BUFFER, &i2c_config);
+ ACPI_TYPE_BUFFER, &i2c_config,
+ sizeof(i2c_config));
if (ret)
return ret;
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 53023e30cf8d47..9b369d289fa81f 100644
--- a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
+++ b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
@@ -75,13 +75,15 @@ static const struct acpi_gpio_mapping quickspi_gpios[] = {
* @func: ACPI method's function number
* @type: ACPI parameter's data type
* @prop_buf: point to return buffer
+ * @buf_size: size of @prop_buf in bytes (0 to skip length check)
*
* This is a helper function for device to query its ACPI parameters.
*
* Return: 0 if successful or ENODEV on failed.
*/
static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid,
- u64 rev, u64 func, acpi_object_type type, void *prop_buf)
+ u64 rev, u64 func, acpi_object_type type,
+ void *prop_buf, size_t buf_size)
{
acpi_handle handle = acpi_device_handle(adev);
union acpi_object *obj;
@@ -94,10 +96,15 @@ static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid,
return -ENODEV;
}
- if (type == ACPI_TYPE_INTEGER)
+ if (type == ACPI_TYPE_INTEGER) {
*(u32 *)prop_buf = (u32)obj->integer.value;
- else if (type == ACPI_TYPE_BUFFER)
+ } else if (type == ACPI_TYPE_BUFFER) {
+ if (buf_size > 0 && obj->buffer.length > buf_size) {
+ ACPI_FREE(obj);
+ return -ENOSPC;
+ }
memcpy(prop_buf, obj->buffer.pointer, obj->buffer.length);
+ }
ACPI_FREE(obj);
@@ -129,7 +136,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_HDR_ADDR,
ACPI_TYPE_INTEGER,
- &qsdev->input_report_hdr_addr);
+ &qsdev->input_report_hdr_addr, 0);
if (ret)
return ret;
@@ -137,7 +144,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_BDY_ADDR,
ACPI_TYPE_INTEGER,
- &qsdev->input_report_bdy_addr);
+ &qsdev->input_report_bdy_addr, 0);
if (ret)
return ret;
@@ -145,7 +152,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_OUTPUT_REP_ADDR,
ACPI_TYPE_INTEGER,
- &qsdev->output_report_addr);
+ &qsdev->output_report_addr, 0);
if (ret)
return ret;
@@ -153,7 +160,8 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_READ_OPCODE,
ACPI_TYPE_BUFFER,
- &qsdev->spi_read_opcode);
+ &qsdev->spi_read_opcode,
+ sizeof(qsdev->spi_read_opcode));
if (ret)
return ret;
@@ -161,7 +169,8 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_WRITE_OPCODE,
ACPI_TYPE_BUFFER,
- &qsdev->spi_write_opcode);
+ &qsdev->spi_write_opcode,
+ sizeof(qsdev->spi_write_opcode));
if (ret)
return ret;
@@ -169,7 +178,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_IO_MODE,
ACPI_TYPE_INTEGER,
- &qsdev->spi_read_io_mode);
+ &qsdev->spi_read_io_mode, 0);
if (ret)
return ret;
@@ -184,7 +193,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_CONNECTION_SPEED,
ACPI_TYPE_INTEGER,
- &qsdev->spi_freq_val);
+ &qsdev->spi_freq_val, 0);
if (ret)
return ret;
@@ -192,7 +201,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_LIMIT_PACKET_SIZE,
ACPI_TYPE_INTEGER,
- &qsdev->limit_packet_size);
+ &qsdev->limit_packet_size, 0);
if (ret)
return ret;
@@ -205,7 +214,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_PERFORMANCE_LIMIT,
ACPI_TYPE_INTEGER,
- &qsdev->performance_limit);
+ &qsdev->performance_limit, 0);
if (ret)
return ret;
@@ -215,7 +224,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_ACTIVE_LTR,
ACPI_TYPE_INTEGER,
- &qsdev->active_ltr_val);
+ &qsdev->active_ltr_val, 0);
if (ret)
return ret;
@@ -223,7 +232,7 @@ static int quickspi_get_acpi_resources(struct quickspi_device *qsdev)
ACPI_QUICKSPI_REVISION_NUM,
ACPI_QUICKSPI_FUNC_NUM_LP_LTR,
ACPI_TYPE_INTEGER,
- &qsdev->low_power_ltr_val);
+ &qsdev->low_power_ltr_val, 0);
if (ret)
return ret;
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* RE: [PATCH v2] HID: intel-thc-hid: validate ACPI buffer length before memcpy
2026-10-25 15:47 ` [PATCH v2] HID: intel-thc-hid: validate ACPI buffer length before memcpy Tristan Madani
2026-10-25 15:57 ` sashiko-bot
@ 2026-10-26 2:02 ` Xu, Even
1 sibling, 0 replies; 7+ messages in thread
From: Xu, Even @ 2026-10-26 2:02 UTC (permalink / raw)
To: Tristan Madani, Sun, Xinpeng, jikos@kernel.org,
bentiss@kernel.org
Cc: srinivas.pandruvada@linux.intel.com, mpearson-lenovo@squebb.ca,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
Tristan Madani, stable@vger.kernel.org
> -----Original Message-----
> From: Tristan Madani <tristmd@gmail.com>
> Sent: Sunday, October 25, 2026 11:48 PM
> To: Xu, Even <even.xu@intel.com>; Sun, Xinpeng <xinpeng.sun@intel.com>;
> jikos@kernel.org; bentiss@kernel.org
> Cc: srinivas.pandruvada@linux.intel.com; mpearson-lenovo@squebb.ca; linux-
> input@vger.kernel.org; linux-kernel@vger.kernel.org; Tristan Madani
> <tristan@talencesecurity.com>; stable@vger.kernel.org
> Subject: [PATCH v2] HID: intel-thc-hid: validate ACPI buffer length before memcpy
>
> From: Tristan Madani <tristan@talencesecurity.com>
>
> The QuickI2C and QuickSPI ACPI helper functions copy firmware-returned buffers
> into caller-provided structures without verifying the buffer length. Malformed or
> short ACPI tables could cause an out-of-bounds read from the firmware buffer,
> and oversized responses could overflow the destination struct.
>
> Additionally, quicki2c_acpi_get_dsd_property() does not validate the returned
> ACPI object type before accessing buffer fields, and does not free the allocated
> ACPI buffer on the success path, leaking memory on every call.
>
> Add a buf_size parameter to the ACPI helper functions and reject responses
> larger than the destination buffer. Accept shorter responses to handle firmware
> that returns buffers without struct tail padding (e.g. ISUB tables returning 177 or
> 145 bytes for a 184-byte struct).
> Zero-initialize caller stack structures so fields beyond the firmware response
> length are deterministic. Add the missing type check and kfree to the DSD helper.
>
> Fixes: 5282e45ccbfa ("HID: intel-thc-hid: intel-quicki2c: Add THC QuickI2C ACPI
> interfaces")
> Fixes: 7cb06f08ef13 ("HID: intel-thc-hid: intel-quickspi: Add THC QuickSPI ACPI
> interfaces")
> Cc: stable@vger.kernel.org
> Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
> ---
> Changes in v2:
> - Use overflow-only check (>) instead of exact-match (!=) so firmware
> returning shorter buffers (e.g. 177 or 145 bytes for 184-byte ISUB
> struct, or 1 byte for 4-byte SPI opcode) is accepted
> - Zero-initialize caller stack structures for deterministic behavior
> with short firmware responses
> - Add missing type validation and kfree in DSD helper
> - Add braces per coding style
>
> .../intel-quicki2c/pci-quicki2c.c | 40 ++++++++++++++-----
> .../intel-quickspi/pci-quickspi.c | 36 ++++++++++-------
> 2 files changed, 51 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> index 7a913f717efaad..dd21864d16b05b 100644
> --- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> +++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> @@ -62,7 +62,8 @@ static const struct acpi_gpio_mapping quicki2c_gpios[] = {
> * Return: 0 if success or ENODEV on failure.
> */
> static int quicki2c_acpi_get_dsm_property(struct acpi_device *adev, const
> guid_t *guid,
> - u64 rev, u64 func, acpi_object_type
> type, void *prop_buf)
> + u64 rev, u64 func, acpi_object_type
> type,
> + void *prop_buf, size_t buf_size)
> {
> acpi_handle handle = acpi_device_handle(adev);
> union acpi_object *obj;
> @@ -75,10 +76,15 @@ static int quicki2c_acpi_get_dsm_property(struct
> acpi_device *adev, const guid_t
> return -ENODEV;
> }
>
> - if (type == ACPI_TYPE_INTEGER)
> + if (type == ACPI_TYPE_INTEGER) {
> *(u32 *)prop_buf = (u32)obj->integer.value;
> - else if (type == ACPI_TYPE_BUFFER)
> + } else if (type == ACPI_TYPE_BUFFER) {
> + if (buf_size > 0 && obj->buffer.length > buf_size) {
> + ACPI_FREE(obj);
> + return -ENOSPC;
> + }
> memcpy(prop_buf, obj->buffer.pointer, obj->buffer.length);
> + }
>
> ACPI_FREE(obj);
>
> @@ -97,7 +103,8 @@ static int quicki2c_acpi_get_dsm_property(struct
> acpi_device *adev, const guid_t
> * Return: 0 if success or ENODEV on failed.
> */
> static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string
> dsd_method_name,
> - acpi_object_type type, void
> *prop_buf)
> + acpi_object_type type, void *prop_buf,
> + size_t buf_size)
> {
> acpi_handle handle = acpi_device_handle(adev);
> struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -
> 113,7 +120,16 @@ static int quicki2c_acpi_get_dsd_property(struct acpi_device
> *adev, acpi_string
>
> ret_obj = buffer.pointer;
>
> + if (ret_obj->type != type) {
> + kfree(buffer.pointer);
> + return -EINVAL;
> + }
> + if (buf_size > 0 && ret_obj->buffer.length > buf_size) {
> + kfree(buffer.pointer);
> + return -ENOSPC;
> + }
> memcpy(prop_buf, ret_obj->buffer.pointer, ret_obj->buffer.length);
> + kfree(buffer.pointer);
>
> return 0;
> }
> @@ -129,8 +145,8 @@ static int quicki2c_acpi_get_dsd_property(struct
> acpi_device *adev, acpi_string static int quicki2c_get_acpi_resources(struct
> quicki2c_device *qcdev) {
> struct acpi_device *adev = ACPI_COMPANION(qcdev->dev);
> - struct quicki2c_subip_acpi_parameter i2c_param;
> - struct quicki2c_subip_acpi_config i2c_config;
> + struct quicki2c_subip_acpi_parameter i2c_param = {};
> + struct quicki2c_subip_acpi_config i2c_config = {};
> u32 hid_desc_addr;
> int ret = -EINVAL;
>
> @@ -145,7 +161,7 @@ static int quicki2c_get_acpi_resources(struct
> quicki2c_device *qcdev)
> QUICKI2C_ACPI_REVISION_NUM,
>
> QUICKI2C_ACPI_FUNC_NUM_HID_DESC_ADDR,
> ACPI_TYPE_INTEGER,
> - &hid_desc_addr);
> + &hid_desc_addr, 0);
> if (ret)
> return ret;
>
> @@ -155,7 +171,7 @@ static int quicki2c_get_acpi_resources(struct
> quicki2c_device *qcdev)
> QUICKI2C_ACPI_REVISION_NUM,
>
> QUICKI2C_ACPI_FUNC_NUM_ACTIVE_LTR_VAL,
> ACPI_TYPE_INTEGER,
> - &qcdev->active_ltr_val);
> + &qcdev->active_ltr_val, 0);
> if (ret)
> return ret;
>
> @@ -163,12 +179,13 @@ static int quicki2c_get_acpi_resources(struct
> quicki2c_device *qcdev)
> QUICKI2C_ACPI_REVISION_NUM,
>
> QUICKI2C_ACPI_FUNC_NUM_LP_LTR_VAL,
> ACPI_TYPE_INTEGER,
> - &qcdev->low_power_ltr_val);
> + &qcdev->low_power_ltr_val, 0);
> if (ret)
> return ret;
>
> ret = quicki2c_acpi_get_dsd_property(adev,
> QUICKI2C_ACPI_METHOD_NAME_ICRS,
> - ACPI_TYPE_BUFFER, &i2c_param);
> + ACPI_TYPE_BUFFER, &i2c_param,
> + sizeof(i2c_param));
> if (ret)
> return ret;
>
> @@ -180,7 +197,8 @@ static int quicki2c_get_acpi_resources(struct
> quicki2c_device *qcdev)
> qcdev->i2c_config.target_addr = i2c_param.device_address;
>
> ret = quicki2c_acpi_get_dsd_property(adev,
> QUICKI2C_ACPI_METHOD_NAME_ISUB,
> - ACPI_TYPE_BUFFER, &i2c_config);
> + ACPI_TYPE_BUFFER, &i2c_config,
> + sizeof(i2c_config));
> if (ret)
> return ret;
>
> 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 53023e30cf8d47..e4331ba4e503d9 100644
> --- a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> +++ b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> @@ -81,7 +81,8 @@ static const struct acpi_gpio_mapping quickspi_gpios[] = {
> * Return: 0 if successful or ENODEV on failed.
> */
> static int thc_acpi_get_property(struct acpi_device *adev, const guid_t *guid,
> - u64 rev, u64 func, acpi_object_type type, void
> *prop_buf)
> + u64 rev, u64 func, acpi_object_type type,
> + void *prop_buf, size_t buf_size)
> {
> acpi_handle handle = acpi_device_handle(adev);
> union acpi_object *obj;
> @@ -94,10 +95,15 @@ static int thc_acpi_get_property(struct acpi_device
> *adev, const guid_t *guid,
> return -ENODEV;
> }
>
> - if (type == ACPI_TYPE_INTEGER)
> + if (type == ACPI_TYPE_INTEGER) {
> *(u32 *)prop_buf = (u32)obj->integer.value;
> - else if (type == ACPI_TYPE_BUFFER)
> + } else if (type == ACPI_TYPE_BUFFER) {
> + if (buf_size > 0 && obj->buffer.length > buf_size) {
> + ACPI_FREE(obj);
> + return -ENOSPC;
> + }
> memcpy(prop_buf, obj->buffer.pointer, obj->buffer.length);
> + }
>
> ACPI_FREE(obj);
>
> @@ -129,7 +135,7 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
>
> ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_HDR_ADDR,
> ACPI_TYPE_INTEGER,
> - &qsdev->input_report_hdr_addr);
> + &qsdev->input_report_hdr_addr, 0);
> if (ret)
> return ret;
>
> @@ -137,7 +143,7 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
>
> ACPI_QUICKSPI_FUNC_NUM_INPUT_REP_BDY_ADDR,
> ACPI_TYPE_INTEGER,
> - &qsdev->input_report_bdy_addr);
> + &qsdev->input_report_bdy_addr, 0);
> if (ret)
> return ret;
>
> @@ -145,7 +151,7 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
>
> ACPI_QUICKSPI_FUNC_NUM_OUTPUT_REP_ADDR,
> ACPI_TYPE_INTEGER,
> - &qsdev->output_report_addr);
> + &qsdev->output_report_addr, 0);
> if (ret)
> return ret;
>
> @@ -153,7 +159,8 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
>
> ACPI_QUICKSPI_FUNC_NUM_READ_OPCODE,
> ACPI_TYPE_BUFFER,
> - &qsdev->spi_read_opcode);
> + &qsdev->spi_read_opcode,
> + sizeof(qsdev->spi_read_opcode));
> if (ret)
> return ret;
>
> @@ -161,7 +168,8 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
>
> ACPI_QUICKSPI_FUNC_NUM_WRITE_OPCODE,
> ACPI_TYPE_BUFFER,
> - &qsdev->spi_write_opcode);
> + &qsdev->spi_write_opcode,
> + sizeof(qsdev->spi_write_opcode));
> if (ret)
> return ret;
>
> @@ -169,7 +177,7 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
> ACPI_QUICKSPI_FUNC_NUM_IO_MODE,
> ACPI_TYPE_INTEGER,
> - &qsdev->spi_read_io_mode);
> + &qsdev->spi_read_io_mode, 0);
> if (ret)
> return ret;
>
> @@ -184,7 +192,7 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
>
> ACPI_QUICKSPI_FUNC_NUM_CONNECTION_SPEED,
> ACPI_TYPE_INTEGER,
> - &qsdev->spi_freq_val);
> + &qsdev->spi_freq_val, 0);
> if (ret)
> return ret;
>
> @@ -192,7 +200,7 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
>
> ACPI_QUICKSPI_FUNC_NUM_LIMIT_PACKET_SIZE,
> ACPI_TYPE_INTEGER,
> - &qsdev->limit_packet_size);
> + &qsdev->limit_packet_size, 0);
> if (ret)
> return ret;
>
> @@ -205,7 +213,7 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
>
> ACPI_QUICKSPI_FUNC_NUM_PERFORMANCE_LIMIT,
> ACPI_TYPE_INTEGER,
> - &qsdev->performance_limit);
> + &qsdev->performance_limit, 0);
> if (ret)
> return ret;
>
> @@ -215,7 +223,7 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
> ACPI_QUICKSPI_FUNC_NUM_ACTIVE_LTR,
> ACPI_TYPE_INTEGER,
> - &qsdev->active_ltr_val);
> + &qsdev->active_ltr_val, 0);
> if (ret)
> return ret;
>
> @@ -223,7 +231,7 @@ static int quickspi_get_acpi_resources(struct
> quickspi_device *qsdev)
> ACPI_QUICKSPI_REVISION_NUM,
> ACPI_QUICKSPI_FUNC_NUM_LP_LTR,
> ACPI_TYPE_INTEGER,
> - &qsdev->low_power_ltr_val);
> + &qsdev->low_power_ltr_val, 0);
> if (ret)
> return ret;
>
Thanks for your patch!
It will be better if you can split it into two separate patches (One for QuickSPI, one for QuickI2C).
Reviewed-by: Even Xu <even.xu@intel.com>
> --
> 2.47.3
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-26 2:02 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-24 20:58 [PATCH] HID: intel-thc-hid: validate ACPI buffer length before use Tristan Madani
2026-10-24 21:35 ` sashiko-bot
2026-10-25 10:49 ` kernel test robot
2026-10-25 15:47 ` [PATCH v2] HID: intel-thc-hid: validate ACPI buffer length before memcpy Tristan Madani
2026-10-25 15:57 ` sashiko-bot
2026-10-26 2:02 ` Xu, Even
2026-10-25 21:40 ` [PATCH v3] " Tristan Madani
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox