[PATCH v1 09/30] ACPICA: executer: Add bounds checking for PCC field read access

From: Pawel Chmielewski

Date: Tue Oct 20 2026 - 10:17:12 EST


From: ikaros <void0red@xxxxxxxxx>

Add validation in AcpiExReadDataFromField to ensure that PCC field
reads do not exceed the bounds of the InternalPccBuffer. Check for
a NULL buffer pointer and verify that BaseByteOffset + field byte
length does not exceed Region.Length.

Link: https://github.com/acpica/acpica/commit/661d2310fd25
Closes: https://github.com/open-acpica/acpica/issues/1165
Signed-off-by: ikaros <void0red@xxxxxxxxx>
Signed-off-by: Pawel Chmielewski <pawel.chmielewski@xxxxxxxxx>
---
drivers/acpi/acpica/exfield.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index 9a55524ed8f4..b9da19ffcd3e 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -208,12 +208,32 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"PCC FieldRead bits %u\n",
obj_desc->field.bit_length));
+ /*
+ * Ensure the field access does not exceed the bounds of the
+ * internal_pcc_buffer. The buffer is allocated with the region length,
+ * so verify that base_byte_offset + field byte length <= Region.Length.
+ */
+ if (!obj_desc->field.region_obj->field.internal_pcc_buffer) {
+ status = AE_AML_NO_OPERAND;
+ goto exit;
+ }

+ buffer_length = (acpi_size)ACPI_ROUND_BITS_UP_TO_BYTES(
+ obj_desc->field.bit_length);
+ if (obj_desc->field.base_byte_offset + buffer_length >
+ obj_desc->field.region_obj->region.length) {
+ ACPI_ERROR((
+ AE_INFO,
+ "PCC field at offset %u length %u exceeds region size %u",
+ obj_desc->field.base_byte_offset, buffer_length,
+ obj_desc->field.region_obj->region.length));
+ status = AE_AML_BUFFER_LIMIT;
+ goto exit;
+ }
memcpy(buffer,
obj_desc->field.region_obj->field.internal_pcc_buffer +
obj_desc->field.base_byte_offset,
- (acpi_size)ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.
- bit_length));
+ buffer_length);

*ret_buffer_desc = buffer_desc;
return AE_OK;
--
2.50.1