|
12 | 12 | #include <linux/bitops.h> |
13 | 13 | #include <linux/elf.h> |
14 | 14 | #include <linux/ftrace.h> |
15 | | -#include <linux/gfp.h> |
16 | 15 | #include <linux/kasan.h> |
17 | 16 | #include <linux/kernel.h> |
18 | 17 | #include <linux/mm.h> |
19 | 18 | #include <linux/moduleloader.h> |
20 | 19 | #include <linux/random.h> |
21 | 20 | #include <linux/scs.h> |
22 | | -#include <linux/vmalloc.h> |
23 | 21 |
|
24 | 22 | #include <asm/alternative.h> |
25 | 23 | #include <asm/insn.h> |
26 | 24 | #include <asm/scs.h> |
27 | 25 | #include <asm/sections.h> |
28 | 26 |
|
29 | | -static u64 module_direct_base __ro_after_init = 0; |
30 | | -static u64 module_plt_base __ro_after_init = 0; |
31 | | - |
32 | | -/* |
33 | | - * Choose a random page-aligned base address for a window of 'size' bytes which |
34 | | - * entirely contains the interval [start, end - 1]. |
35 | | - */ |
36 | | -static u64 __init random_bounding_box(u64 size, u64 start, u64 end) |
37 | | -{ |
38 | | - u64 max_pgoff, pgoff; |
39 | | - |
40 | | - if ((end - start) >= size) |
41 | | - return 0; |
42 | | - |
43 | | - max_pgoff = (size - (end - start)) / PAGE_SIZE; |
44 | | - pgoff = get_random_u32_inclusive(0, max_pgoff); |
45 | | - |
46 | | - return start - pgoff * PAGE_SIZE; |
47 | | -} |
48 | | - |
49 | | -/* |
50 | | - * Modules may directly reference data and text anywhere within the kernel |
51 | | - * image and other modules. References using PREL32 relocations have a +/-2G |
52 | | - * range, and so we need to ensure that the entire kernel image and all modules |
53 | | - * fall within a 2G window such that these are always within range. |
54 | | - * |
55 | | - * Modules may directly branch to functions and code within the kernel text, |
56 | | - * and to functions and code within other modules. These branches will use |
57 | | - * CALL26/JUMP26 relocations with a +/-128M range. Without PLTs, we must ensure |
58 | | - * that the entire kernel text and all module text falls within a 128M window |
59 | | - * such that these are always within range. With PLTs, we can expand this to a |
60 | | - * 2G window. |
61 | | - * |
62 | | - * We chose the 128M region to surround the entire kernel image (rather than |
63 | | - * just the text) as using the same bounds for the 128M and 2G regions ensures |
64 | | - * by construction that we never select a 128M region that is not a subset of |
65 | | - * the 2G region. For very large and unusual kernel configurations this means |
66 | | - * we may fall back to PLTs where they could have been avoided, but this keeps |
67 | | - * the logic significantly simpler. |
68 | | - */ |
69 | | -static int __init module_init_limits(void) |
70 | | -{ |
71 | | - u64 kernel_end = (u64)_end; |
72 | | - u64 kernel_start = (u64)_text; |
73 | | - u64 kernel_size = kernel_end - kernel_start; |
74 | | - |
75 | | - /* |
76 | | - * The default modules region is placed immediately below the kernel |
77 | | - * image, and is large enough to use the full 2G relocation range. |
78 | | - */ |
79 | | - BUILD_BUG_ON(KIMAGE_VADDR != MODULES_END); |
80 | | - BUILD_BUG_ON(MODULES_VSIZE < SZ_2G); |
81 | | - |
82 | | - if (!kaslr_enabled()) { |
83 | | - if (kernel_size < SZ_128M) |
84 | | - module_direct_base = kernel_end - SZ_128M; |
85 | | - if (kernel_size < SZ_2G) |
86 | | - module_plt_base = kernel_end - SZ_2G; |
87 | | - } else { |
88 | | - u64 min = kernel_start; |
89 | | - u64 max = kernel_end; |
90 | | - |
91 | | - if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) { |
92 | | - pr_info("2G module region forced by RANDOMIZE_MODULE_REGION_FULL\n"); |
93 | | - } else { |
94 | | - module_direct_base = random_bounding_box(SZ_128M, min, max); |
95 | | - if (module_direct_base) { |
96 | | - min = module_direct_base; |
97 | | - max = module_direct_base + SZ_128M; |
98 | | - } |
99 | | - } |
100 | | - |
101 | | - module_plt_base = random_bounding_box(SZ_2G, min, max); |
102 | | - } |
103 | | - |
104 | | - pr_info("%llu pages in range for non-PLT usage", |
105 | | - module_direct_base ? (SZ_128M - kernel_size) / PAGE_SIZE : 0); |
106 | | - pr_info("%llu pages in range for PLT usage", |
107 | | - module_plt_base ? (SZ_2G - kernel_size) / PAGE_SIZE : 0); |
108 | | - |
109 | | - return 0; |
110 | | -} |
111 | | -subsys_initcall(module_init_limits); |
112 | | - |
113 | | -void *module_alloc(unsigned long size) |
114 | | -{ |
115 | | - void *p = NULL; |
116 | | - |
117 | | - /* |
118 | | - * Where possible, prefer to allocate within direct branch range of the |
119 | | - * kernel such that no PLTs are necessary. |
120 | | - */ |
121 | | - if (module_direct_base) { |
122 | | - p = __vmalloc_node_range(size, MODULE_ALIGN, |
123 | | - module_direct_base, |
124 | | - module_direct_base + SZ_128M, |
125 | | - GFP_KERNEL | __GFP_NOWARN, |
126 | | - PAGE_KERNEL, 0, NUMA_NO_NODE, |
127 | | - __builtin_return_address(0)); |
128 | | - } |
129 | | - |
130 | | - if (!p && module_plt_base) { |
131 | | - p = __vmalloc_node_range(size, MODULE_ALIGN, |
132 | | - module_plt_base, |
133 | | - module_plt_base + SZ_2G, |
134 | | - GFP_KERNEL | __GFP_NOWARN, |
135 | | - PAGE_KERNEL, 0, NUMA_NO_NODE, |
136 | | - __builtin_return_address(0)); |
137 | | - } |
138 | | - |
139 | | - if (!p) { |
140 | | - pr_warn_ratelimited("%s: unable to allocate memory\n", |
141 | | - __func__); |
142 | | - } |
143 | | - |
144 | | - if (p && (kasan_alloc_module_shadow(p, size, GFP_KERNEL) < 0)) { |
145 | | - vfree(p); |
146 | | - return NULL; |
147 | | - } |
148 | | - |
149 | | - /* Memory is intended to be executable, reset the pointer tag. */ |
150 | | - return kasan_reset_tag(p); |
151 | | -} |
152 | | - |
153 | 27 | enum aarch64_reloc_op { |
154 | 28 | RELOC_OP_NONE, |
155 | 29 | RELOC_OP_ABS, |
|
0 commit comments