aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorAshutosh Naik <ashutosh.naik@gmail.com>2006-01-08 04:04:25 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-08 23:14:03 -0500
commiteea8b54dc0dceb740da697a89c54d20dde340306 (patch)
treec5f42385a174aa38aeb251eec361557a2b31d047 /kernel/module.c
parentb368fae6abaa1736b8f26128c32947d47237b8e5 (diff)
[PATCH] modules: prevent overriding of symbols
Ensure that an exported symbol does not already exist in the kernel or in some other module's exported symbol table. This is done by checking the symbol tables for the exported symbol at the time of loading the module. Currently this is done after the relocation of the symbol. Signed-off-by: Ashutosh Naik <ashutosh.naik@gmail.com> Signed-off-by: Anand Krishnan <anandhkrishnan@yahoo.co.in> Cc: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/module.c')
-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;