diff options
| -rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/module.c | 43 |
2 files changed, 42 insertions, 5 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 7116fda7077f..580a60cabd9b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -2053,8 +2053,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
| 2053 | IOAPICs that may be present in the system. | 2053 | IOAPICs that may be present in the system. |
| 2054 | 2054 | ||
| 2055 | nokaslr [X86] | 2055 | nokaslr [X86] |
| 2056 | Disable kernel base offset ASLR (Address Space | 2056 | Disable kernel and module base offset ASLR (Address |
| 2057 | Layout Randomization) if built into the kernel. | 2057 | Space Layout Randomization) if built into the kernel. |
| 2058 | 2058 | ||
| 2059 | noautogroup Disable scheduler automatic task group creation. | 2059 | noautogroup Disable scheduler automatic task group creation. |
| 2060 | 2060 | ||
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 18be189368bb..49483137371f 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,49 @@ 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 | 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 | |||
| 46 | void *module_alloc(unsigned long size) | 81 | void *module_alloc(unsigned long size) |
| 47 | { | 82 | { |
| 48 | if (PAGE_ALIGN(size) > MODULES_LEN) | 83 | if (PAGE_ALIGN(size) > MODULES_LEN) |
| 49 | return NULL; | 84 | return NULL; |
| 50 | return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, | 85 | return __vmalloc_node_range(size, 1, |
| 51 | GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC, | 86 | MODULES_VADDR + get_module_load_offset(), |
| 52 | NUMA_NO_NODE, __builtin_return_address(0)); | 87 | MODULES_END, GFP_KERNEL | __GFP_HIGHMEM, |
| 88 | PAGE_KERNEL_EXEC, NUMA_NO_NODE, | ||
| 89 | __builtin_return_address(0)); | ||
| 53 | } | 90 | } |
| 54 | 91 | ||
| 55 | #ifdef CONFIG_X86_32 | 92 | #ifdef CONFIG_X86_32 |
