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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.