[PATCH v2 3/6] arm64: kaslr: split kaslr/module initialization

Ard Biesheuvel ardb at kernel.org
Tue May 30 03:26:31 PDT 2023


On Fri, 12 May 2023 at 17:22, Mark Rutland <mark.rutland at arm.com> wrote:
>
> Currently kaslr_init() handles a mixture of detecting/announcing whether
> KASLR is enabled, and randomizing the module region depening on whether
> KASLR is enabled.
>
> To make it easier to rework the module region initialization, split the
> KASLR initialization into two steps:
>
> * kaslr_init() determines whether KASLR should be enabled, and announces
>   this choice, recoding this to a new global boolean variable. This is
>   called from setup_arch() just before the existing call to
>   kaslr_requires_kpti() so that this will always provide the expected
>   result.
>
> * kaslr_module_init() randomizes the module region when required. This
>   is called as a syubsys_initcall, where we previosuly called

subsys_initcall

>   kaslr_init().
>
> As a bomus, moving the KASLR reporting earlier makes it easier to spot

bonus

> and permits it to be logged via earlycon, making it easier to debug any
> issues that could be triggerer by KASLR.

triggered

>
> Booting a v6.4-rc1 kernel with this patch applied, the log looks like:
>
> | EFI stub: Booting Linux Kernel...
> | EFI stub: Generating empty DTB
> | EFI stub: Exiting boot services...
> | [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x000f0510]
> | [    0.000000] Linux version 6.4.0-rc1-00006-g4763a8f8aeb3 (mark at lakrids) (aarch64-linux-gcc (GCC) 12.1.0, GNU ld (GNU Binutils) 2.38) #2 SMP PREEMPT Tue May  9 11:03:37 BST 2023
> | [    0.000000] KASLR enabled
> | [    0.000000] earlycon: pl11 at MMIO 0x0000000009000000 (options '')
> | [    0.000000] printk: bootconsole [pl11] enabled
>
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/include/asm/memory.h | 14 +++++++-----
>  arch/arm64/kernel/kaslr.c       | 39 +++++++++++++++++++++------------
>  arch/arm64/kernel/setup.c       |  2 ++
>  3 files changed, 35 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index c735afdf639b..215efc3bbbcf 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -204,15 +204,17 @@ static inline unsigned long kaslr_offset(void)
>         return kimage_vaddr - KIMAGE_VADDR;
>  }
>
> +#ifdef CONFIG_RANDOMIZE_BASE
> +void kaslr_init(void);
>  static inline bool kaslr_enabled(void)
>  {
> -       /*
> -        * The KASLR offset modulo MIN_KIMG_ALIGN is taken from the physical
> -        * placement of the image rather than from the seed, so a displacement
> -        * of less than MIN_KIMG_ALIGN means that no seed was provided.
> -        */
> -       return kaslr_offset() >= MIN_KIMG_ALIGN;
> +       extern bool __kaslr_is_enabled;
> +       return __kaslr_is_enabled;
>  }
> +#else
> +static inline void kaslr_init(void) { }
> +static inline bool kaslr_enabled(void) { return false; }
> +#endif
>
>  /*
>   * Allow all memory at the discovery stage. We will clip it later.
> diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
> index df433c80c6ef..ce7079ba1dc1 100644
> --- a/arch/arm64/kernel/kaslr.c
> +++ b/arch/arm64/kernel/kaslr.c
> @@ -25,28 +25,39 @@ u16 __initdata memstart_offset_seed;
>
>  struct arm64_ftr_override kaslr_feature_override __initdata;
>
> -static int __init kaslr_init(void)
> -{
> -       u64 module_range;
> -       u32 seed;
> -
> -       /*
> -        * Set a reasonable default for module_alloc_base in case
> -        * we end up running with module randomization disabled.
> -        */
> -       module_alloc_base = (u64)_etext - MODULES_VSIZE;
> +bool __ro_after_init __kaslr_is_enabled = false;
>
> +void __init kaslr_init(void)
> +{
>         if (kaslr_feature_override.val & kaslr_feature_override.mask & 0xf) {
>                 pr_info("KASLR disabled on command line\n");
> -               return 0;
> +               return;
>         }
>
> -       if (!kaslr_enabled()) {
> +       /*
> +        * The KASLR offset modulo MIN_KIMG_ALIGN is taken from the physical
> +        * placement of the image rather than from the seed, so a displacement
> +        * of less than MIN_KIMG_ALIGN means that no seed was provided.
> +        */
> +       if (kaslr_offset() < MIN_KIMG_ALIGN) {
>                 pr_warn("KASLR disabled due to lack of seed\n");
> -               return 0;
> +               return;
>         }
>
>         pr_info("KASLR enabled\n");
> +       __kaslr_is_enabled = true;
> +}
> +
> +int kaslr_module_init(void)
> +{
> +       u64 module_range;
> +       u32 seed;
> +
> +       /*
> +        * Set a reasonable default for module_alloc_base in case
> +        * we end up running with module randomization disabled.
> +        */
> +       module_alloc_base = (u64)_etext - MODULES_VSIZE;
>
>         seed = get_random_u32();
>
> @@ -80,4 +91,4 @@ static int __init kaslr_init(void)
>
>         return 0;
>  }
> -subsys_initcall(kaslr_init)
> +subsys_initcall(kaslr_module_init)
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index b8ec7b3ac9cb..417a8a86b2db 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -296,6 +296,8 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
>
>         *cmdline_p = boot_command_line;
>
> +       kaslr_init();
> +
>         /*
>          * If know now we are going to need KPTI then use non-global
>          * mappings from the start, avoiding the cost of rewriting
> --
> 2.30.2
>



More information about the linux-arm-kernel mailing list