diff options
Diffstat (limited to 'kernel/module.c')
| -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; |
