:: commit 1fa4c96bb7213f3ebec142c65b0046fd44421e2f

Mintsuki <mintsuki@protonmail.com> — 2025-12-26 10:33

parents: 5fcaaff029

lib/acpi: Add RSDT/XSDT length validation

diff --git a/common/lib/acpi.c b/common/lib/acpi.c
index ac7c94da..fd134f51 100644
--- a/common/lib/acpi.c
+++ b/common/lib/acpi.c
@@ -218,8 +218,18 @@ void *acpi_get_table(const char *signature, int index) {
     else
         rsdt = (struct rsdt *)(uintptr_t)rsdp->rsdt_addr;
 
-    size_t entry_count =
-        (rsdt->header.length - sizeof(struct sdt)) / (use_xsdt ? 8 : 4);
+    if (rsdt == NULL) {
+        return NULL;
+    }
+
+    // Validate RSDT/XSDT header length
+    if (rsdt->header.length < sizeof(struct sdt)) {
+        printv("acpi: Invalid %s header length\n", use_xsdt ? "XSDT" : "RSDT");
+        return NULL;
+    }
+
+    size_t entry_size = use_xsdt ? 8 : 4;
+    size_t entry_count = (rsdt->header.length - sizeof(struct sdt)) / entry_size;
 
     for (size_t i = 0; i < entry_count; i++) {
         struct sdt *ptr;
@@ -277,6 +287,9 @@ void acpi_map_tables(void) {
     }
 
     struct rsdt *xsdt = (void *)(uintptr_t)rsdp->xsdt_addr;
+    if (xsdt->header.length < sizeof(struct sdt)) {
+        goto no_xsdt;
+    }
     size_t xsdt_entry_count = (xsdt->header.length - sizeof(struct sdt)) / 8;
 
     map_single_table((uintptr_t)xsdt, (uint32_t)-1);
@@ -293,6 +306,9 @@ no_xsdt:;
     }
 
     struct rsdt *rsdt = (void *)(uintptr_t)rsdp->rsdt_addr;
+    if (rsdt->header.length < sizeof(struct sdt)) {
+        goto no_rsdt;
+    }
     size_t rsdt_entry_count = (rsdt->header.length - sizeof(struct sdt)) / 4;
 
     map_single_table((uintptr_t)rsdt, (uint32_t)-1);
tab: 248 wrap: offon