[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