From 3639a1af80da2005a802c1a45c7198fc294b5daf Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Tue, 21 Jul 2020 14:46:34 +0200 Subject: [PATCH] acpi_drv: avoid out-of-bound access to FADT table Fixes #3829 --- repos/os/src/drivers/acpi/acpi.cc | 37 +++++++++---------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/repos/os/src/drivers/acpi/acpi.cc b/repos/os/src/drivers/acpi/acpi.cc index d620c1d20e..cec5f9c2b2 100644 --- a/repos/os/src/drivers/acpi/acpi.cc +++ b/repos/os/src/drivers/acpi/acpi.cc @@ -140,13 +140,13 @@ struct Dmar_struct_header : Generic void apply(FUNC const &func = [] () { } ) { addr_t addr = dmar_entry_start(); - do { + while (addr < dmar_entry_end()) { Dmar_common dmar(addr); func(dmar); addr = dmar.base() + dmar.read(); - } while (addr < dmar_entry_end()); + } } struct Dmar_struct_header * clone(Genode::Allocator &alloc) @@ -205,13 +205,13 @@ struct Dmar_drhd : Genode::Mmio void apply(FUNC const &func = [] () { } ) { addr_t addr = base() + 16; - do { + while (addr < base() + read()) { Device_scope scope(addr); func(scope); addr = scope.base() + scope.read(); - } while (addr < base() + read()); + } } }; @@ -228,13 +228,13 @@ struct Dmar_rmrr : Genode::Mmio void apply(FUNC const &func = [] () { } ) { addr_t addr = base() + 24; - do { + while (addr < base() + read()) { Device_scope scope(addr); func(scope); addr = scope.base() + scope.read(); - } while (addr < base() + read()); + } } }; @@ -242,30 +242,13 @@ struct Dmar_rmrr : Genode::Mmio /* Fixed ACPI description table (FADT) */ struct Fadt : Genode::Mmio { - static uint32_t features; - static uint32_t reset_type; - static uint64_t reset_addr; - static uint8_t reset_value; + Fadt(addr_t a) : Genode::Mmio(a) { } - Fadt(addr_t a) : Genode::Mmio(a) - { - features = read(); - reset_type = read(); - reset_addr = read(); - reset_value = read(); - } + struct Dsdt : Register<0x28, 32> { }; - struct Dsdt : Register<0x28, 32> { }; - struct Feature_flags : Register<0x70, 32> { }; - struct Reset_reg_type : Register<0x74, 32> { }; - struct Reset_reg_addr : Register<0x78, 64> { }; - struct Reset_value : Register<0x80, 8> { }; + static uint32_t size() { return Dsdt::OFFSET + Dsdt::ACCESS_WIDTH / 8; } }; -uint32_t Fadt::features = 0; -uint32_t Fadt::reset_type = 0; -uint64_t Fadt::reset_addr = 0; -uint8_t Fadt::reset_value = 0; class Dmar_entry : public List::Element { @@ -1218,7 +1201,7 @@ class Acpi_table continue; } - if (table.is_facp()) { + if (table.is_facp() && Fadt::size() <= table->size) { Fadt fadt(reinterpret_cast(table->signature)); dsdt = fadt.read(); }