Skip to content

Commit

Permalink
Merge branch 'x86-kaslr-for-linus' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/tip/tip

Pull x86 kaslr update from Ingo Molnar:
 "This adds kernel module load address randomization"

* 'x86-kaslr-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86, kaslr: fix module lock ordering problem
  x86, kaslr: randomize module base load address
  • Loading branch information
Linus Torvalds committed Mar 31, 2014
2 parents c0fc3cb + 9dd721c commit e06df6a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
4 changes: 2 additions & 2 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2060,8 +2060,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.

Expand Down
46 changes: 43 additions & 3 deletions arch/x86/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -43,13 +44,52 @@ do { \
} while (0)
#endif

#ifdef CONFIG_RANDOMIZE_BASE
static unsigned long module_load_offset;
static int randomize_modules = 1;

/* Mutex protects the module_load_offset. */
static DEFINE_MUTEX(module_kaslr_mutex);

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_kaslr_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_kaslr_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
Expand Down

0 comments on commit e06df6a

Please sign in to comment.