Re:[PATCH] x86/boot: validate SRAT subtables before parsing
From: jiale yao
Date: Sat Oct 17 2026 - 03:33:40 EST
At 2026-10-16 22:14:24, "Jiale Yao" <yaojiale02@xxxxxxx> wrote:
>The compressed boot SRAT walker only rejects zero-length subtables. It
>can advance beyond the table or read memory-affinity fields from a
>truncated record when firmware supplies an invalid length.
>
>Validate the SRAT header, each generic subtable range, and the fixed
>memory-affinity record before accessing typed fields.
>
Fixes: 02a3e3cdb7f1 ("x86/boot: Parse SRAT table and count immovable memory regions")
>Signed-off-by: Jiale Yao <yaojiale02@xxxxxxx>
>---
> arch/x86/boot/compressed/acpi.c | 19 ++++++++++++++++---
> 1 file changed, 16 insertions(+), 3 deletions(-)
>
>diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
>index aed27604c11f..310ddb9243b8 100644
>--- a/arch/x86/boot/compressed/acpi.c
>+++ b/arch/x86/boot/compressed/acpi.c
>@@ -289,14 +289,22 @@ int count_immovable_mem_regions(void)
> return 0;
>
> table_header = (struct acpi_table_header *)table_addr;
>+ if (table_header->length < sizeof(struct acpi_table_srat))
>+ return 0;
>+
> table_end = table_addr + table_header->length;
> table = table_addr + sizeof(struct acpi_table_srat);
>
>- while (table + sizeof(struct acpi_subtable_header) < table_end) {
>+ while (table < table_end) {
>+ if (table_end - table < sizeof(struct acpi_subtable_header)) {
>+ debug_putstr("Invalid truncated SRAT subtable header.\n");
>+ return 0;
>+ }
>
> sub_table = (struct acpi_subtable_header *)table;
>- if (!sub_table->length) {
>- debug_putstr("Invalid zero length SRAT subtable.\n");
>+ if (sub_table->length < sizeof(*sub_table) ||
>+ sub_table->length > table_end - table) {
>+ debug_putstr("Invalid SRAT subtable length.\n");
> return 0;
> }
>
>@@ -304,6 +312,11 @@ int count_immovable_mem_regions(void)
> struct acpi_srat_mem_affinity *ma;
>
> ma = (struct acpi_srat_mem_affinity *)sub_table;
>+ if (sub_table->length < sizeof(*ma)) {
>+ debug_putstr("Invalid memory affinity subtable.\n");
>+ return 0;
>+ }
>+
> if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && ma->length) {
> immovable_mem[num].start = ma->base_address;
> immovable_mem[num].size = ma->length;
>--
>2.34.1