mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 12:52:30 +00:00
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 <ahonig@google.com> Link: http://lkml.kernel.org/r/20140226005916.GA27083@www.outflux.net Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
parent
cfbf8d4857
commit
e2b32e6785
@ -2053,8 +2053,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
IOAPICs that may be present in the system.
|
||||
|
||||
nokaslr [X86]
|
||||
Disable kernel base offset ASLR (Address Space
|
||||
Layout Randomization) if built into the kernel.
|
||||
Disable kernel and module base offset ASLR (Address
|
||||
Space Layout Randomization) if built into the kernel.
|
||||
|
||||
noautogroup Disable scheduler automatic task group creation.
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
@ -43,13 +44,49 @@ do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RANDOMIZE_BASE
|
||||
static unsigned long module_load_offset;
|
||||
static int randomize_modules = 1;
|
||||
|
||||
static int __init parse_nokaslr(char *p)
|
||||
{
|
||||
randomize_modules = 0;
|
||||
return 0;
|
||||
}
|
||||
early_param("nokaslr", parse_nokaslr);
|
||||
|
||||
static unsigned long int get_module_load_offset(void)
|
||||
{
|
||||
if (randomize_modules) {
|
||||
mutex_lock(&module_mutex);
|
||||
/*
|
||||
* Calculate the module_load_offset the first time this
|
||||
* code is called. Once calculated it stays the same until
|
||||
* reboot.
|
||||
*/
|
||||
if (module_load_offset == 0)
|
||||
module_load_offset =
|
||||
(get_random_int() % 1024 + 1) * PAGE_SIZE;
|
||||
mutex_unlock(&module_mutex);
|
||||
}
|
||||
return module_load_offset;
|
||||
}
|
||||
#else
|
||||
static unsigned long int get_module_load_offset(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
if (PAGE_ALIGN(size) > MODULES_LEN)
|
||||
return NULL;
|
||||
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
|
||||
GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
|
||||
NUMA_NO_NODE, __builtin_return_address(0));
|
||||
return __vmalloc_node_range(size, 1,
|
||||
MODULES_VADDR + get_module_load_offset(),
|
||||
MODULES_END, GFP_KERNEL | __GFP_HIGHMEM,
|
||||
PAGE_KERNEL_EXEC, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
|
Loading…
Reference in New Issue
Block a user