Skip to content

Commit fc5a89f

Browse files
ardbiesheuvelwilldeacon
authored andcommitted
arm64: kaslr: defer initialization to initcall where permitted
The early KASLR init code runs extremely early, and anything that could be deferred until later should be. So let's defer the randomization of the module region until much later - this also simplifies the arithmetic, given that we no longer have to reason about the link time vs load time placement of the core kernel explicitly. Also get rid of the global status variable, and infer the status reported by the diagnostic print from other KASLR related context. While at it, get rid of the special case for KASAN without KASAN_VMALLOC, which never occurs in practice. Signed-off-by: Ard Biesheuvel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 005e126 commit fc5a89f

File tree

1 file changed

+40
-55
lines changed

1 file changed

+40
-55
lines changed

arch/arm64/kernel/kaslr.c

Lines changed: 40 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@
2020
#include <asm/sections.h>
2121
#include <asm/setup.h>
2222

23-
enum kaslr_status {
24-
KASLR_ENABLED,
25-
KASLR_DISABLED_CMDLINE,
26-
KASLR_DISABLED_NO_SEED,
27-
KASLR_DISABLED_FDT_REMAP,
28-
};
29-
30-
static enum kaslr_status __initdata kaslr_status;
3123
u64 __ro_after_init module_alloc_base;
3224
u16 __initdata memstart_offset_seed;
3325

@@ -63,23 +55,16 @@ struct arm64_ftr_override kaslr_feature_override __initdata;
6355
u64 __init kaslr_early_init(void)
6456
{
6557
void *fdt;
66-
u64 seed, offset, mask, module_range;
58+
u64 seed, offset, mask;
6759
unsigned long raw;
6860

69-
/*
70-
* Set a reasonable default for module_alloc_base in case
71-
* we end up running with module randomization disabled.
72-
*/
73-
module_alloc_base = (u64)_etext - MODULES_VSIZE;
74-
7561
/*
7662
* Try to map the FDT early. If this fails, we simply bail,
7763
* and proceed with KASLR disabled. We will make another
7864
* attempt at mapping the FDT in setup_machine()
7965
*/
8066
fdt = get_early_fdt_ptr();
8167
if (!fdt) {
82-
kaslr_status = KASLR_DISABLED_FDT_REMAP;
8368
return 0;
8469
}
8570

@@ -93,7 +78,6 @@ u64 __init kaslr_early_init(void)
9378
* return 0 if that is the case.
9479
*/
9580
if (kaslr_feature_override.val & kaslr_feature_override.mask & 0xf) {
96-
kaslr_status = KASLR_DISABLED_CMDLINE;
9781
return 0;
9882
}
9983

@@ -106,7 +90,6 @@ u64 __init kaslr_early_init(void)
10690
seed ^= raw;
10791

10892
if (!seed) {
109-
kaslr_status = KASLR_DISABLED_NO_SEED;
11093
return 0;
11194
}
11295

@@ -126,19 +109,43 @@ u64 __init kaslr_early_init(void)
126109
/* use the top 16 bits to randomize the linear region */
127110
memstart_offset_seed = seed >> 48;
128111

129-
if (!IS_ENABLED(CONFIG_KASAN_VMALLOC) &&
130-
(IS_ENABLED(CONFIG_KASAN_GENERIC) ||
131-
IS_ENABLED(CONFIG_KASAN_SW_TAGS)))
132-
/*
133-
* KASAN without KASAN_VMALLOC does not expect the module region
134-
* to intersect the vmalloc region, since shadow memory is
135-
* allocated for each module at load time, whereas the vmalloc
136-
* region is shadowed by KASAN zero pages. So keep modules
137-
* out of the vmalloc region if KASAN is enabled without
138-
* KASAN_VMALLOC, and put the kernel well within 4 GB of the
139-
* module region.
140-
*/
141-
return offset % SZ_2G;
112+
return offset;
113+
}
114+
115+
static int __init kaslr_init(void)
116+
{
117+
u64 module_range;
118+
u32 seed;
119+
120+
/*
121+
* Set a reasonable default for module_alloc_base in case
122+
* we end up running with module randomization disabled.
123+
*/
124+
module_alloc_base = (u64)_etext - MODULES_VSIZE;
125+
126+
if (kaslr_feature_override.val & kaslr_feature_override.mask & 0xf) {
127+
pr_info("KASLR disabled on command line\n");
128+
return 0;
129+
}
130+
131+
if (!kaslr_offset()) {
132+
pr_warn("KASLR disabled due to lack of seed\n");
133+
return 0;
134+
}
135+
136+
pr_info("KASLR enabled\n");
137+
138+
/*
139+
* KASAN without KASAN_VMALLOC does not expect the module region to
140+
* intersect the vmalloc region, since shadow memory is allocated for
141+
* each module at load time, whereas the vmalloc region will already be
142+
* shadowed by KASAN zero pages.
143+
*/
144+
BUILD_BUG_ON((IS_ENABLED(CONFIG_KASAN_GENERIC) ||
145+
IS_ENABLED(CONFIG_KASAN_SW_TAGS)) &&
146+
!IS_ENABLED(CONFIG_KASAN_VMALLOC));
147+
148+
seed = get_random_u32();
142149

143150
if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) {
144151
/*
@@ -150,8 +157,7 @@ u64 __init kaslr_early_init(void)
150157
* resolved normally.)
151158
*/
152159
module_range = SZ_2G - (u64)(_end - _stext);
153-
module_alloc_base = max((u64)_end + offset - SZ_2G,
154-
(u64)MODULES_VADDR);
160+
module_alloc_base = max((u64)_end - SZ_2G, (u64)MODULES_VADDR);
155161
} else {
156162
/*
157163
* Randomize the module region by setting module_alloc_base to
@@ -163,33 +169,12 @@ u64 __init kaslr_early_init(void)
163169
* when ARM64_MODULE_PLTS is enabled.
164170
*/
165171
module_range = MODULES_VSIZE - (u64)(_etext - _stext);
166-
module_alloc_base = (u64)_etext + offset - MODULES_VSIZE;
167172
}
168173

169174
/* use the lower 21 bits to randomize the base of the module region */
170175
module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21;
171176
module_alloc_base &= PAGE_MASK;
172177

173-
return offset;
174-
}
175-
176-
static int __init kaslr_init(void)
177-
{
178-
switch (kaslr_status) {
179-
case KASLR_ENABLED:
180-
pr_info("KASLR enabled\n");
181-
break;
182-
case KASLR_DISABLED_CMDLINE:
183-
pr_info("KASLR disabled on command line\n");
184-
break;
185-
case KASLR_DISABLED_NO_SEED:
186-
pr_warn("KASLR disabled due to lack of seed\n");
187-
break;
188-
case KASLR_DISABLED_FDT_REMAP:
189-
pr_warn("KASLR disabled due to FDT remapping failure\n");
190-
break;
191-
}
192-
193178
return 0;
194179
}
195-
core_initcall(kaslr_init)
180+
subsys_initcall(kaslr_init)

0 commit comments

Comments
 (0)