Skip to content

Commit e46b710

Browse files
mrutland-armctmarinas
authored andcommitted
arm64: module: move module randomization to module.c
When CONFIG_RANDOMIZE_BASE=y, module_alloc_base is a variable which is configured by kaslr_module_init() in kaslr.c, and otherwise it is an expression defined in module.h. As kaslr_module_init() is no longer tightly coupled with the KASLR initialization code, we can centralize this in module.c. This patch moves kaslr_module_init() to module.c, making module_alloc_base a static variable, and removing redundant includes from kaslr.c. For the defintion of struct arm64_ftr_override we must include <asm/cpufeature.h>, which was previously included transitively via another header. There should be no functional change as a result of this patch. 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 6e13b6b commit e46b710

File tree

3 files changed

+50
-64
lines changed

3 files changed

+50
-64
lines changed

arch/arm64/include/asm/module.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs,
3030
u64 module_emit_veneer_for_adrp(struct module *mod, Elf64_Shdr *sechdrs,
3131
void *loc, u64 val);
3232

33-
#ifdef CONFIG_RANDOMIZE_BASE
34-
extern u64 module_alloc_base;
35-
#else
36-
#define module_alloc_base ((u64)_etext - MODULES_VSIZE)
37-
#endif
38-
3933
struct plt_entry {
4034
/*
4135
* A program that conforms to the AArch64 Procedure Call Standard

arch/arm64/kernel/kaslr.c

Lines changed: 2 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,12 @@
44
*/
55

66
#include <linux/cache.h>
7-
#include <linux/crc32.h>
87
#include <linux/init.h>
9-
#include <linux/libfdt.h>
10-
#include <linux/mm_types.h>
11-
#include <linux/sched.h>
12-
#include <linux/types.h>
13-
#include <linux/pgtable.h>
14-
#include <linux/random.h>
8+
#include <linux/printk.h>
159

16-
#include <asm/fixmap.h>
17-
#include <asm/kernel-pgtable.h>
10+
#include <asm/cpufeature.h>
1811
#include <asm/memory.h>
19-
#include <asm/mmu.h>
20-
#include <asm/sections.h>
21-
#include <asm/setup.h>
2212

23-
u64 __ro_after_init module_alloc_base;
2413
u16 __initdata memstart_offset_seed;
2514

2615
struct arm64_ftr_override kaslr_feature_override __initdata;
@@ -47,48 +36,3 @@ void __init kaslr_init(void)
4736
pr_info("KASLR enabled\n");
4837
__kaslr_is_enabled = true;
4938
}
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;
61-
62-
seed = get_random_u32();
63-
64-
if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) {
65-
/*
66-
* Randomize the module region over a 2 GB window covering the
67-
* kernel. This reduces the risk of modules leaking information
68-
* about the address of the kernel itself, but results in
69-
* branches between modules and the core kernel that are
70-
* resolved via PLTs. (Branches between modules will be
71-
* resolved normally.)
72-
*/
73-
module_range = SZ_2G - (u64)(_end - _stext);
74-
module_alloc_base = max((u64)_end - SZ_2G, (u64)MODULES_VADDR);
75-
} else {
76-
/*
77-
* Randomize the module region by setting module_alloc_base to
78-
* a PAGE_SIZE multiple in the range [_etext - MODULES_VSIZE,
79-
* _stext) . This guarantees that the resulting region still
80-
* covers [_stext, _etext], and that all relative branches can
81-
* be resolved without veneers unless this region is exhausted
82-
* and we fall back to a larger 2GB window in module_alloc()
83-
* when ARM64_MODULE_PLTS is enabled.
84-
*/
85-
module_range = MODULES_VSIZE - (u64)(_etext - _stext);
86-
}
87-
88-
/* use the lower 21 bits to randomize the base of the module region */
89-
module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21;
90-
module_alloc_base &= PAGE_MASK;
91-
92-
return 0;
93-
}
94-
subsys_initcall(kaslr_module_init)

arch/arm64/kernel/module.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,61 @@
1515
#include <linux/kernel.h>
1616
#include <linux/mm.h>
1717
#include <linux/moduleloader.h>
18+
#include <linux/random.h>
1819
#include <linux/scs.h>
1920
#include <linux/vmalloc.h>
21+
2022
#include <asm/alternative.h>
2123
#include <asm/insn.h>
2224
#include <asm/scs.h>
2325
#include <asm/sections.h>
2426

27+
static u64 __ro_after_init module_alloc_base = (u64)_etext - MODULES_VSIZE;
28+
29+
#ifdef CONFIG_RANDOMIZE_BASE
30+
static int __init kaslr_module_init(void)
31+
{
32+
u64 module_range;
33+
u32 seed;
34+
35+
if (!kaslr_enabled())
36+
return 0;
37+
38+
seed = get_random_u32();
39+
40+
if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) {
41+
/*
42+
* Randomize the module region over a 2 GB window covering the
43+
* kernel. This reduces the risk of modules leaking information
44+
* about the address of the kernel itself, but results in
45+
* branches between modules and the core kernel that are
46+
* resolved via PLTs. (Branches between modules will be
47+
* resolved normally.)
48+
*/
49+
module_range = SZ_2G - (u64)(_end - _stext);
50+
module_alloc_base = max((u64)_end - SZ_2G, (u64)MODULES_VADDR);
51+
} else {
52+
/*
53+
* Randomize the module region by setting module_alloc_base to
54+
* a PAGE_SIZE multiple in the range [_etext - MODULES_VSIZE,
55+
* _stext) . This guarantees that the resulting region still
56+
* covers [_stext, _etext], and that all relative branches can
57+
* be resolved without veneers unless this region is exhausted
58+
* and we fall back to a larger 2GB window in module_alloc()
59+
* when ARM64_MODULE_PLTS is enabled.
60+
*/
61+
module_range = MODULES_VSIZE - (u64)(_etext - _stext);
62+
}
63+
64+
/* use the lower 21 bits to randomize the base of the module region */
65+
module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21;
66+
module_alloc_base &= PAGE_MASK;
67+
68+
return 0;
69+
}
70+
subsys_initcall(kaslr_module_init)
71+
#endif
72+
2573
void *module_alloc(unsigned long size)
2674
{
2775
u64 module_alloc_end = module_alloc_base + MODULES_VSIZE;

0 commit comments

Comments
 (0)