diff options
author | Heiko Carstens <hca@linux.ibm.com> | 2023-03-31 15:03:23 +0200 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2023-04-13 17:36:26 +0200 |
commit | 34644cc2e15a7a91ec36b496e218694d17371589 (patch) | |
tree | 462ff34d8a9610c6ea286ece35ed324bad27207a /arch/s390/kernel/module.c | |
parent | s390/kaslr: provide kaslr_enabled() function (diff) | |
download | linux-34644cc2e15a7a91ec36b496e218694d17371589.tar.xz linux-34644cc2e15a7a91ec36b496e218694d17371589.zip |
s390/kaslr: randomize module base load address
Randomize the load address of modules in the kernel to make KASLR effective
for modules.
This is the s390 variant of commit e2b32e678513 ("x86, kaslr: randomize
module base load address").
Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390/kernel/module.c')
-rw-r--r-- | arch/s390/kernel/module.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 2d159b32885b..6588f4efe378 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -26,6 +26,7 @@ #include <asm/facility.h> #include <asm/ftrace.lds.h> #include <asm/set_memory.h> +#include <asm/setup.h> #if 0 #define DEBUGP printk @@ -35,6 +36,24 @@ #define PLT_ENTRY_SIZE 22 +static unsigned long get_module_load_offset(void) +{ + static DEFINE_MUTEX(module_kaslr_mutex); + static unsigned long module_load_offset; + + if (!kaslr_enabled()) + return 0; + /* + * Calculate the module_load_offset the first time this code + * is called. Once calculated it stays the same until reboot. + */ + mutex_lock(&module_kaslr_mutex); + if (!module_load_offset) + module_load_offset = get_random_u32_inclusive(1, 1024) * PAGE_SIZE; + mutex_unlock(&module_kaslr_mutex); + return module_load_offset; +} + void *module_alloc(unsigned long size) { gfp_t gfp_mask = GFP_KERNEL; @@ -42,7 +61,8 @@ void *module_alloc(unsigned long size) if (PAGE_ALIGN(size) > MODULES_LEN) return NULL; - p = __vmalloc_node_range(size, MODULE_ALIGN, MODULES_VADDR, MODULES_END, + p = __vmalloc_node_range(size, MODULE_ALIGN, + MODULES_VADDR + get_module_load_offset(), MODULES_END, gfp_mask, PAGE_KERNEL_EXEC, VM_DEFER_KMEMLEAK, NUMA_NO_NODE, __builtin_return_address(0)); if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) { |