diff options
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 94 |
1 files changed, 49 insertions, 45 deletions
diff --git a/kernel/module.c b/kernel/module.c index 7f60e782de1e..67009bd56c52 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -87,6 +87,12 @@ static inline int strong_try_module_get(struct module *mod) | |||
| 87 | return try_module_get(mod); | 87 | return try_module_get(mod); |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static inline void add_taint_module(struct module *mod, unsigned flag) | ||
| 91 | { | ||
| 92 | add_taint(flag); | ||
| 93 | mod->taints |= flag; | ||
| 94 | } | ||
| 95 | |||
| 90 | /* A thread that wants to hold a reference to a module only while it | 96 | /* A thread that wants to hold a reference to a module only while it |
| 91 | * is running can call ths to safely exit. | 97 | * is running can call ths to safely exit. |
| 92 | * nfsd and lockd use this. | 98 | * nfsd and lockd use this. |
| @@ -847,12 +853,10 @@ static int check_version(Elf_Shdr *sechdrs, | |||
| 847 | return 0; | 853 | return 0; |
| 848 | } | 854 | } |
| 849 | /* Not in module's version table. OK, but that taints the kernel. */ | 855 | /* Not in module's version table. OK, but that taints the kernel. */ |
| 850 | if (!(tainted & TAINT_FORCED_MODULE)) { | 856 | if (!(tainted & TAINT_FORCED_MODULE)) |
| 851 | printk("%s: no version for \"%s\" found: kernel tainted.\n", | 857 | printk("%s: no version for \"%s\" found: kernel tainted.\n", |
| 852 | mod->name, symname); | 858 | mod->name, symname); |
| 853 | add_taint(TAINT_FORCED_MODULE); | 859 | add_taint_module(mod, TAINT_FORCED_MODULE); |
| 854 | mod->taints |= TAINT_FORCED_MODULE; | ||
| 855 | } | ||
| 856 | return 1; | 860 | return 1; |
| 857 | } | 861 | } |
| 858 | 862 | ||
| @@ -910,7 +914,8 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, | |||
| 910 | unsigned long ret; | 914 | unsigned long ret; |
| 911 | const unsigned long *crc; | 915 | const unsigned long *crc; |
| 912 | 916 | ||
| 913 | ret = __find_symbol(name, &owner, &crc, mod->license_gplok); | 917 | ret = __find_symbol(name, &owner, &crc, |
| 918 | !(mod->taints & TAINT_PROPRIETARY_MODULE)); | ||
| 914 | if (ret) { | 919 | if (ret) { |
| 915 | /* use_module can fail due to OOM, or module unloading */ | 920 | /* use_module can fail due to OOM, or module unloading */ |
| 916 | if (!check_version(sechdrs, versindex, name, mod, crc) || | 921 | if (!check_version(sechdrs, versindex, name, mod, crc) || |
| @@ -1335,12 +1340,11 @@ static void set_license(struct module *mod, const char *license) | |||
| 1335 | if (!license) | 1340 | if (!license) |
| 1336 | license = "unspecified"; | 1341 | license = "unspecified"; |
| 1337 | 1342 | ||
| 1338 | mod->license_gplok = license_is_gpl_compatible(license); | 1343 | if (!license_is_gpl_compatible(license)) { |
| 1339 | if (!mod->license_gplok && !(tainted & TAINT_PROPRIETARY_MODULE)) { | 1344 | if (!(tainted & TAINT_PROPRIETARY_MODULE)) |
| 1340 | printk(KERN_WARNING "%s: module license '%s' taints kernel.\n", | 1345 | printk(KERN_WARNING "%s: module license '%s' taints" |
| 1341 | mod->name, license); | 1346 | "kernel.\n", mod->name, license); |
| 1342 | add_taint(TAINT_PROPRIETARY_MODULE); | 1347 | add_taint_module(mod, TAINT_PROPRIETARY_MODULE); |
| 1343 | mod->taints |= TAINT_PROPRIETARY_MODULE; | ||
| 1344 | } | 1348 | } |
| 1345 | } | 1349 | } |
| 1346 | 1350 | ||
| @@ -1619,8 +1623,7 @@ static struct module *load_module(void __user *umod, | |||
| 1619 | modmagic = get_modinfo(sechdrs, infoindex, "vermagic"); | 1623 | modmagic = get_modinfo(sechdrs, infoindex, "vermagic"); |
| 1620 | /* This is allowed: modprobe --force will invalidate it. */ | 1624 | /* This is allowed: modprobe --force will invalidate it. */ |
| 1621 | if (!modmagic) { | 1625 | if (!modmagic) { |
| 1622 | add_taint(TAINT_FORCED_MODULE); | 1626 | add_taint_module(mod, TAINT_FORCED_MODULE); |
| 1623 | mod->taints |= TAINT_FORCED_MODULE; | ||
| 1624 | printk(KERN_WARNING "%s: no version magic, tainting kernel.\n", | 1627 | printk(KERN_WARNING "%s: no version magic, tainting kernel.\n", |
| 1625 | mod->name); | 1628 | mod->name); |
| 1626 | } else if (!same_magic(modmagic, vermagic)) { | 1629 | } else if (!same_magic(modmagic, vermagic)) { |
| @@ -1714,14 +1717,10 @@ static struct module *load_module(void __user *umod, | |||
| 1714 | /* Set up license info based on the info section */ | 1717 | /* Set up license info based on the info section */ |
| 1715 | set_license(mod, get_modinfo(sechdrs, infoindex, "license")); | 1718 | set_license(mod, get_modinfo(sechdrs, infoindex, "license")); |
| 1716 | 1719 | ||
| 1717 | if (strcmp(mod->name, "ndiswrapper") == 0) { | 1720 | if (strcmp(mod->name, "ndiswrapper") == 0) |
| 1718 | add_taint(TAINT_PROPRIETARY_MODULE); | 1721 | add_taint_module(mod, TAINT_PROPRIETARY_MODULE); |
| 1719 | mod->taints |= TAINT_PROPRIETARY_MODULE; | 1722 | if (strcmp(mod->name, "driverloader") == 0) |
| 1720 | } | 1723 | add_taint_module(mod, TAINT_PROPRIETARY_MODULE); |
| 1721 | if (strcmp(mod->name, "driverloader") == 0) { | ||
| 1722 | add_taint(TAINT_PROPRIETARY_MODULE); | ||
| 1723 | mod->taints |= TAINT_PROPRIETARY_MODULE; | ||
| 1724 | } | ||
| 1725 | 1724 | ||
| 1726 | /* Set up MODINFO_ATTR fields */ | 1725 | /* Set up MODINFO_ATTR fields */ |
| 1727 | setup_modinfo(mod, sechdrs, infoindex); | 1726 | setup_modinfo(mod, sechdrs, infoindex); |
| @@ -1766,8 +1765,7 @@ static struct module *load_module(void __user *umod, | |||
| 1766 | (mod->num_unused_gpl_syms && !unusedgplcrcindex)) { | 1765 | (mod->num_unused_gpl_syms && !unusedgplcrcindex)) { |
| 1767 | printk(KERN_WARNING "%s: No versions for exported symbols." | 1766 | printk(KERN_WARNING "%s: No versions for exported symbols." |
| 1768 | " Tainting kernel.\n", mod->name); | 1767 | " Tainting kernel.\n", mod->name); |
| 1769 | add_taint(TAINT_FORCED_MODULE); | 1768 | add_taint_module(mod, TAINT_FORCED_MODULE); |
| 1770 | mod->taints |= TAINT_FORCED_MODULE; | ||
| 1771 | } | 1769 | } |
| 1772 | #endif | 1770 | #endif |
| 1773 | 1771 | ||
| @@ -2132,9 +2130,33 @@ static void m_stop(struct seq_file *m, void *p) | |||
| 2132 | mutex_unlock(&module_mutex); | 2130 | mutex_unlock(&module_mutex); |
| 2133 | } | 2131 | } |
| 2134 | 2132 | ||
| 2133 | static char *taint_flags(unsigned int taints, char *buf) | ||
| 2134 | { | ||
| 2135 | int bx = 0; | ||
| 2136 | |||
| 2137 | if (taints) { | ||
| 2138 | buf[bx++] = '('; | ||
| 2139 | if (taints & TAINT_PROPRIETARY_MODULE) | ||
| 2140 | buf[bx++] = 'P'; | ||
| 2141 | if (taints & TAINT_FORCED_MODULE) | ||
| 2142 | buf[bx++] = 'F'; | ||
| 2143 | /* | ||
| 2144 | * TAINT_FORCED_RMMOD: could be added. | ||
| 2145 | * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't | ||
| 2146 | * apply to modules. | ||
| 2147 | */ | ||
| 2148 | buf[bx++] = ')'; | ||
| 2149 | } | ||
| 2150 | buf[bx] = '\0'; | ||
| 2151 | |||
| 2152 | return buf; | ||
| 2153 | } | ||
| 2154 | |||
| 2135 | static int m_show(struct seq_file *m, void *p) | 2155 | static int m_show(struct seq_file *m, void *p) |
| 2136 | { | 2156 | { |
| 2137 | struct module *mod = list_entry(p, struct module, list); | 2157 | struct module *mod = list_entry(p, struct module, list); |
| 2158 | char buf[8]; | ||
| 2159 | |||
| 2138 | seq_printf(m, "%s %lu", | 2160 | seq_printf(m, "%s %lu", |
| 2139 | mod->name, mod->init_size + mod->core_size); | 2161 | mod->name, mod->init_size + mod->core_size); |
| 2140 | print_unload_info(m, mod); | 2162 | print_unload_info(m, mod); |
| @@ -2147,6 +2169,10 @@ static int m_show(struct seq_file *m, void *p) | |||
| 2147 | /* Used by oprofile and other similar tools. */ | 2169 | /* Used by oprofile and other similar tools. */ |
| 2148 | seq_printf(m, " 0x%p", mod->module_core); | 2170 | seq_printf(m, " 0x%p", mod->module_core); |
| 2149 | 2171 | ||
| 2172 | /* Taints info */ | ||
| 2173 | if (mod->taints) | ||
| 2174 | seq_printf(m, " %s", taint_flags(mod->taints, buf)); | ||
| 2175 | |||
| 2150 | seq_printf(m, "\n"); | 2176 | seq_printf(m, "\n"); |
| 2151 | return 0; | 2177 | return 0; |
| 2152 | } | 2178 | } |
| @@ -2235,28 +2261,6 @@ struct module *module_text_address(unsigned long addr) | |||
| 2235 | return mod; | 2261 | return mod; |
| 2236 | } | 2262 | } |
| 2237 | 2263 | ||
| 2238 | static char *taint_flags(unsigned int taints, char *buf) | ||
| 2239 | { | ||
| 2240 | *buf = '\0'; | ||
| 2241 | if (taints) { | ||
| 2242 | int bx; | ||
| 2243 | |||
| 2244 | buf[0] = '('; | ||
| 2245 | bx = 1; | ||
| 2246 | if (taints & TAINT_PROPRIETARY_MODULE) | ||
| 2247 | buf[bx++] = 'P'; | ||
| 2248 | if (taints & TAINT_FORCED_MODULE) | ||
| 2249 | buf[bx++] = 'F'; | ||
| 2250 | /* | ||
| 2251 | * TAINT_FORCED_RMMOD: could be added. | ||
| 2252 | * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't | ||
| 2253 | * apply to modules. | ||
| 2254 | */ | ||
| 2255 | buf[bx] = ')'; | ||
| 2256 | } | ||
| 2257 | return buf; | ||
| 2258 | } | ||
| 2259 | |||
| 2260 | /* Don't grab lock, we're oopsing. */ | 2264 | /* Don't grab lock, we're oopsing. */ |
| 2261 | void print_modules(void) | 2265 | void print_modules(void) |
| 2262 | { | 2266 | { |
