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); }