Skip to content

Commit e2b32e6

Browse files
keesH. Peter Anvin
authored andcommitted
x86, kaslr: randomize module base load address
Randomize the load address of modules in the kernel to make kASLR effective for modules. Modules can only be loaded within a particular range of virtual address space. This patch adds 10 bits of entropy to the load address by adding 1-1024 * PAGE_SIZE to the beginning range where modules are loaded. The single base offset was chosen because randomizing each module load ends up wasting/fragmenting memory too much. Prior approaches to minimizing fragmentation while doing randomization tend to result in worse entropy than just doing a single base address offset. Example kASLR boot without this change, with a single module loaded: ---[ Modules ]--- 0xffffffffc0000000-0xffffffffc0001000 4K ro GLB x pte 0xffffffffc0001000-0xffffffffc0002000 4K ro GLB NX pte 0xffffffffc0002000-0xffffffffc0004000 8K RW GLB NX pte 0xffffffffc0004000-0xffffffffc0200000 2032K pte 0xffffffffc0200000-0xffffffffff000000 1006M pmd ---[ End Modules ]--- Example kASLR boot after this change, same module loaded: ---[ Modules ]--- 0xffffffffc0000000-0xffffffffc0200000 2M pmd 0xffffffffc0200000-0xffffffffc03bf000 1788K pte 0xffffffffc03bf000-0xffffffffc03c0000 4K ro GLB x pte 0xffffffffc03c0000-0xffffffffc03c1000 4K ro GLB NX pte 0xffffffffc03c1000-0xffffffffc03c3000 8K RW GLB NX pte 0xffffffffc03c3000-0xffffffffc0400000 244K pte 0xffffffffc0400000-0xffffffffff000000 1004M pmd ---[ End Modules ]--- Signed-off-by: Andy Honig <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Kees Cook <[email protected]> Signed-off-by: H. Peter Anvin <[email protected]>
1 parent cfbf8d4 commit e2b32e6

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

Documentation/kernel-parameters.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,8 +2053,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
20532053
IOAPICs that may be present in the system.
20542054

20552055
nokaslr [X86]
2056-
Disable kernel base offset ASLR (Address Space
2057-
Layout Randomization) if built into the kernel.
2056+
Disable kernel and module base offset ASLR (Address
2057+
Space Layout Randomization) if built into the kernel.
20582058

20592059
noautogroup Disable scheduler automatic task group creation.
20602060

arch/x86/kernel/module.c

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <linux/mm.h>
2929
#include <linux/gfp.h>
3030
#include <linux/jump_label.h>
31+
#include <linux/random.h>
3132

3233
#include <asm/page.h>
3334
#include <asm/pgtable.h>
@@ -43,13 +44,49 @@ do { \
4344
} while (0)
4445
#endif
4546

47+
#ifdef CONFIG_RANDOMIZE_BASE
48+
static unsigned long module_load_offset;
49+
static int randomize_modules = 1;
50+
51+
static int __init parse_nokaslr(char *p)
52+
{
53+
randomize_modules = 0;
54+
return 0;
55+
}
56+
early_param("nokaslr", parse_nokaslr);
57+
58+
static unsigned long int get_module_load_offset(void)
59+
{
60+
if (randomize_modules) {
61+
mutex_lock(&module_mutex);
62+
/*
63+
* Calculate the module_load_offset the first time this
64+
* code is called. Once calculated it stays the same until
65+
* reboot.
66+
*/
67+
if (module_load_offset == 0)
68+
module_load_offset =
69+
(get_random_int() % 1024 + 1) * PAGE_SIZE;
70+
mutex_unlock(&module_mutex);
71+
}
72+
return module_load_offset;
73+
}
74+
#else
75+
static unsigned long int get_module_load_offset(void)
76+
{
77+
return 0;
78+
}
79+
#endif
80+
4681
void *module_alloc(unsigned long size)
4782
{
4883
if (PAGE_ALIGN(size) > MODULES_LEN)
4984
return NULL;
50-
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
51-
GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
52-
NUMA_NO_NODE, __builtin_return_address(0));
85+
return __vmalloc_node_range(size, 1,
86+
MODULES_VADDR + get_module_load_offset(),
87+
MODULES_END, GFP_KERNEL | __GFP_HIGHMEM,
88+
PAGE_KERNEL_EXEC, NUMA_NO_NODE,
89+
__builtin_return_address(0));
5390
}
5491

5592
#ifdef CONFIG_X86_32

0 commit comments

Comments
 (0)