Re: [PATCH] ACPI: APMT: validate node bounds before device registration
Hanjun Guo <[email protected]>
| Newsgroups | org.kernel.vger.linux-acpi,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> > --- > 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