Skip to content

Commit 6e13b6b

Browse files
mrutland-armctmarinas
authored andcommitted
arm64: kaslr: split kaslr/module initialization
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]>
1 parent 55123af commit 6e13b6b

File tree

3 files changed

+35
-20
lines changed

3 files changed

+35
-20
lines changed

arch/arm64/include/asm/memory.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,15 +204,17 @@ static inline unsigned long kaslr_offset(void)
204204
return kimage_vaddr - KIMAGE_VADDR;
205205
}
206206

207+
#ifdef CONFIG_RANDOMIZE_BASE
208+
void kaslr_init(void);
207209
static inline bool kaslr_enabled(void)
208210
{
209-
/*
210-
* The KASLR offset modulo MIN_KIMG_ALIGN is taken from the physical
211-
* placement of the image rather than from the seed, so a displacement
212-
* of less than MIN_KIMG_ALIGN means that no seed was provided.
213-
*/
214-
return kaslr_offset() >= MIN_KIMG_ALIGN;
211+
extern bool __kaslr_is_enabled;
212+
return __kaslr_is_enabled;
215213
}
214+
#else
215+
static inline void kaslr_init(void) { }
216+
static inline bool kaslr_enabled(void) { return false; }
217+
#endif
216218

217219
/*
218220
* Allow all memory at the discovery stage. We will clip it later.

arch/arm64/kernel/kaslr.c

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,39 @@ u16 __initdata memstart_offset_seed;
2525

2626
struct arm64_ftr_override kaslr_feature_override __initdata;
2727

28-
static int __init kaslr_init(void)
29-
{
30-
u64 module_range;
31-
u32 seed;
32-
33-
/*
34-
* Set a reasonable default for module_alloc_base in case
35-
* we end up running with module randomization disabled.
36-
*/
37-
module_alloc_base = (u64)_etext - MODULES_VSIZE;
28+
bool __ro_after_init __kaslr_is_enabled = false;
3829

30+
void __init kaslr_init(void)
31+
{
3932
if (kaslr_feature_override.val & kaslr_feature_override.mask & 0xf) {
4033
pr_info("KASLR disabled on command line\n");
41-
return 0;
34+
return;
4235
}
4336

44-
if (!kaslr_enabled()) {
37+
/*
38+
* The KASLR offset modulo MIN_KIMG_ALIGN is taken from the physical
39+
* placement of the image rather than from the seed, so a displacement
40+
* of less than MIN_KIMG_ALIGN means that no seed was provided.
41+
*/
42+
if (kaslr_offset() < MIN_KIMG_ALIGN) {
4543
pr_warn("KASLR disabled due to lack of seed\n");
46-
return 0;
44+
return;
4745
}
4846

4947
pr_info("KASLR enabled\n");
48+
__kaslr_is_enabled = true;
49+
}
50+
51+
int kaslr_module_init(void)
52+
{
53+
u64 module_range;
54+
u32 seed;
55+
56+
/*
57+
* Set a reasonable default for module_alloc_base in case
58+
* we end up running with module randomization disabled.
59+
*/
60+
module_alloc_base = (u64)_etext - MODULES_VSIZE;
5061

5162
seed = get_random_u32();
5263

@@ -80,4 +91,4 @@ static int __init kaslr_init(void)
8091

8192
return 0;
8293
}
83-
subsys_initcall(kaslr_init)
94+
subsys_initcall(kaslr_module_init)

arch/arm64/kernel/setup.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
296296

297297
*cmdline_p = boot_command_line;
298298

299+
kaslr_init();
300+
299301
/*
300302
* If know now we are going to need KPTI then use non-global
301303
* mappings from the start, avoiding the cost of rewriting

0 commit comments

Comments
 (0)