diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/kernel/module.c b/kernel/module.c index 7576c2d9462f..0d8d21ee792c 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -102,7 +102,7 @@ static inline int strong_try_module_get(struct module *mod) | |||
102 | static inline void add_taint_module(struct module *mod, unsigned flag) | 102 | static inline void add_taint_module(struct module *mod, unsigned flag) |
103 | { | 103 | { |
104 | add_taint(flag); | 104 | add_taint(flag); |
105 | mod->taints |= flag; | 105 | mod->taints |= (1U << flag); |
106 | } | 106 | } |
107 | 107 | ||
108 | /* | 108 | /* |
@@ -786,6 +786,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
786 | mutex_lock(&module_mutex); | 786 | mutex_lock(&module_mutex); |
787 | /* Store the name of the last unloaded module for diagnostic purposes */ | 787 | /* Store the name of the last unloaded module for diagnostic purposes */ |
788 | strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); | 788 | strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); |
789 | unregister_dynamic_debug_module(mod->name); | ||
789 | free_module(mod); | 790 | free_module(mod); |
790 | 791 | ||
791 | out: | 792 | out: |
@@ -925,7 +926,7 @@ static const char vermagic[] = VERMAGIC_STRING; | |||
925 | static int try_to_force_load(struct module *mod, const char *symname) | 926 | static int try_to_force_load(struct module *mod, const char *symname) |
926 | { | 927 | { |
927 | #ifdef CONFIG_MODULE_FORCE_LOAD | 928 | #ifdef CONFIG_MODULE_FORCE_LOAD |
928 | if (!(tainted & TAINT_FORCED_MODULE)) | 929 | if (!test_taint(TAINT_FORCED_MODULE)) |
929 | printk("%s: no version for \"%s\" found: kernel tainted.\n", | 930 | printk("%s: no version for \"%s\" found: kernel tainted.\n", |
930 | mod->name, symname); | 931 | mod->name, symname); |
931 | add_taint_module(mod, TAINT_FORCED_MODULE); | 932 | add_taint_module(mod, TAINT_FORCED_MODULE); |
@@ -1035,7 +1036,7 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, | |||
1035 | const unsigned long *crc; | 1036 | const unsigned long *crc; |
1036 | 1037 | ||
1037 | ret = find_symbol(name, &owner, &crc, | 1038 | ret = find_symbol(name, &owner, &crc, |
1038 | !(mod->taints & TAINT_PROPRIETARY_MODULE), true); | 1039 | !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); |
1039 | if (!IS_ERR_VALUE(ret)) { | 1040 | if (!IS_ERR_VALUE(ret)) { |
1040 | /* use_module can fail due to OOM, | 1041 | /* use_module can fail due to OOM, |
1041 | or module initialization or unloading */ | 1042 | or module initialization or unloading */ |
@@ -1175,7 +1176,7 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs, | |||
1175 | while (i-- > 0) | 1176 | while (i-- > 0) |
1176 | sysfs_remove_bin_file(notes_attrs->dir, | 1177 | sysfs_remove_bin_file(notes_attrs->dir, |
1177 | ¬es_attrs->attrs[i]); | 1178 | ¬es_attrs->attrs[i]); |
1178 | kobject_del(notes_attrs->dir); | 1179 | kobject_put(notes_attrs->dir); |
1179 | } | 1180 | } |
1180 | kfree(notes_attrs); | 1181 | kfree(notes_attrs); |
1181 | } | 1182 | } |
@@ -1639,7 +1640,7 @@ static void set_license(struct module *mod, const char *license) | |||
1639 | license = "unspecified"; | 1640 | license = "unspecified"; |
1640 | 1641 | ||
1641 | if (!license_is_gpl_compatible(license)) { | 1642 | if (!license_is_gpl_compatible(license)) { |
1642 | if (!(tainted & TAINT_PROPRIETARY_MODULE)) | 1643 | if (!test_taint(TAINT_PROPRIETARY_MODULE)) |
1643 | printk(KERN_WARNING "%s: module license '%s' taints " | 1644 | printk(KERN_WARNING "%s: module license '%s' taints " |
1644 | "kernel.\n", mod->name, license); | 1645 | "kernel.\n", mod->name, license); |
1645 | add_taint_module(mod, TAINT_PROPRIETARY_MODULE); | 1646 | add_taint_module(mod, TAINT_PROPRIETARY_MODULE); |
@@ -1788,6 +1789,33 @@ static inline void add_kallsyms(struct module *mod, | |||
1788 | } | 1789 | } |
1789 | #endif /* CONFIG_KALLSYMS */ | 1790 | #endif /* CONFIG_KALLSYMS */ |
1790 | 1791 | ||
1792 | #ifdef CONFIG_DYNAMIC_PRINTK_DEBUG | ||
1793 | static void dynamic_printk_setup(Elf_Shdr *sechdrs, unsigned int verboseindex) | ||
1794 | { | ||
1795 | struct mod_debug *debug_info; | ||
1796 | unsigned long pos, end; | ||
1797 | unsigned int num_verbose; | ||
1798 | |||
1799 | pos = sechdrs[verboseindex].sh_addr; | ||
1800 | num_verbose = sechdrs[verboseindex].sh_size / | ||
1801 | sizeof(struct mod_debug); | ||
1802 | end = pos + (num_verbose * sizeof(struct mod_debug)); | ||
1803 | |||
1804 | for (; pos < end; pos += sizeof(struct mod_debug)) { | ||
1805 | debug_info = (struct mod_debug *)pos; | ||
1806 | register_dynamic_debug_module(debug_info->modname, | ||
1807 | debug_info->type, debug_info->logical_modname, | ||
1808 | debug_info->flag_names, debug_info->hash, | ||
1809 | debug_info->hash2); | ||
1810 | } | ||
1811 | } | ||
1812 | #else | ||
1813 | static inline void dynamic_printk_setup(Elf_Shdr *sechdrs, | ||
1814 | unsigned int verboseindex) | ||
1815 | { | ||
1816 | } | ||
1817 | #endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */ | ||
1818 | |||
1791 | static void *module_alloc_update_bounds(unsigned long size) | 1819 | static void *module_alloc_update_bounds(unsigned long size) |
1792 | { | 1820 | { |
1793 | void *ret = module_alloc(size); | 1821 | void *ret = module_alloc(size); |
@@ -1811,6 +1839,7 @@ static noinline struct module *load_module(void __user *umod, | |||
1811 | Elf_Ehdr *hdr; | 1839 | Elf_Ehdr *hdr; |
1812 | Elf_Shdr *sechdrs; | 1840 | Elf_Shdr *sechdrs; |
1813 | char *secstrings, *args, *modmagic, *strtab = NULL; | 1841 | char *secstrings, *args, *modmagic, *strtab = NULL; |
1842 | char *staging; | ||
1814 | unsigned int i; | 1843 | unsigned int i; |
1815 | unsigned int symindex = 0; | 1844 | unsigned int symindex = 0; |
1816 | unsigned int strindex = 0; | 1845 | unsigned int strindex = 0; |
@@ -1836,6 +1865,7 @@ static noinline struct module *load_module(void __user *umod, | |||
1836 | #endif | 1865 | #endif |
1837 | unsigned int markersindex; | 1866 | unsigned int markersindex; |
1838 | unsigned int markersstringsindex; | 1867 | unsigned int markersstringsindex; |
1868 | unsigned int verboseindex; | ||
1839 | unsigned int tracepointsindex; | 1869 | unsigned int tracepointsindex; |
1840 | unsigned int tracepointsstringsindex; | 1870 | unsigned int tracepointsstringsindex; |
1841 | unsigned int mcountindex; | 1871 | unsigned int mcountindex; |
@@ -1969,6 +1999,14 @@ static noinline struct module *load_module(void __user *umod, | |||
1969 | goto free_hdr; | 1999 | goto free_hdr; |
1970 | } | 2000 | } |
1971 | 2001 | ||
2002 | staging = get_modinfo(sechdrs, infoindex, "staging"); | ||
2003 | if (staging) { | ||
2004 | add_taint_module(mod, TAINT_CRAP); | ||
2005 | printk(KERN_WARNING "%s: module is from the staging directory," | ||
2006 | " the quality is unknown, you have been warned.\n", | ||
2007 | mod->name); | ||
2008 | } | ||
2009 | |||
1972 | /* Now copy in args */ | 2010 | /* Now copy in args */ |
1973 | args = strndup_user(uargs, ~0UL >> 1); | 2011 | args = strndup_user(uargs, ~0UL >> 1); |
1974 | if (IS_ERR(args)) { | 2012 | if (IS_ERR(args)) { |
@@ -2126,6 +2164,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2126 | markersindex = find_sec(hdr, sechdrs, secstrings, "__markers"); | 2164 | markersindex = find_sec(hdr, sechdrs, secstrings, "__markers"); |
2127 | markersstringsindex = find_sec(hdr, sechdrs, secstrings, | 2165 | markersstringsindex = find_sec(hdr, sechdrs, secstrings, |
2128 | "__markers_strings"); | 2166 | "__markers_strings"); |
2167 | verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose"); | ||
2129 | tracepointsindex = find_sec(hdr, sechdrs, secstrings, "__tracepoints"); | 2168 | tracepointsindex = find_sec(hdr, sechdrs, secstrings, "__tracepoints"); |
2130 | tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings, | 2169 | tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings, |
2131 | "__tracepoints_strings"); | 2170 | "__tracepoints_strings"); |
@@ -2188,6 +2227,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2188 | marker_update_probe_range(mod->markers, | 2227 | marker_update_probe_range(mod->markers, |
2189 | mod->markers + mod->num_markers); | 2228 | mod->markers + mod->num_markers); |
2190 | #endif | 2229 | #endif |
2230 | dynamic_printk_setup(sechdrs, verboseindex); | ||
2191 | #ifdef CONFIG_TRACEPOINTS | 2231 | #ifdef CONFIG_TRACEPOINTS |
2192 | tracepoint_update_probe_range(mod->tracepoints, | 2232 | tracepoint_update_probe_range(mod->tracepoints, |
2193 | mod->tracepoints + mod->num_tracepoints); | 2233 | mod->tracepoints + mod->num_tracepoints); |
@@ -2584,10 +2624,12 @@ static char *module_flags(struct module *mod, char *buf) | |||
2584 | mod->state == MODULE_STATE_GOING || | 2624 | mod->state == MODULE_STATE_GOING || |
2585 | mod->state == MODULE_STATE_COMING) { | 2625 | mod->state == MODULE_STATE_COMING) { |
2586 | buf[bx++] = '('; | 2626 | buf[bx++] = '('; |
2587 | if (mod->taints & TAINT_PROPRIETARY_MODULE) | 2627 | if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE)) |
2588 | buf[bx++] = 'P'; | 2628 | buf[bx++] = 'P'; |
2589 | if (mod->taints & TAINT_FORCED_MODULE) | 2629 | if (mod->taints & (1 << TAINT_FORCED_MODULE)) |
2590 | buf[bx++] = 'F'; | 2630 | buf[bx++] = 'F'; |
2631 | if (mod->taints & (1 << TAINT_CRAP)) | ||
2632 | buf[bx++] = 'C'; | ||
2591 | /* | 2633 | /* |
2592 | * TAINT_FORCED_RMMOD: could be added. | 2634 | * TAINT_FORCED_RMMOD: could be added. |
2593 | * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't | 2635 | * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't |