From 5d12da9dd6c155f7a09dfcaa2b9827764c939b2a Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 13 Apr 2020 15:36:37 +0200 Subject: [PATCH] efi/libstub/arm64: Simplify randomized loading of kernel image The KASLR code path in the arm64 version of the EFI stub incorporates some overly complicated logic to randomly allocate a region of the right alignment: there is no need to randomize the placement of the kernel modulo 2 MiB separately from the placement of the 2 MiB aligned allocation itself - we can simply follow the same logic used by the non-randomized placement, which is to allocate at the correct alignment, and only take TEXT_OFFSET into account if it is not a round multiple of the alignment. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/arm64-stub.c | 32 ++++------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index cfd535c13242..6fc3bd9a56db 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c @@ -52,7 +52,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, { efi_status_t status; unsigned long kernel_size, kernel_memsize = 0; - u64 phys_seed = 0; + u32 phys_seed = 0; if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { if (!nokaslr()) { @@ -74,36 +74,15 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, kernel_size = _edata - _text; kernel_memsize = kernel_size + (_end - _edata); + *reserve_size = kernel_memsize + TEXT_OFFSET % min_kimg_align; if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && phys_seed != 0) { - /* - * Produce a displacement in the interval [0, MIN_KIMG_ALIGN) - * that doesn't violate this kernel's de-facto alignment - * constraints. - */ - u32 mask = (MIN_KIMG_ALIGN - 1) & ~(EFI_KIMG_ALIGN - 1); - u32 offset = (phys_seed >> 32) & mask; - - /* - * With CONFIG_RANDOMIZE_TEXT_OFFSET=y, TEXT_OFFSET may not - * be a multiple of EFI_KIMG_ALIGN, and we must ensure that - * we preserve the misalignment of 'offset' relative to - * EFI_KIMG_ALIGN so that statically allocated objects whose - * alignment exceeds PAGE_SIZE appear correctly aligned in - * memory. - */ - offset |= TEXT_OFFSET % EFI_KIMG_ALIGN; - /* * If KASLR is enabled, and we have some randomness available, * locate the kernel at a randomized offset in physical memory. */ - *reserve_size = kernel_memsize + offset; - status = efi_random_alloc(*reserve_size, - MIN_KIMG_ALIGN, reserve_addr, - (u32)phys_seed); - - *image_addr = *reserve_addr + offset; + status = efi_random_alloc(*reserve_size, min_kimg_align, + reserve_addr, phys_seed); } else { status = EFI_OUT_OF_RESOURCES; } @@ -119,7 +98,6 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, return EFI_SUCCESS; } - *reserve_size = kernel_memsize + TEXT_OFFSET % min_kimg_align; status = efi_low_alloc(*reserve_size, min_kimg_align, reserve_addr); @@ -128,9 +106,9 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, *reserve_size = 0; return status; } - *image_addr = *reserve_addr + TEXT_OFFSET % min_kimg_align; } + *image_addr = *reserve_addr + TEXT_OFFSET % min_kimg_align; memcpy((void *)*image_addr, _text, kernel_size); return EFI_SUCCESS;