[PATCH] iommu: amd: Validate the IVMD length before walking by it

From: Shirong Zhao

Date: Mon Oct 12 2026 - 05:17:01 EST


init_memory_definitions() steps through the IVMD entries at the end of the
IVRS table by m->length, a u16 read straight out of the table, and nothing
constrains it.

A zero length leaves p where it is and the loop never ends. A length
shorter than the IVMD header steps through table payload one byte at a
time and reinterprets it as IVMD entries, and each one that carries
IVMD_FLAG_UNITY_MAP or IVMD_FLAG_EXCL_RANGE is handed to
init_unity_map_range(), which is what sets up the IOMMU unity mapping.

Require the length to cover the header, which is what IVRS already
specifies for an IVMD entry, and use FW_BUG as the rest of this file does
for malformed IVRS content.

Checked against torvalds/linux at HEAD; the file is unmodified there.

Found by EFSM.R17, which reports a loop whose cursor advances by a step
memory can supply as zero while the exit condition depends on that cursor.
Signed-off-by: Shirong Zhao <shxzhaosr@xxxxxxx>

---
drivers/iommu/amd/init.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 8a410d4..d446abc 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -2702,6 +2702,10 @@ static int __init init_memory_definitions(struct acpi_table_header *table)

while (p < end) {
m = (struct ivmd_header *)p;
+ if (m->length < sizeof(*m)) {
+ pr_warn(FW_BUG "Invalid IVMD length %u\n", m->length);
+ break;
+ }
if (m->flags & (IVMD_FLAG_UNITY_MAP | IVMD_FLAG_EXCL_RANGE))
init_unity_map_range(m, table);