diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2008-05-01 22:15:00 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2008-05-01 07:15:00 -0400 |
commit | b211104d111c99dbb97c636b57bd9db711455684 (patch) | |
tree | 129d949287a17457f3a8081dd6f04b8a945bcb29 /kernel/module.c | |
parent | 4e2d92454b2d822fe1d474efabccc2a3806d5f86 (diff) |
module: Enhance verify_export_symbols
Make verify_export_symbols check the modules unused, unused_gpl and
gpl_future syms.
Inspired by Jan Beulich's fix, but table-driven.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/kernel/module.c b/kernel/module.c index ee918938518a..d2d093e74165 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -1400,33 +1400,33 @@ EXPORT_SYMBOL_GPL(__symbol_get); | |||
1400 | */ | 1400 | */ |
1401 | static int verify_export_symbols(struct module *mod) | 1401 | static int verify_export_symbols(struct module *mod) |
1402 | { | 1402 | { |
1403 | const char *name = NULL; | 1403 | unsigned int i; |
1404 | unsigned long i, ret = 0; | ||
1405 | struct module *owner; | 1404 | struct module *owner; |
1406 | const unsigned long *crc; | 1405 | const struct kernel_symbol *s; |
1407 | 1406 | struct { | |
1408 | for (i = 0; i < mod->num_syms; i++) | 1407 | const struct kernel_symbol *sym; |
1409 | if (!IS_ERR_VALUE(find_symbol(mod->syms[i].name, | 1408 | unsigned int num; |
1410 | &owner, &crc, true, false))) { | 1409 | } arr[] = { |
1411 | name = mod->syms[i].name; | 1410 | { mod->syms, mod->num_syms }, |
1412 | ret = -ENOEXEC; | 1411 | { mod->gpl_syms, mod->num_gpl_syms }, |
1413 | goto dup; | 1412 | { mod->gpl_future_syms, mod->num_gpl_future_syms }, |
1414 | } | 1413 | { mod->unused_syms, mod->num_unused_syms }, |
1414 | { mod->unused_gpl_syms, mod->num_unused_gpl_syms }, | ||
1415 | }; | ||
1415 | 1416 | ||
1416 | for (i = 0; i < mod->num_gpl_syms; i++) | 1417 | for (i = 0; i < ARRAY_SIZE(arr); i++) { |
1417 | if (!IS_ERR_VALUE(find_symbol(mod->gpl_syms[i].name, | 1418 | for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) { |
1418 | &owner, &crc, true, false))) { | 1419 | if (!IS_ERR_VALUE(find_symbol(s->name, &owner, |
1419 | name = mod->gpl_syms[i].name; | 1420 | NULL, true, false))) { |
1420 | ret = -ENOEXEC; | 1421 | printk(KERN_ERR |
1421 | goto dup; | 1422 | "%s: exports duplicate symbol %s" |
1423 | " (owned by %s)\n", | ||
1424 | mod->name, s->name, module_name(owner)); | ||
1425 | return -ENOEXEC; | ||
1426 | } | ||
1422 | } | 1427 | } |
1423 | 1428 | } | |
1424 | dup: | 1429 | return 0; |
1425 | if (ret) | ||
1426 | printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n", | ||
1427 | mod->name, name, module_name(owner)); | ||
1428 | |||
1429 | return ret; | ||
1430 | } | 1430 | } |
1431 | 1431 | ||
1432 | /* Change all symbols so that st_value encodes the pointer directly. */ | 1432 | /* Change all symbols so that st_value encodes the pointer directly. */ |