* [PATCH] ACPI: processor: validate CPU mapping entries
@ 2026-10-16 14:14 Jiale Yao
2026-10-17 7:33 ` jiale yao
0 siblings, 1 reply; 2+ messages in thread
From: Jiale Yao @ 2026-10-16 14:14 UTC (permalink / raw)
To: Rafael J. Wysocki, Len Brown, linux-acpi, linux-kernel; +Cc: Jiale Yao
CPU physical ID lookup walks MADT subtables directly and also accepts
records returned by _MAT. Both paths can pass a truncated typed record
to a CPU-specific mapper, and the MADT walker can be stalled or moved
outside the table by an invalid length.
Validate generic record bounds and the minimum size required by each
supported CPU record before dispatching it on both provider paths.
Signed-off-by: Jiale Yao <yaojiale02@163.com>
---
drivers/acpi/processor_core.c | 48 ++++++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 3bf076c150fa..4d5ff53f27ab 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -157,6 +157,47 @@ static int map_core_pic_id(struct acpi_subtable_header *entry,
return -EINVAL;
}
+static bool madt_cpu_entry_is_valid(struct acpi_subtable_header *entry,
+ unsigned long end)
+{
+ unsigned long start = (unsigned long)entry;
+ size_t length, min_length;
+
+ if (start >= end || end - start < sizeof(*entry))
+ return false;
+
+ length = entry->length;
+ if (length < sizeof(*entry) || length > end - start)
+ return false;
+
+ switch (entry->type) {
+ case ACPI_MADT_TYPE_LOCAL_APIC:
+ min_length = sizeof(struct acpi_madt_local_apic);
+ break;
+ case ACPI_MADT_TYPE_LOCAL_X2APIC:
+ min_length = sizeof(struct acpi_madt_local_x2apic);
+ break;
+ case ACPI_MADT_TYPE_LOCAL_SAPIC:
+ min_length = sizeof(struct acpi_madt_local_sapic);
+ break;
+ case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+ min_length = offsetofend(struct acpi_madt_generic_interrupt,
+ arm_mpidr);
+ break;
+ case ACPI_MADT_TYPE_RINTC:
+ min_length = offsetofend(struct acpi_madt_rintc, uid);
+ break;
+ case ACPI_MADT_TYPE_CORE_PIC:
+ min_length = sizeof(struct acpi_madt_core_pic);
+ break;
+ default:
+ min_length = sizeof(*entry);
+ break;
+ }
+
+ return length >= min_length;
+}
+
static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
int type, u32 acpi_id)
{
@@ -172,7 +213,8 @@ static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
/* Parse all entries looking for a match. */
entry += sizeof(struct acpi_table_madt);
- while (entry + sizeof(struct acpi_subtable_header) < madt_end) {
+ while (madt_cpu_entry_is_valid((struct acpi_subtable_header *)entry,
+ madt_end)) {
struct acpi_subtable_header *header =
(struct acpi_subtable_header *)entry;
if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
@@ -251,6 +293,10 @@ static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
}
header = (struct acpi_subtable_header *)obj->buffer.pointer;
+ if (!madt_cpu_entry_is_valid(header,
+ (unsigned long)header + obj->buffer.length))
+ goto exit;
+
if (header->type == ACPI_MADT_TYPE_LOCAL_APIC)
map_lapic_id(header, acpi_id, &phys_id);
else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC)
--
2.34.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re:[PATCH] ACPI: processor: validate CPU mapping entries
2026-10-16 14:14 [PATCH] ACPI: processor: validate CPU mapping entries Jiale Yao
@ 2026-10-17 7:33 ` jiale yao
0 siblings, 0 replies; 2+ messages in thread
From: jiale yao @ 2026-10-17 7:33 UTC (permalink / raw)
To: Rafael J. Wysocki, Len Brown, linux-acpi, linux-kernel
At 2026-10-16 22:14:40, "Jiale Yao" <yaojiale02@163.com> wrote:
>CPU physical ID lookup walks MADT subtables directly and also accepts
>records returned by _MAT. Both paths can pass a truncated typed record
>to a CPU-specific mapper, and the MADT walker can be stalled or moved
>outside the table by an invalid length.
>
>Validate generic record bounds and the minimum size required by each
>supported CPU record before dispatching it on both provider paths.
>
Fixes: 78ed8bd2944b ("ACPI: processor: move acpi_get_cpuid into processor_core.c")
>Signed-off-by: Jiale Yao <yaojiale02@163.com>
>---
> drivers/acpi/processor_core.c | 48 ++++++++++++++++++++++++++++++++++-
> 1 file changed, 47 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
>index 3bf076c150fa..4d5ff53f27ab 100644
>--- a/drivers/acpi/processor_core.c
>+++ b/drivers/acpi/processor_core.c
>@@ -157,6 +157,47 @@ static int map_core_pic_id(struct acpi_subtable_header *entry,
> return -EINVAL;
> }
>
>+static bool madt_cpu_entry_is_valid(struct acpi_subtable_header *entry,
>+ unsigned long end)
>+{
>+ unsigned long start = (unsigned long)entry;
>+ size_t length, min_length;
>+
>+ if (start >= end || end - start < sizeof(*entry))
>+ return false;
>+
>+ length = entry->length;
>+ if (length < sizeof(*entry) || length > end - start)
>+ return false;
>+
>+ switch (entry->type) {
>+ case ACPI_MADT_TYPE_LOCAL_APIC:
>+ min_length = sizeof(struct acpi_madt_local_apic);
>+ break;
>+ case ACPI_MADT_TYPE_LOCAL_X2APIC:
>+ min_length = sizeof(struct acpi_madt_local_x2apic);
>+ break;
>+ case ACPI_MADT_TYPE_LOCAL_SAPIC:
>+ min_length = sizeof(struct acpi_madt_local_sapic);
>+ break;
>+ case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
>+ min_length = offsetofend(struct acpi_madt_generic_interrupt,
>+ arm_mpidr);
>+ break;
>+ case ACPI_MADT_TYPE_RINTC:
>+ min_length = offsetofend(struct acpi_madt_rintc, uid);
>+ break;
>+ case ACPI_MADT_TYPE_CORE_PIC:
>+ min_length = sizeof(struct acpi_madt_core_pic);
>+ break;
>+ default:
>+ min_length = sizeof(*entry);
>+ break;
>+ }
>+
>+ return length >= min_length;
>+}
>+
> static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
> int type, u32 acpi_id)
> {
>@@ -172,7 +213,8 @@ static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
> /* Parse all entries looking for a match. */
>
> entry += sizeof(struct acpi_table_madt);
>- while (entry + sizeof(struct acpi_subtable_header) < madt_end) {
>+ while (madt_cpu_entry_is_valid((struct acpi_subtable_header *)entry,
>+ madt_end)) {
> struct acpi_subtable_header *header =
> (struct acpi_subtable_header *)entry;
> if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
>@@ -251,6 +293,10 @@ static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
> }
>
> header = (struct acpi_subtable_header *)obj->buffer.pointer;
>+ if (!madt_cpu_entry_is_valid(header,
>+ (unsigned long)header + obj->buffer.length))
>+ goto exit;
>+
> if (header->type == ACPI_MADT_TYPE_LOCAL_APIC)
> map_lapic_id(header, acpi_id, &phys_id);
> else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC)
>--
>2.34.1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-17 7:33 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-16 14:14 [PATCH] ACPI: processor: validate CPU mapping entries Jiale Yao
2026-10-17 7:33 ` jiale yao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®