diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/module.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/kernel/module.c b/kernel/module.c index 5d9078d6f0fa..fb6f091f5940 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -1204,6 +1204,39 @@ void *__symbol_get(const char *symbol) | |||
1204 | } | 1204 | } |
1205 | EXPORT_SYMBOL_GPL(__symbol_get); | 1205 | EXPORT_SYMBOL_GPL(__symbol_get); |
1206 | 1206 | ||
1207 | /* | ||
1208 | * Ensure that an exported symbol [global namespace] does not already exist | ||
1209 | * in the Kernel or in some other modules exported symbol table. | ||
1210 | */ | ||
1211 | static int verify_export_symbols(struct module *mod) | ||
1212 | { | ||
1213 | const char *name = NULL; | ||
1214 | unsigned long i, ret = 0; | ||
1215 | struct module *owner; | ||
1216 | const unsigned long *crc; | ||
1217 | |||
1218 | for (i = 0; i < mod->num_syms; i++) | ||
1219 | if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) { | ||
1220 | name = mod->syms[i].name; | ||
1221 | ret = -ENOEXEC; | ||
1222 | goto dup; | ||
1223 | } | ||
1224 | |||
1225 | for (i = 0; i < mod->num_gpl_syms; i++) | ||
1226 | if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) { | ||
1227 | name = mod->gpl_syms[i].name; | ||
1228 | ret = -ENOEXEC; | ||
1229 | goto dup; | ||
1230 | } | ||
1231 | |||
1232 | dup: | ||
1233 | if (ret) | ||
1234 | printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n", | ||
1235 | mod->name, name, module_name(owner)); | ||
1236 | |||
1237 | return ret; | ||
1238 | } | ||
1239 | |||
1207 | /* Change all symbols so that sh_value encodes the pointer directly. */ | 1240 | /* Change all symbols so that sh_value encodes the pointer directly. */ |
1208 | static int simplify_symbols(Elf_Shdr *sechdrs, | 1241 | static int simplify_symbols(Elf_Shdr *sechdrs, |
1209 | unsigned int symindex, | 1242 | unsigned int symindex, |
@@ -1772,6 +1805,12 @@ static struct module *load_module(void __user *umod, | |||
1772 | goto cleanup; | 1805 | goto cleanup; |
1773 | } | 1806 | } |
1774 | 1807 | ||
1808 | /* Find duplicate symbols */ | ||
1809 | err = verify_export_symbols(mod); | ||
1810 | |||
1811 | if (err < 0) | ||
1812 | goto cleanup; | ||
1813 | |||
1775 | /* Set up and sort exception table */ | 1814 | /* Set up and sort exception table */ |
1776 | mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable); | 1815 | mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable); |
1777 | mod->extable = extable = (void *)sechdrs[exindex].sh_addr; | 1816 | mod->extable = extable = (void *)sechdrs[exindex].sh_addr; |