Kernel/Interrupts: Add ByteReaders to read possible unaligned MADT data

The MADT data could be on unaligned boundary - for example, a GSI number
(u32) on unaligned address which leads to a KUBSAN error and halting the
system.
This commit is contained in:
Liav A 2021-11-28 19:23:58 +02:00 committed by Andreas Kling
parent bbdb55126c
commit f57900a41b
Notes: sideshowbarker 2024-07-17 22:47:34 +09:00

View File

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <AK/ByteReader.h>
#include <Kernel/API/Syscall.h> #include <Kernel/API/Syscall.h>
#include <Kernel/Arch/x86/InterruptDisabler.h> #include <Kernel/Arch/x86/InterruptDisabler.h>
#include <Kernel/Arch/x86/Interrupts.h> #include <Kernel/Arch/x86/Interrupts.h>
@ -206,16 +207,20 @@ UNMAP_AFTER_INIT void InterruptManagement::locate_apic_data()
} }
if (madt_entry->type == (u8)ACPI::Structures::MADTEntryType::InterruptSourceOverride) { if (madt_entry->type == (u8)ACPI::Structures::MADTEntryType::InterruptSourceOverride) {
auto* interrupt_override_entry = (const ACPI::Structures::MADTEntries::InterruptSourceOverride*)madt_entry; auto* interrupt_override_entry = (const ACPI::Structures::MADTEntries::InterruptSourceOverride*)madt_entry;
u32 global_system_interrupt = 0;
ByteReader::load<u32>(reinterpret_cast<u8 const*>(&interrupt_override_entry->global_system_interrupt), global_system_interrupt);
u16 flags = 0;
ByteReader::load<u16>(reinterpret_cast<u8 const*>(&interrupt_override_entry->flags), flags);
m_isa_interrupt_overrides.empend( m_isa_interrupt_overrides.empend(
interrupt_override_entry->bus, interrupt_override_entry->bus,
interrupt_override_entry->source, interrupt_override_entry->source,
interrupt_override_entry->global_system_interrupt, global_system_interrupt,
interrupt_override_entry->flags); flags);
dbgln("Interrupts: Overriding INT {:#x} with GSI {}, for bus {:#x}", dbgln("Interrupts: Overriding INT {:#x} with GSI {}, for bus {:#x}",
interrupt_override_entry->source, interrupt_override_entry->source,
interrupt_override_entry->global_system_interrupt, global_system_interrupt,
interrupt_override_entry->bus); flags);
} }
madt_entry = (ACPI::Structures::MADTEntryHeader*)(VirtualAddress(madt_entry).offset(entry_length).get()); madt_entry = (ACPI::Structures::MADTEntryHeader*)(VirtualAddress(madt_entry).offset(entry_length).get());
entries_length -= entry_length; entries_length -= entry_length;