]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.10.101/modules-fix-longstanding-proc-kallsyms-vs-module-insertion-race.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.10.101 / modules-fix-longstanding-proc-kallsyms-vs-module-insertion-race.patch
1 From 8244062ef1e54502ef55f54cced659913f244c3e Mon Sep 17 00:00:00 2001
2 From: Rusty Russell <rusty@rustcorp.com.au>
3 Date: Wed, 3 Feb 2016 16:55:26 +1030
4 Subject: modules: fix longstanding /proc/kallsyms vs module insertion race.
5
6 From: Rusty Russell <rusty@rustcorp.com.au>
7
8 commit 8244062ef1e54502ef55f54cced659913f244c3e upstream.
9
10 For CONFIG_KALLSYMS, we keep two symbol tables and two string tables.
11 There's one full copy, marked SHF_ALLOC and laid out at the end of the
12 module's init section. There's also a cut-down version that only
13 contains core symbols and strings, and lives in the module's core
14 section.
15
16 After module init (and before we free the module memory), we switch
17 the mod->symtab, mod->num_symtab and mod->strtab to point to the core
18 versions. We do this under the module_mutex.
19
20 However, kallsyms doesn't take the module_mutex: it uses
21 preempt_disable() and rcu tricks to walk through the modules, because
22 it's used in the oops path. It's also used in /proc/kallsyms.
23 There's nothing atomic about the change of these variables, so we can
24 get the old (larger!) num_symtab and the new symtab pointer; in fact
25 this is what I saw when trying to reproduce.
26
27 By grouping these variables together, we can use a
28 carefully-dereferenced pointer to ensure we always get one or the
29 other (the free of the module init section is already done in an RCU
30 callback, so that's safe). We allocate the init one at the end of the
31 module init section, and keep the core one inside the struct module
32 itself (it could also have been allocated at the end of the module
33 core, but that's probably overkill).
34
35 [ Rebased for 4.4-stable and older, because the following changes aren't
36 in the older trees:
37 - e0224418516b4d8a6c2160574bac18447c354ef0: adds arg to is_core_symbol
38 - 7523e4dc5057e157212b4741abd6256e03404cf1: module_init/module_core/init_size/core_size
39 become init_layout.base/core_layout.base/init_layout.size/core_layout.size.
40
41 Original commit: 8244062ef1e54502ef55f54cced659913f244c3e
42 ]
43
44 Reported-by: Weilong Chen <chenweilong@huawei.com>
45 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=111541
46 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
47 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
48
49 ---
50 include/linux/module.h | 17 +++----
51 kernel/module.c | 111 ++++++++++++++++++++++++++++++-------------------
52 2 files changed, 78 insertions(+), 50 deletions(-)
53
54 --- a/include/linux/module.h
55 +++ b/include/linux/module.h
56 @@ -220,6 +220,12 @@ struct module_ref {
57 unsigned long decs;
58 } __attribute((aligned(2 * sizeof(unsigned long))));
59
60 +struct mod_kallsyms {
61 + Elf_Sym *symtab;
62 + unsigned int num_symtab;
63 + char *strtab;
64 +};
65 +
66 struct module
67 {
68 enum module_state state;
69 @@ -308,14 +314,9 @@ struct module
70 #endif
71
72 #ifdef CONFIG_KALLSYMS
73 - /*
74 - * We keep the symbol and string tables for kallsyms.
75 - * The core_* fields below are temporary, loader-only (they
76 - * could really be discarded after module init).
77 - */
78 - Elf_Sym *symtab, *core_symtab;
79 - unsigned int num_symtab, core_num_syms;
80 - char *strtab, *core_strtab;
81 + /* Protected by RCU and/or module_mutex: use rcu_dereference() */
82 + struct mod_kallsyms *kallsyms;
83 + struct mod_kallsyms core_kallsyms;
84
85 /* Section attributes */
86 struct module_sect_attrs *sect_attrs;
87 --- a/kernel/module.c
88 +++ b/kernel/module.c
89 @@ -179,6 +179,9 @@ struct load_info {
90 struct _ddebug *debug;
91 unsigned int num_debug;
92 bool sig_ok;
93 +#ifdef CONFIG_KALLSYMS
94 + unsigned long mod_kallsyms_init_off;
95 +#endif
96 struct {
97 unsigned int sym, str, mod, vers, info, pcpu;
98 } index;
99 @@ -2346,8 +2349,20 @@ static void layout_symtab(struct module
100 strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
101 info->index.str) | INIT_OFFSET_MASK;
102 pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
103 +
104 + /* We'll tack temporary mod_kallsyms on the end. */
105 + mod->init_size = ALIGN(mod->init_size,
106 + __alignof__(struct mod_kallsyms));
107 + info->mod_kallsyms_init_off = mod->init_size;
108 + mod->init_size += sizeof(struct mod_kallsyms);
109 + mod->init_size = debug_align(mod->init_size);
110 }
111
112 +/*
113 + * We use the full symtab and strtab which layout_symtab arranged to
114 + * be appended to the init section. Later we switch to the cut-down
115 + * core-only ones.
116 + */
117 static void add_kallsyms(struct module *mod, const struct load_info *info)
118 {
119 unsigned int i, ndst;
120 @@ -2356,28 +2371,33 @@ static void add_kallsyms(struct module *
121 char *s;
122 Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
123
124 - mod->symtab = (void *)symsec->sh_addr;
125 - mod->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
126 + /* Set up to point into init section. */
127 + mod->kallsyms = mod->module_init + info->mod_kallsyms_init_off;
128 +
129 + mod->kallsyms->symtab = (void *)symsec->sh_addr;
130 + mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
131 /* Make sure we get permanent strtab: don't use info->strtab. */
132 - mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
133 + mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
134
135 /* Set types up while we still have access to sections. */
136 - for (i = 0; i < mod->num_symtab; i++)
137 - mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
138 -
139 - mod->core_symtab = dst = mod->module_core + info->symoffs;
140 - mod->core_strtab = s = mod->module_core + info->stroffs;
141 - src = mod->symtab;
142 - for (ndst = i = 0; i < mod->num_symtab; i++) {
143 + for (i = 0; i < mod->kallsyms->num_symtab; i++)
144 + mod->kallsyms->symtab[i].st_info
145 + = elf_type(&mod->kallsyms->symtab[i], info);
146 +
147 + /* Now populate the cut down core kallsyms for after init. */
148 + mod->core_kallsyms.symtab = dst = mod->module_core + info->symoffs;
149 + mod->core_kallsyms.strtab = s = mod->module_core + info->stroffs;
150 + src = mod->kallsyms->symtab;
151 + for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
152 if (i == 0 ||
153 is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
154 dst[ndst] = src[i];
155 - dst[ndst++].st_name = s - mod->core_strtab;
156 - s += strlcpy(s, &mod->strtab[src[i].st_name],
157 + dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
158 + s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
159 KSYM_NAME_LEN) + 1;
160 }
161 }
162 - mod->core_num_syms = ndst;
163 + mod->core_kallsyms.num_symtab = ndst;
164 }
165 #else
166 static inline void layout_symtab(struct module *mod, struct load_info *info)
167 @@ -3117,9 +3137,8 @@ static int do_init_module(struct module
168 module_put(mod);
169 trim_init_extable(mod);
170 #ifdef CONFIG_KALLSYMS
171 - mod->num_symtab = mod->core_num_syms;
172 - mod->symtab = mod->core_symtab;
173 - mod->strtab = mod->core_strtab;
174 + /* Switch to core kallsyms now init is done: kallsyms may be walking! */
175 + rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
176 #endif
177 unset_module_init_ro_nx(mod);
178 module_free(mod, mod->module_init);
179 @@ -3398,9 +3417,9 @@ static inline int is_arm_mapping_symbol(
180 && (str[2] == '\0' || str[2] == '.');
181 }
182
183 -static const char *symname(struct module *mod, unsigned int symnum)
184 +static const char *symname(struct mod_kallsyms *kallsyms, unsigned int symnum)
185 {
186 - return mod->strtab + mod->symtab[symnum].st_name;
187 + return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
188 }
189
190 static const char *get_ksymbol(struct module *mod,
191 @@ -3410,6 +3429,7 @@ static const char *get_ksymbol(struct mo
192 {
193 unsigned int i, best = 0;
194 unsigned long nextval;
195 + struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
196
197 /* At worse, next value is at end of module */
198 if (within_module_init(addr, mod))
199 @@ -3419,32 +3439,32 @@ static const char *get_ksymbol(struct mo
200
201 /* Scan for closest preceding symbol, and next symbol. (ELF
202 starts real symbols at 1). */
203 - for (i = 1; i < mod->num_symtab; i++) {
204 - if (mod->symtab[i].st_shndx == SHN_UNDEF)
205 + for (i = 1; i < kallsyms->num_symtab; i++) {
206 + if (kallsyms->symtab[i].st_shndx == SHN_UNDEF)
207 continue;
208
209 /* We ignore unnamed symbols: they're uninformative
210 * and inserted at a whim. */
211 - if (*symname(mod, i) == '\0'
212 - || is_arm_mapping_symbol(symname(mod, i)))
213 + if (*symname(kallsyms, i) == '\0'
214 + || is_arm_mapping_symbol(symname(kallsyms, i)))
215 continue;
216
217 - if (mod->symtab[i].st_value <= addr
218 - && mod->symtab[i].st_value > mod->symtab[best].st_value)
219 + if (kallsyms->symtab[i].st_value <= addr
220 + && kallsyms->symtab[i].st_value > kallsyms->symtab[best].st_value)
221 best = i;
222 - if (mod->symtab[i].st_value > addr
223 - && mod->symtab[i].st_value < nextval)
224 - nextval = mod->symtab[i].st_value;
225 + if (kallsyms->symtab[i].st_value > addr
226 + && kallsyms->symtab[i].st_value < nextval)
227 + nextval = kallsyms->symtab[i].st_value;
228 }
229
230 if (!best)
231 return NULL;
232
233 if (size)
234 - *size = nextval - mod->symtab[best].st_value;
235 + *size = nextval - kallsyms->symtab[best].st_value;
236 if (offset)
237 - *offset = addr - mod->symtab[best].st_value;
238 - return symname(mod, best);
239 + *offset = addr - kallsyms->symtab[best].st_value;
240 + return symname(kallsyms, best);
241 }
242
243 /* For kallsyms to ask for address resolution. NULL means not found. Careful
244 @@ -3540,18 +3560,21 @@ int module_get_kallsym(unsigned int symn
245
246 preempt_disable();
247 list_for_each_entry_rcu(mod, &modules, list) {
248 + struct mod_kallsyms *kallsyms;
249 +
250 if (mod->state == MODULE_STATE_UNFORMED)
251 continue;
252 - if (symnum < mod->num_symtab) {
253 - *value = mod->symtab[symnum].st_value;
254 - *type = mod->symtab[symnum].st_info;
255 - strlcpy(name, symname(mod, symnum), KSYM_NAME_LEN);
256 + kallsyms = rcu_dereference_sched(mod->kallsyms);
257 + if (symnum < kallsyms->num_symtab) {
258 + *value = kallsyms->symtab[symnum].st_value;
259 + *type = kallsyms->symtab[symnum].st_info;
260 + strlcpy(name, symname(kallsyms, symnum), KSYM_NAME_LEN);
261 strlcpy(module_name, mod->name, MODULE_NAME_LEN);
262 *exported = is_exported(name, *value, mod);
263 preempt_enable();
264 return 0;
265 }
266 - symnum -= mod->num_symtab;
267 + symnum -= kallsyms->num_symtab;
268 }
269 preempt_enable();
270 return -ERANGE;
271 @@ -3560,11 +3583,12 @@ int module_get_kallsym(unsigned int symn
272 static unsigned long mod_find_symname(struct module *mod, const char *name)
273 {
274 unsigned int i;
275 + struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
276
277 - for (i = 0; i < mod->num_symtab; i++)
278 - if (strcmp(name, symname(mod, i)) == 0 &&
279 - mod->symtab[i].st_info != 'U')
280 - return mod->symtab[i].st_value;
281 + for (i = 0; i < kallsyms->num_symtab; i++)
282 + if (strcmp(name, symname(kallsyms, i)) == 0 &&
283 + kallsyms->symtab[i].st_info != 'U')
284 + return kallsyms->symtab[i].st_value;
285 return 0;
286 }
287
288 @@ -3603,11 +3627,14 @@ int module_kallsyms_on_each_symbol(int (
289 int ret;
290
291 list_for_each_entry(mod, &modules, list) {
292 + /* We hold module_mutex: no need for rcu_dereference_sched */
293 + struct mod_kallsyms *kallsyms = mod->kallsyms;
294 +
295 if (mod->state == MODULE_STATE_UNFORMED)
296 continue;
297 - for (i = 0; i < mod->num_symtab; i++) {
298 - ret = fn(data, symname(mod, i),
299 - mod, mod->symtab[i].st_value);
300 + for (i = 0; i < kallsyms->num_symtab; i++) {
301 + ret = fn(data, symname(kallsyms, i),
302 + mod, kallsyms->symtab[i].st_value);
303 if (ret != 0)
304 return ret;
305 }