diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-31 15:34:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-31 15:34:49 -0400 |
commit | e06df6a7eae1ab1ef4deb076aeeaed90e948e5c0 (patch) | |
tree | ff3a95036550939440f5cd2e7d251bb303b337f9 | |
parent | c0fc3cbac0a6fe40f98c5e5ed5f2df5e291bc94d (diff) | |
parent | 9dd721c6dbfc310f94306902611f86dda87a45fa (diff) |
Merge branch 'x86-kaslr-for-linus' of git://git.kernel.org/pub/scm/linux/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
-rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
-rw-r--r-- | arch/x86/kernel/module.c | 46 |
2 files changed, 45 insertions, 5 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 06600cc9a26c..67755ea834a7 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2060,8 +2060,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2060 | IOAPICs that may be present in the system. | 2060 | IOAPICs that may be present in the system. |
2061 | 2061 | ||
2062 | nokaslr [X86] | 2062 | nokaslr [X86] |
2063 | Disable kernel base offset ASLR (Address Space | 2063 | Disable kernel and module base offset ASLR (Address |
2064 | Layout Randomization) if built into the kernel. | 2064 | Space Layout Randomization) if built into the kernel. |
2065 | 2065 | ||
2066 | noautogroup Disable scheduler automatic task group creation. | 2066 | noautogroup Disable scheduler automatic task group creation. |
2067 | 2067 | ||
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 18be189368bb..e69f9882bf95 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/gfp.h> | 29 | #include <linux/gfp.h> |
30 | #include <linux/jump_label.h> | 30 | #include <linux/jump_label.h> |
31 | #include <linux/random.h> | ||
31 | 32 | ||
32 | #include <asm/page.h> | 33 | #include <asm/page.h> |
33 | #include <asm/pgtable.h> | 34 | #include <asm/pgtable.h> |
@@ -43,13 +44,52 @@ do { \ | |||
43 | } while (0) | 44 | } while (0) |
44 | #endif | 45 | #endif |
45 | 46 | ||
47 | #ifdef CONFIG_RANDOMIZE_BASE | ||
48 | static unsigned long module_load_offset; | ||
49 | static int randomize_modules = 1; | ||
50 | |||
51 | /* Mutex protects the module_load_offset. */ | ||
52 | static DEFINE_MUTEX(module_kaslr_mutex); | ||
53 | |||
54 | static int __init parse_nokaslr(char *p) | ||
55 | { | ||
56 | randomize_modules = 0; | ||
57 | return 0; | ||
58 | } | ||
59 | early_param("nokaslr", parse_nokaslr); | ||
60 | |||
61 | static unsigned long int get_module_load_offset(void) | ||
62 | { | ||
63 | if (randomize_modules) { | ||
64 | mutex_lock(&module_kaslr_mutex); | ||
65 | /* | ||
66 | * Calculate the module_load_offset the first time this | ||
67 | * code is called. Once calculated it stays the same until | ||
68 | * reboot. | ||
69 | */ | ||
70 | if (module_load_offset == 0) | ||
71 | module_load_offset = | ||
72 | (get_random_int() % 1024 + 1) * PAGE_SIZE; | ||
73 | mutex_unlock(&module_kaslr_mutex); | ||
74 | } | ||
75 | return module_load_offset; | ||
76 | } | ||
77 | #else | ||
78 | static unsigned long int get_module_load_offset(void) | ||
79 | { | ||
80 | return 0; | ||
81 | } | ||
82 | #endif | ||
83 | |||
46 | void *module_alloc(unsigned long size) | 84 | void *module_alloc(unsigned long size) |
47 | { | 85 | { |
48 | if (PAGE_ALIGN(size) > MODULES_LEN) | 86 | if (PAGE_ALIGN(size) > MODULES_LEN) |
49 | return NULL; | 87 | return NULL; |
50 | return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, | 88 | return __vmalloc_node_range(size, 1, |
51 | GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC, | 89 | MODULES_VADDR + get_module_load_offset(), |
52 | NUMA_NO_NODE, __builtin_return_address(0)); | 90 | MODULES_END, GFP_KERNEL | __GFP_HIGHMEM, |
91 | PAGE_KERNEL_EXEC, NUMA_NO_NODE, | ||
92 | __builtin_return_address(0)); | ||
53 | } | 93 | } |
54 | 94 | ||
55 | #ifdef CONFIG_X86_32 | 95 | #ifdef CONFIG_X86_32 |