aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/module.c39
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}
1205EXPORT_SYMBOL_GPL(__symbol_get); 1205EXPORT_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 */
1211static 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
1232dup:
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. */
1208static int simplify_symbols(Elf_Shdr *sechdrs, 1241static 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;