aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 4b06bbad49c2..e4276046a1b6 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -496,15 +496,15 @@ static void module_unload_free(struct module *mod)
496} 496}
497 497
498#ifdef CONFIG_MODULE_FORCE_UNLOAD 498#ifdef CONFIG_MODULE_FORCE_UNLOAD
499static inline int try_force(unsigned int flags) 499static inline int try_force_unload(unsigned int flags)
500{ 500{
501 int ret = (flags & O_TRUNC); 501 int ret = (flags & O_TRUNC);
502 if (ret) 502 if (ret)
503 add_taint(TAINT_FORCED_MODULE); 503 add_taint(TAINT_FORCED_RMMOD);
504 return ret; 504 return ret;
505} 505}
506#else 506#else
507static inline int try_force(unsigned int flags) 507static inline int try_force_unload(unsigned int flags)
508{ 508{
509 return 0; 509 return 0;
510} 510}
@@ -524,7 +524,7 @@ static int __try_stop_module(void *_sref)
524 524
525 /* If it's not unused, quit unless we are told to block. */ 525 /* If it's not unused, quit unless we are told to block. */
526 if ((sref->flags & O_NONBLOCK) && module_refcount(sref->mod) != 0) { 526 if ((sref->flags & O_NONBLOCK) && module_refcount(sref->mod) != 0) {
527 if (!(*sref->forced = try_force(sref->flags))) 527 if (!(*sref->forced = try_force_unload(sref->flags)))
528 return -EWOULDBLOCK; 528 return -EWOULDBLOCK;
529 } 529 }
530 530
@@ -609,7 +609,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
609 /* If it has an init func, it must have an exit func to unload */ 609 /* If it has an init func, it must have an exit func to unload */
610 if ((mod->init != NULL && mod->exit == NULL) 610 if ((mod->init != NULL && mod->exit == NULL)
611 || mod->unsafe) { 611 || mod->unsafe) {
612 forced = try_force(flags); 612 forced = try_force_unload(flags);
613 if (!forced) { 613 if (!forced) {
614 /* This module can't be removed */ 614 /* This module can't be removed */
615 ret = -EBUSY; 615 ret = -EBUSY;
@@ -958,7 +958,6 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
958 unsigned long ret; 958 unsigned long ret;
959 const unsigned long *crc; 959 const unsigned long *crc;
960 960
961 spin_lock_irq(&modlist_lock);
962 ret = __find_symbol(name, &owner, &crc, mod->license_gplok); 961 ret = __find_symbol(name, &owner, &crc, mod->license_gplok);
963 if (ret) { 962 if (ret) {
964 /* use_module can fail due to OOM, or module unloading */ 963 /* use_module can fail due to OOM, or module unloading */
@@ -966,7 +965,6 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
966 !use_module(mod, owner)) 965 !use_module(mod, owner))
967 ret = 0; 966 ret = 0;
968 } 967 }
969 spin_unlock_irq(&modlist_lock);
970 return ret; 968 return ret;
971} 969}
972 970
@@ -1204,6 +1202,39 @@ void *__symbol_get(const char *symbol)
1204} 1202}
1205EXPORT_SYMBOL_GPL(__symbol_get); 1203EXPORT_SYMBOL_GPL(__symbol_get);
1206 1204
1205/*
1206 * Ensure that an exported symbol [global namespace] does not already exist
1207 * in the Kernel or in some other modules exported symbol table.
1208 */
1209static int verify_export_symbols(struct module *mod)
1210{
1211 const char *name = NULL;
1212 unsigned long i, ret = 0;
1213 struct module *owner;
1214 const unsigned long *crc;
1215
1216 for (i = 0; i < mod->num_syms; i++)
1217 if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
1218 name = mod->syms[i].name;
1219 ret = -ENOEXEC;
1220 goto dup;
1221 }
1222
1223 for (i = 0; i < mod->num_gpl_syms; i++)
1224 if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
1225 name = mod->gpl_syms[i].name;
1226 ret = -ENOEXEC;
1227 goto dup;
1228 }
1229
1230dup:
1231 if (ret)
1232 printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n",
1233 mod->name, name, module_name(owner));
1234
1235 return ret;
1236}
1237
1207/* Change all symbols so that sh_value encodes the pointer directly. */ 1238/* Change all symbols so that sh_value encodes the pointer directly. */
1208static int simplify_symbols(Elf_Shdr *sechdrs, 1239static int simplify_symbols(Elf_Shdr *sechdrs,
1209 unsigned int symindex, 1240 unsigned int symindex,
@@ -1715,6 +1746,11 @@ static struct module *load_module(void __user *umod,
1715 /* Set up license info based on the info section */ 1746 /* Set up license info based on the info section */
1716 set_license(mod, get_modinfo(sechdrs, infoindex, "license")); 1747 set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
1717 1748
1749 if (strcmp(mod->name, "ndiswrapper") == 0)
1750 add_taint(TAINT_PROPRIETARY_MODULE);
1751 if (strcmp(mod->name, "driverloader") == 0)
1752 add_taint(TAINT_PROPRIETARY_MODULE);
1753
1718#ifdef CONFIG_MODULE_UNLOAD 1754#ifdef CONFIG_MODULE_UNLOAD
1719 /* Set up MODINFO_ATTR fields */ 1755 /* Set up MODINFO_ATTR fields */
1720 setup_modinfo(mod, sechdrs, infoindex); 1756 setup_modinfo(mod, sechdrs, infoindex);
@@ -1767,6 +1803,12 @@ static struct module *load_module(void __user *umod,
1767 goto cleanup; 1803 goto cleanup;
1768 } 1804 }
1769 1805
1806 /* Find duplicate symbols */
1807 err = verify_export_symbols(mod);
1808
1809 if (err < 0)
1810 goto cleanup;
1811
1770 /* Set up and sort exception table */ 1812 /* Set up and sort exception table */
1771 mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable); 1813 mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
1772 mod->extable = extable = (void *)sechdrs[exindex].sh_addr; 1814 mod->extable = extable = (void *)sechdrs[exindex].sh_addr;