Re: [PATCH] ACPI: APMT: validate node bounds before device registration

From: Hanjun Guo

Date: Fri Jul 17 2026 - 02:51:47 EST


Hi Pengpeng,

On 2026/7/6 17:38, Pengpeng Hou wrote:
The APMT parser walks variable-length nodes from the ACPI table and
passes each node pointer to the platform device that is later consumed by
the Arm Coresight PMU driver. The loop only checked that the node start
was before the table end before reading the full struct acpi_apmt_node and
advancing by node->length.

Validate the fixed node body and the declared node length before using the
node. This keeps malformed short nodes from being consumed locally or
propagated to the runtime PMU driver as platform data.

Signed-off-by: Pengpeng Hou <pengpeng@xxxxxxxxxxx>
---
drivers/acpi/arm64/apmt.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/drivers/acpi/arm64/apmt.c b/drivers/acpi/arm64/apmt.c
index bb010f6164e5..5f341fa86fab 100644
--- a/drivers/acpi/arm64/apmt.c
+++ b/drivers/acpi/arm64/apmt.c
@@ -23,6 +23,21 @@
/* Root pointer to the mapped APMT table */
static struct acpi_table_header *apmt_table;
+static bool __init apmt_node_valid(struct acpi_table_apmt *apmt, u64 offset,
+ u64 end)
+{
+ struct acpi_apmt_node *node;
+
+ if (offset > end || end - offset < sizeof(*node))
+ return false;
+
+ node = ACPI_ADD_PTR(struct acpi_apmt_node, apmt, offset);
+ if (node->length < sizeof(*node))
+ return false;
+
+ return node->length <= end - offset;
+}
+
static int __init apmt_init_resources(struct resource *res,
struct acpi_apmt_node *node)
{
@@ -129,8 +144,13 @@ static int __init apmt_init_platform_devices(void)
apmt = (struct acpi_table_apmt *)apmt_table;
offset = sizeof(*apmt);
end = apmt->header.length;
+ if (end < sizeof(*apmt))
+ return -EINVAL;

This means the firmware reports the wrong length of the ACPI table, it's
better to print FW_BUG here.

It's a rare case because the APMT is not work at all if the length
is less than size of the head.

while (offset < end) {
+ if (!apmt_node_valid(apmt, offset, end))
+ return -EINVAL;
Do you have the real bad case? or can you trigger it?

Thanks
Hanjun