[PATCH v2 00/20] ACPI/irqchip: validate MADT entries before use

Jiale Yao yaojiale02 at 163.com
Wed Oct 28 20:52:31 PDT 2026


ACPI interrupt-controller setup passes firmware-supplied MADT subtables
to architecture and irqchip callbacks.  The common table walker only
guarantees that a generic subtable header is readable.  A number of
callbacks cast that header to a larger controller-specific structure and
read typed fields before checking that the complete record is present.
Truncated records can therefore cause out-of-bounds reads during early
CPU and interrupt-controller discovery.

This series combines the previously posted generic/irqchip series [1],
the RISC-V series [2], and the remaining MADT callback checks into one
set.  The common irqchip probe path first rejects entries whose declared
range leaves the table.  Each parser then validates the minimum size of
the concrete record before its first typed access.

Testing
=======

The RISC-V cases were tested with qemu-system-riscv64, EDK2 pflash
firmware, a KASAN-enabled kernel, CONFIG_ACPI_TABLE_UPGRADE=y, and an
uncompressed initramfs containing an overriding MADT.  The malformed
table is one page long and ends with a three-byte RINTC entry, while a
complete struct acpi_madt_rintc is 36 bytes.

On an unpatched kernel the override was accepted and setup_smp() faulted
in acpi_parse_rintc() while reading processor->flags four bytes from the
start of the truncated record.  The record starts three bytes before the
end of the mapped page, so that read entered the following unmapped page:

  Unable to handle kernel paging request
  epc : acpi_parse_rintc+0x46/0x206
  cause: 000000000000000d
  Kernel panic - not syncing: Attempted to kill the idle task!

Applying only the old arch/riscv/kernel/acpi.c and
drivers/irqchip/irq-riscv-intc.c checks produced the same fault because
the setup_smp() parser runs first.  With patch 7 moving the existing
BAD_MADT_ENTRY() check before the flags read, plus patches 9 and 20, the
out-of-bounds access disappeared.  The malformed table was rejected and
the kernel later stopped at the existing acpi_init_rintc_map() BUG for a
machine with no valid RINTC entries.  This is the current fail-closed
behavior; it is not an out-of-bounds access.

The LoongArch LPC-PIC case was exercised with an overriding MADT ending
in a three-byte LPC-PIC entry.  Temporary diagnostic instrumentation in
pch_lpc_parse_madt() reported:

  decl_len=3 sizeof=14 beyond_end=11

This confirms the field accesses covered by patch 19 extend eleven bytes
beyond the supplied record.  LoongArch maps this early table directly,
so the read did not itself cause a page fault.

Dynamic test coverage by patch is therefore:

  7       RISC-V RINTC fault reproduced; the early check prevents it.
  9       The malformed RINTC is rejected in acpi_init_rintc_map().
  19      LoongArch LPC-PIC over-read observed with instrumentation.
  20      Included in the complete RINTC fix; the boot stops at the
          existing fail-closed BUG before irqchip probing reaches it.
  1-6,
  8,
  10-18 No dynamic claim.  The required GICv5, AVEC, redirect-int,
          HTVEC, and related controller models are not available in the
          QEMU configurations used for this test.

All twenty patches were checked with scripts/checkpatch.pl and were
applied both individually where independent and as the complete series
to the base commit below.

Changes in v2:
- Combine and supersede the six-patch irqchip series [1], the two-patch
  RISC-V series [2], and the remaining MADT checks.
- Add the RISC-V QEMU/EDK2 truncated-RINTC reproduction and fixed-kernel
  result.
- Retain the setup_smp() RINTC fix: testing showed that the later RISC-V
  checks alone do not prevent the early boot fault.
- Document the LoongArch LPC-PIC instrumentation result and the QEMU
  hardware-model limitations for the other callbacks.
- Rebase on the current tree and keep Fixes and stable trailers on every
  patch.

[1] https://lore.kernel.org/r/20261021144524.364143-1-yaojiale02@163.com
[2] https://lore.kernel.org/r/20261016141249.2791819-1-yaojiale02@163.com

Jiale Yao (20):
  ACPI: irqchip: validate MADT entry bounds before probing
  irqchip/gic-v3-its: validate MADT ITS entries
  irqchip/gic-v3: validate MADT records before use
  irqchip/gic-v5-its: validate MADT translate frames
  irqchip/loongarch-cpu: validate MADT LIO-PIC entries
  irqchip/loongson-eiointc: validate MADT BIO-PIC entries
  riscv: validate RINTC entries before use
  ACPI: riscv: validate interrupt controller MADT entries
  riscv: acpi: validate RINTC entries before use
  irqchip/gic-v5-irs: validate MADT GICC entries
  irqchip/gic-v5-irs: validate MADT IRS entries
  irqchip/gic-v5: validate MADT IRS records
  irqchip/gic: validate MADT distributor records
  irqchip/loongarch-avec: validate MADT MSI-PIC entries
  irqchip/loongarch-ir: validate MADT MSI-PIC entries
  irqchip/loongson-htvec: validate MADT BIO-PIC entries
  irqchip/loongson-htvec: validate MADT MSI-PIC entries
  irqchip/loongson-liointc: validate MADT HT-PIC entries
  irqchip/loongson-pch-pic: validate MADT LPC-PIC entries
  irqchip/riscv-intc: validate MADT RINTC entries

 arch/riscv/kernel/acpi.c               |  3 +++
 arch/riscv/kernel/smpboot.c            |  6 +++---
 drivers/acpi/riscv/irq.c               |  6 ++++++
 drivers/acpi/scan.c                    |  7 +++++++
 drivers/irqchip/irq-gic-v3-its.c       |  3 +++
 drivers/irqchip/irq-gic-v3.c           | 15 +++++++++++++++
 drivers/irqchip/irq-gic-v5-irs.c       |  6 ++++++
 drivers/irqchip/irq-gic-v5-its.c       |  3 +++
 drivers/irqchip/irq-gic-v5.c           |  3 +++
 drivers/irqchip/irq-gic.c              |  3 +++
 drivers/irqchip/irq-loongarch-avec.c   |  3 +++
 drivers/irqchip/irq-loongarch-cpu.c    |  3 +++
 drivers/irqchip/irq-loongarch-ir.c     |  3 +++
 drivers/irqchip/irq-loongson-eiointc.c | 10 ++++++++--
 drivers/irqchip/irq-loongson-htvec.c   |  6 ++++++
 drivers/irqchip/irq-loongson-liointc.c |  3 +++
 drivers/irqchip/irq-loongson-pch-pic.c |  3 +++
 drivers/irqchip/irq-riscv-intc.c       |  5 ++++-
 18 files changed, 85 insertions(+), 6 deletions(-)

base-commit: 65ba8f34ec886ec72b2c07ddc8cf3d815c32869d
-- 
2.34.1




More information about the linux-arm-kernel mailing list