From bbceb155ce2be13d81cee34152c254fcc5927137 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Sun, 31 Dec 2023 00:15:02 +0200 Subject: [PATCH] Kernel: Restrict KASLR randomization range when KASAN is enabled To allow for easy mapping between the kernel virtual addresses and KASAN shadow memory, we map shadow memory at the very end of the virtual range, so that we can index into it using just an offset. To ensure this range is free when needed, we restrict the possible KASLR range when KASAN is enabled to make sure we don't use the end of the virtual range. This fixes the random kernel panics that could occur when KASAN is enabled, if the kernel was randomly placed at the very end of the virtual range. --- Kernel/Prekernel/CMakeLists.txt | 4 ++++ Kernel/Prekernel/init.cpp | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/Kernel/Prekernel/CMakeLists.txt b/Kernel/Prekernel/CMakeLists.txt index cdff1582a5..567981ed4e 100644 --- a/Kernel/Prekernel/CMakeLists.txt +++ b/Kernel/Prekernel/CMakeLists.txt @@ -41,3 +41,7 @@ get_target_property(PREKERNEL_TARGET_OPTIONS ${PREKERNEL_TARGET} COMPILE_OPTIONS list(REMOVE_ITEM PREKERNEL_TARGET_OPTIONS "-fsanitize-coverage=trace-pc") list(REMOVE_ITEM PREKERNEL_TARGET_OPTIONS "-fsanitize=kernel-address") set_target_properties(${PREKERNEL_TARGET} PROPERTIES COMPILE_OPTIONS "${PREKERNEL_TARGET_OPTIONS}") + +if (ENABLE_KERNEL_ADDRESS_SANITIZER) + add_compile_definitions(KERNEL_ADDRESS_SANITIZER_ENABLED) +endif() diff --git a/Kernel/Prekernel/init.cpp b/Kernel/Prekernel/init.cpp index 546160209b..26d23232a2 100644 --- a/Kernel/Prekernel/init.cpp +++ b/Kernel/Prekernel/init.cpp @@ -112,6 +112,13 @@ extern "C" [[noreturn]] void init() if (__builtin_strstr(kernel_cmdline, "disable_kaslr") == nullptr) { FlatPtr maximum_offset = (FlatPtr)KERNEL_PD_SIZE - MAX_KERNEL_SIZE - 2 * MiB; // The first 2 MiB are used for mapping the pre-kernel +#ifdef KERNEL_ADDRESS_SANITIZER_ENABLED + // To allow for easy mapping between the kernel virtual addresses and KASAN shadow memory, + // we map shadow memory at the very end of the virtual range, so that we can index into it + // using just an offset. To ensure this range is free when needed, we restrict the possible + // KASLR range when KASAN is enabled to make sure we don't use the end of the virtual range. + maximum_offset -= ceil_div(maximum_offset, 9ul); +#endif kernel_load_base += (generate_secure_seed() % maximum_offset); kernel_load_base &= ~(2 * MiB - 1); }