From 756f5985b5e4ca0b08e60fff36ef3c51fb79de75 Mon Sep 17 00:00:00 2001 From: Fabian Ruhland Date: Fri, 11 Oct 2024 14:27:53 +0200 Subject: [PATCH] config_tables: Skip ACPI entries with invalid RSDP version --- towboot/src/boot/config_tables.rs | 58 ++++++++++++++++++------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/towboot/src/boot/config_tables.rs b/towboot/src/boot/config_tables.rs index 1cd32d5..017626e 100644 --- a/towboot/src/boot/config_tables.rs +++ b/towboot/src/boot/config_tables.rs @@ -14,8 +14,6 @@ use uefi::table::cfg::{ SMBIOS3_GUID, }; -static mut RSDP_V2_SET: bool = false; - /// Go through all of the configuration tables. /// Some of them are interesting for Multiboot2. pub(super) fn parse_for_multiboot(info_builder: &mut InfoBuilder) { @@ -27,8 +25,8 @@ pub(super) fn parse_for_multiboot(info_builder: &mut InfoBuilder) { debug!("going through configuration tables..."); for table in config_tables { match table.guid { - ACPI_GUID => handle_acpi(&table, info_builder), - ACPI2_GUID => handle_acpi(&table, info_builder), + ACPI_GUID => handle_acpi_v1(&table, info_builder), + ACPI2_GUID => handle_acpi_v2(&table, info_builder), DEBUG_IMAGE_INFO_GUID => debug!("ignoring image debug info"), DXE_SERVICES_GUID => debug!("ignoring dxe services table"), HAND_OFF_BLOCK_LIST_GUID => debug!("ignoring hand-off block list"), @@ -42,33 +40,45 @@ pub(super) fn parse_for_multiboot(info_builder: &mut InfoBuilder) { } } -/// Parse the ACPI RSDP and create the Multiboot struct for it. -fn handle_acpi(table: &ConfigTableEntry, info_builder: &mut InfoBuilder) { - debug!("handling ACPI RSDP"); +/// Parse the ACPI RSDP version 1 and create the Multiboot struct for it. +fn handle_acpi_v1(table: &ConfigTableEntry, info_builder: &mut InfoBuilder) { + debug!("handling ACPI RSDP version 1"); + let rsdp = unsafe { *(table.address as *const Rsdp) }; + if rsdp.validate().is_err() { + warn!("the RSDP is invalid"); + return; + } + if rsdp.revision() != 0 { + warn!("invalid RSDP revision (expected: 0, got: {})", rsdp.revision()); + return; + } + + info_builder.set_rsdp_v1( + rsdp.signature(), rsdp.checksum(), + rsdp.oem_id().as_bytes()[0..6].try_into().unwrap(), + rsdp.revision(), rsdp.rsdt_address(), + ); +} + +/// Parse the ACPI RSDP version 2 and create the Multiboot struct for it. +fn handle_acpi_v2(table: &ConfigTableEntry, info_builder: &mut InfoBuilder) { + debug!("handling ACPI RSDP version 2"); let rsdp = unsafe { *(table.address as *const Rsdp) }; if rsdp.validate().is_err() { warn!("the RSDP is invalid"); return; } if rsdp.revision() == 0 { - info_builder.set_rsdp_v1( - rsdp.signature(), rsdp.checksum(), - rsdp.oem_id().as_bytes()[0..6].try_into().unwrap(), - rsdp.revision(), rsdp.rsdt_address(), - ); - } else { - unsafe { - if !RSDP_V2_SET { - info_builder.set_rsdp_v2( - rsdp.signature(), rsdp.checksum(), - rsdp.oem_id().as_bytes()[0..6].try_into().unwrap(), - rsdp.revision(), rsdp.rsdt_address(), rsdp.length(), - rsdp.xsdt_address(), rsdp.ext_checksum(), - ); - RSDP_V2_SET = true; - } - } + warn!("invalid RSDP revision (expected: >0, got: {})", rsdp.revision()); + return; } + + info_builder.set_rsdp_v2( + rsdp.signature(), rsdp.checksum(), + rsdp.oem_id().as_bytes()[0..6].try_into().unwrap(), + rsdp.revision(), rsdp.rsdt_address(), rsdp.length(), + rsdp.xsdt_address(), rsdp.ext_checksum(), + ); } /// The entry point for SMBIOS.