[PATCH 2/3] arm64: kaslr: deal with physically misaligned kernel images

Ard Biesheuvel ard.biesheuvel at linaro.org
Wed Mar 2 10:11:25 PST 2016


On 2 March 2016 at 18:11, Ard Biesheuvel <ard.biesheuvel at linaro.org> wrote:
> Since KASLR requires a relocatable kernel image anyway, there is no
> practical reason to refuse an image whose load address is not exactly
> TEXT_OFFSET bytes above a 2 MB aligned base address, as long as the
> physical and virtual misalignment with respect to the swapper block
> size are equal. So treat the misalignment of the physical load address
> as the initial KASLR offset, and fix up the remaining code to deal with
> that.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  arch/arm64/kernel/head.S  | 16 ++++++++++++----
>  arch/arm64/kernel/kaslr.c |  6 +++---
>  2 files changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 1d4ae36db0bb..934d6dcd7a57 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -25,6 +25,7 @@
>  #include <linux/irqchip/arm-gic-v3.h>
>
>  #include <asm/assembler.h>
> +#include <asm/boot.h>
>  #include <asm/ptrace.h>
>  #include <asm/asm-offsets.h>
>  #include <asm/cache.h>
> @@ -211,8 +212,12 @@ section_table:
>  ENTRY(stext)
>         bl      preserve_boot_args
>         bl      el2_setup                       // Drop to EL1, w20=cpu_boot_mode
> -       mov     x23, xzr                        // KASLR offset, defaults to 0
>         adrp    x24, __PHYS_OFFSET
> +#ifdef CONFIG_RANDOMIZE_BASE

This should be ifndef. (I moved this around right before posting, but
failed to invert the condition)

> +       mov     x23, xzr                        // KASLR offset, defaults to 0
> +#else
> +       and     x23, x24, MIN_KIMG_ALIGN - 1    // unless loaded phys misaligned
> +#endif
>         bl      set_cpu_boot_mode_flag
>         bl      __create_page_tables            // x25=TTBR0, x26=TTBR1
>         /*
> @@ -489,11 +494,13 @@ __mmap_switched:
>         bl      kasan_early_init
>  #endif
>  #ifdef CONFIG_RANDOMIZE_BASE
> -       cbnz    x23, 0f                         // already running randomized?
> +       tst     x23, ~(MIN_KIMG_ALIGN - 1)      // already running randomized?
> +       b.ne    0f
>         mov     x0, x21                         // pass FDT address in x0
> +       mov     x1, x23                         // pass modulo offset in x1
>         bl      kaslr_early_init                // parse FDT for KASLR options
>         cbz     x0, 0f                          // KASLR disabled? just proceed
> -       mov     x23, x0                         // record KASLR offset
> +       orr     x23, x23, x0                    // record KASLR offset
>         ret     x28                             // we must enable KASLR, return
>                                                 // to __enable_mmu()
>  0:
> @@ -753,7 +760,8 @@ __enable_mmu:
>         isb
>  #ifdef CONFIG_RANDOMIZE_BASE
>         mov     x19, x0                         // preserve new SCTLR_EL1 value
> -       blr     x27
> +       add     x30, x27, x23
> +       blr     x30
>
>         /*
>          * If we return here, we have a KASLR displacement in x23 which we need
> diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
> index 582983920054..b05469173ba5 100644
> --- a/arch/arm64/kernel/kaslr.c
> +++ b/arch/arm64/kernel/kaslr.c
> @@ -74,7 +74,7 @@ extern void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size,
>   * containing function pointers) to be reinitialized, and zero-initialized
>   * .bss variables will be reset to 0.
>   */
> -u64 __init kaslr_early_init(u64 dt_phys)
> +u64 __init kaslr_early_init(u64 dt_phys, u64 modulo_offset)
>  {
>         void *fdt;
>         u64 seed, offset, mask, module_range;
> @@ -132,8 +132,8 @@ u64 __init kaslr_early_init(u64 dt_phys)
>          * boundary (for 4KB/16KB/64KB granule kernels, respectively). If this
>          * happens, increase the KASLR offset by the size of the kernel image.
>          */
> -       if ((((u64)_text + offset) >> SWAPPER_TABLE_SHIFT) !=
> -           (((u64)_end + offset) >> SWAPPER_TABLE_SHIFT))
> +       if ((((u64)_text + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT) !=
> +           (((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT))
>                 offset = (offset + (u64)(_end - _text)) & mask;
>
>         if (IS_ENABLED(CONFIG_KASAN))
> --
> 2.5.0
>



More information about the linux-arm-kernel mailing list