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.
This commit is contained in:
Idan Horowitz 2023-12-31 00:15:02 +02:00 committed by Andreas Kling
parent e394971209
commit bbceb155ce
2 changed files with 11 additions and 0 deletions

View file

@ -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()

View file

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