Skip to content

Commit

Permalink
arm64: kaslr: split kaslr/module initialization
Browse files Browse the repository at this point in the history
BugLink: https://bugs.launchpad.net/bugs/2024857

Currently kaslr_init() handles a mixture of detecting/announcing whether
KASLR is enabled, and randomizing the module region depending 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, recording 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 subsys_initcall, where we previously called
  kaslr_init().

As a bonus, moving the KASLR reporting earlier makes it easier to spot
and permits it to be logged via earlycon, making it easier to debug any
issues that could be triggered by KASLR.

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@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 <[email protected]>
Reviewed-by: Ard Biesheuvel <[email protected]>
Cc: Will Deacon <[email protected]>
Tested-by: Shanker Donthineni <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Catalin Marinas <[email protected]>
(cherry picked from commit 6e13b6b linux-next)
Signed-off-by: Tushar Dave <[email protected]>
Acked-by: Brad Figg <[email protected]>
Acked-by: Ian May <[email protected]>
Acked-by: Jacob Martin <[email protected]>
Signed-off-by: Brad Figg <[email protected]>
  • Loading branch information
Mark Rutland authored and nvidia-bfigg committed Nov 16, 2023
1 parent d5394d1 commit 17f5237
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 20 deletions.
14 changes: 8 additions & 6 deletions arch/arm64/include/asm/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
39 changes: 25 additions & 14 deletions arch/arm64/kernel/kaslr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -80,4 +91,4 @@ static int __init kaslr_init(void)

return 0;
}
subsys_initcall(kaslr_init)
subsys_initcall(kaslr_module_init)
2 changes: 2 additions & 0 deletions arch/arm64/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,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
Expand Down

0 comments on commit 17f5237

Please sign in to comment.