diff -Naurp linux-2.6.15-rc5-vanilla/kernel/module.c linux-2.6.15-rc5-mod/kernel/module.c --- linux-2.6.15-rc5-vanilla/kernel/module.c 2005-12-07 19:32:23.000000000 +0530 +++ linux-2.6.15-rc5-mod/kernel/module.c 2005-12-12 17:47:28.000000000 +0530 @@ -1204,6 +1204,63 @@ void *__symbol_get(const char *symbol) } EXPORT_SYMBOL_GPL(__symbol_get); +/* + * Ensure that an exported symbol [global namespace] does not already exist + * in the Kernel or in some other modules exported symbol table. + */ +static int verify_export_symbols(Elf_Shdr *sechdrs, + const char *strtab, + struct module *mod) +{ + struct kernel_symbol *exportsym, *gplsym; + unsigned long i,ret=0,value=0; + struct module *owner; + const unsigned long *crc; + unsigned long index=0; + + spin_lock_irq(&modlist_lock); + + exportsym = (struct kernel_symbol *)mod->syms; + gplsym = (struct kernel_symbol *)mod->gpl_syms; + + if (exportsym) + for (i = 0; i < mod->num_syms; exportsym++,i++) { + index = (unsigned long)(exportsym->name); + if (exportsym->name) { + value = __find_symbol(strtab + index, &owner, &crc,1); + + if (value != 0) + goto duplicate_sym; + } + } + + if (gplsym) + for (i = 0; i < mod->num_gpl_syms; gplsym++,i++) { + index = (unsigned long)(gplsym->name); + if (gplsym->name) { + value = __find_symbol(strtab + index, &owner, &crc,1); + + if (value != 0) + goto duplicate_gpl_sym; + } + } + + spin_unlock_irq(&modlist_lock); + /*Done*/ + return ret; + +duplicate_sym: + spin_unlock_irq(&modlist_lock); + printk("%s: Duplicate Exported Symbol found in %s\n", + strtab + index, mod->name); + return -ENOEXEC; +duplicate_gpl_sym: + spin_unlock_irq(&modlist_lock); + printk("%s: Duplicate Exported Symbol found in %s\n", + strtab + index, mod->name); + return -ENOEXEC; +} + /* Change all symbols so that sh_value encodes the pointer directly. */ static int simplify_symbols(Elf_Shdr *sechdrs, unsigned int symindex, @@ -1502,10 +1559,10 @@ static struct module *load_module(void _ { Elf_Ehdr *hdr; Elf_Shdr *sechdrs; - char *secstrings, *args, *modmagic, *strtab = NULL; + char *secstrings, *args, *modmagic, *strtab = NULL, *exportstrtab = NULL; unsigned int i, symindex = 0, strindex = 0, setupindex, exindex, - exportindex, modindex, obsparmindex, infoindex, gplindex, - crcindex, gplcrcindex, versindex, pcpuindex; + exportindex, exportstringindex, modindex, obsparmindex, infoindex, + gplindex, crcindex, gplcrcindex, versindex, pcpuindex; long arglen; struct module *mod; long err = 0; @@ -1585,6 +1642,7 @@ static struct module *load_module(void _ /* Optional sections */ exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); + exportstringindex = find_sec(hdr,sechdrs, secstrings, "__ksymtab_strings"); gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); @@ -1736,6 +1794,13 @@ static struct module *load_module(void _ if (gplcrcindex) mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; + /* Find duplicate symbols */ + exportstrtab = (void *)sechdrs[exportstringindex].sh_addr; + err = verify_export_symbols(sechdrs, exportstrtab, mod); + + if (err < 0) + goto cleanup; + #ifdef CONFIG_MODVERSIONS if ((mod->num_syms && !crcindex) || (mod->num_gpl_syms && !gplcrcindex)) {