diff options
author | Alexey Dobriyan <adobriyan@sw.ru> | 2007-05-08 03:28:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:08 -0400 |
commit | ea07890a680273b25127129fb555aac0d9324bea (patch) | |
tree | b0742aa5dd90792dc10be3563c1181582d0f5d9e /kernel/kallsyms.c | |
parent | ae84e324709d6320ed8c1fd7b1736fcbaf26df95 (diff) |
Fix race between rmmod and cat /proc/kallsyms
module_get_kallsym() leaks "struct module *" outside of module_mutex which is
no-no, because module can dissapear right after mutex unlock.
Copy all needed information from inside module_mutex into caller-supplied
space.
[bunk@stusta.de: is_exported() can now become static]
Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/kallsyms.c')
-rw-r--r-- | kernel/kallsyms.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index d086c91d44ed..f1ea6f66ac6c 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c | |||
@@ -301,25 +301,20 @@ void __print_symbol(const char *fmt, unsigned long address) | |||
301 | struct kallsym_iter | 301 | struct kallsym_iter |
302 | { | 302 | { |
303 | loff_t pos; | 303 | loff_t pos; |
304 | struct module *owner; | ||
305 | unsigned long value; | 304 | unsigned long value; |
306 | unsigned int nameoff; /* If iterating in core kernel symbols */ | 305 | unsigned int nameoff; /* If iterating in core kernel symbols */ |
307 | char type; | 306 | char type; |
308 | char name[KSYM_NAME_LEN+1]; | 307 | char name[KSYM_NAME_LEN+1]; |
308 | char module_name[MODULE_NAME_LEN + 1]; | ||
309 | int exported; | ||
309 | }; | 310 | }; |
310 | 311 | ||
311 | static int get_ksymbol_mod(struct kallsym_iter *iter) | 312 | static int get_ksymbol_mod(struct kallsym_iter *iter) |
312 | { | 313 | { |
313 | iter->owner = module_get_kallsym(iter->pos - kallsyms_num_syms, | 314 | if (module_get_kallsym(iter->pos - kallsyms_num_syms, &iter->value, |
314 | &iter->value, &iter->type, | 315 | &iter->type, iter->name, iter->module_name, |
315 | iter->name); | 316 | &iter->exported) < 0) |
316 | if (iter->owner == NULL) | ||
317 | return 0; | 317 | return 0; |
318 | |||
319 | /* Label it "global" if it is exported, "local" if not exported. */ | ||
320 | iter->type = is_exported(iter->name, iter->owner) | ||
321 | ? toupper(iter->type) : tolower(iter->type); | ||
322 | |||
323 | return 1; | 318 | return 1; |
324 | } | 319 | } |
325 | 320 | ||
@@ -328,7 +323,7 @@ static unsigned long get_ksymbol_core(struct kallsym_iter *iter) | |||
328 | { | 323 | { |
329 | unsigned off = iter->nameoff; | 324 | unsigned off = iter->nameoff; |
330 | 325 | ||
331 | iter->owner = NULL; | 326 | iter->module_name[0] = '\0'; |
332 | iter->value = kallsyms_addresses[iter->pos]; | 327 | iter->value = kallsyms_addresses[iter->pos]; |
333 | 328 | ||
334 | iter->type = kallsyms_get_symbol_type(off); | 329 | iter->type = kallsyms_get_symbol_type(off); |
@@ -392,12 +387,17 @@ static int s_show(struct seq_file *m, void *p) | |||
392 | if (!iter->name[0]) | 387 | if (!iter->name[0]) |
393 | return 0; | 388 | return 0; |
394 | 389 | ||
395 | if (iter->owner) | 390 | if (iter->module_name[0]) { |
391 | char type; | ||
392 | |||
393 | /* Label it "global" if it is exported, | ||
394 | * "local" if not exported. */ | ||
395 | type = iter->exported ? toupper(iter->type) : | ||
396 | tolower(iter->type); | ||
396 | seq_printf(m, "%0*lx %c %s\t[%s]\n", | 397 | seq_printf(m, "%0*lx %c %s\t[%s]\n", |
397 | (int)(2*sizeof(void*)), | 398 | (int)(2*sizeof(void*)), |
398 | iter->value, iter->type, iter->name, | 399 | iter->value, type, iter->name, iter->module_name); |
399 | module_name(iter->owner)); | 400 | } else |
400 | else | ||
401 | seq_printf(m, "%0*lx %c %s\n", | 401 | seq_printf(m, "%0*lx %c %s\n", |
402 | (int)(2*sizeof(void*)), | 402 | (int)(2*sizeof(void*)), |
403 | iter->value, iter->type, iter->name); | 403 | iter->value, iter->type, iter->name); |