diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 188 |
1 files changed, 157 insertions, 31 deletions
diff --git a/kernel/module.c b/kernel/module.c index 46580edff0cb..5a29397ca4b6 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/rculist.h> | 47 | #include <linux/rculist.h> |
48 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
49 | #include <asm/cacheflush.h> | 49 | #include <asm/cacheflush.h> |
50 | #include <asm/mmu_context.h> | ||
50 | #include <linux/license.h> | 51 | #include <linux/license.h> |
51 | #include <asm/sections.h> | 52 | #include <asm/sections.h> |
52 | #include <linux/tracepoint.h> | 53 | #include <linux/tracepoint.h> |
@@ -369,7 +370,7 @@ EXPORT_SYMBOL_GPL(find_module); | |||
369 | 370 | ||
370 | #ifdef CONFIG_SMP | 371 | #ifdef CONFIG_SMP |
371 | 372 | ||
372 | #ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA | 373 | #ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA |
373 | 374 | ||
374 | static void *percpu_modalloc(unsigned long size, unsigned long align, | 375 | static void *percpu_modalloc(unsigned long size, unsigned long align, |
375 | const char *name) | 376 | const char *name) |
@@ -394,7 +395,7 @@ static void percpu_modfree(void *freeme) | |||
394 | free_percpu(freeme); | 395 | free_percpu(freeme); |
395 | } | 396 | } |
396 | 397 | ||
397 | #else /* ... !CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ | 398 | #else /* ... CONFIG_HAVE_LEGACY_PER_CPU_AREA */ |
398 | 399 | ||
399 | /* Number of blocks used and allocated. */ | 400 | /* Number of blocks used and allocated. */ |
400 | static unsigned int pcpu_num_used, pcpu_num_allocated; | 401 | static unsigned int pcpu_num_used, pcpu_num_allocated; |
@@ -540,7 +541,7 @@ static int percpu_modinit(void) | |||
540 | } | 541 | } |
541 | __initcall(percpu_modinit); | 542 | __initcall(percpu_modinit); |
542 | 543 | ||
543 | #endif /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ | 544 | #endif /* CONFIG_HAVE_LEGACY_PER_CPU_AREA */ |
544 | 545 | ||
545 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, | 546 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, |
546 | Elf_Shdr *sechdrs, | 547 | Elf_Shdr *sechdrs, |
@@ -1535,6 +1536,10 @@ static void free_module(struct module *mod) | |||
1535 | 1536 | ||
1536 | /* Finally, free the core (containing the module structure) */ | 1537 | /* Finally, free the core (containing the module structure) */ |
1537 | module_free(mod, mod->module_core); | 1538 | module_free(mod, mod->module_core); |
1539 | |||
1540 | #ifdef CONFIG_MPU | ||
1541 | update_protections(current->mm); | ||
1542 | #endif | ||
1538 | } | 1543 | } |
1539 | 1544 | ||
1540 | void *__symbol_get(const char *symbol) | 1545 | void *__symbol_get(const char *symbol) |
@@ -1792,6 +1797,17 @@ static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs, | |||
1792 | } | 1797 | } |
1793 | } | 1798 | } |
1794 | 1799 | ||
1800 | static void free_modinfo(struct module *mod) | ||
1801 | { | ||
1802 | struct module_attribute *attr; | ||
1803 | int i; | ||
1804 | |||
1805 | for (i = 0; (attr = modinfo_attrs[i]); i++) { | ||
1806 | if (attr->free) | ||
1807 | attr->free(mod); | ||
1808 | } | ||
1809 | } | ||
1810 | |||
1795 | #ifdef CONFIG_KALLSYMS | 1811 | #ifdef CONFIG_KALLSYMS |
1796 | 1812 | ||
1797 | /* lookup symbol in given range of kernel_symbols */ | 1813 | /* lookup symbol in given range of kernel_symbols */ |
@@ -1857,13 +1873,93 @@ static char elf_type(const Elf_Sym *sym, | |||
1857 | return '?'; | 1873 | return '?'; |
1858 | } | 1874 | } |
1859 | 1875 | ||
1876 | static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, | ||
1877 | unsigned int shnum) | ||
1878 | { | ||
1879 | const Elf_Shdr *sec; | ||
1880 | |||
1881 | if (src->st_shndx == SHN_UNDEF | ||
1882 | || src->st_shndx >= shnum | ||
1883 | || !src->st_name) | ||
1884 | return false; | ||
1885 | |||
1886 | sec = sechdrs + src->st_shndx; | ||
1887 | if (!(sec->sh_flags & SHF_ALLOC) | ||
1888 | #ifndef CONFIG_KALLSYMS_ALL | ||
1889 | || !(sec->sh_flags & SHF_EXECINSTR) | ||
1890 | #endif | ||
1891 | || (sec->sh_entsize & INIT_OFFSET_MASK)) | ||
1892 | return false; | ||
1893 | |||
1894 | return true; | ||
1895 | } | ||
1896 | |||
1897 | static unsigned long layout_symtab(struct module *mod, | ||
1898 | Elf_Shdr *sechdrs, | ||
1899 | unsigned int symindex, | ||
1900 | unsigned int strindex, | ||
1901 | const Elf_Ehdr *hdr, | ||
1902 | const char *secstrings, | ||
1903 | unsigned long *pstroffs, | ||
1904 | unsigned long *strmap) | ||
1905 | { | ||
1906 | unsigned long symoffs; | ||
1907 | Elf_Shdr *symsect = sechdrs + symindex; | ||
1908 | Elf_Shdr *strsect = sechdrs + strindex; | ||
1909 | const Elf_Sym *src; | ||
1910 | const char *strtab; | ||
1911 | unsigned int i, nsrc, ndst; | ||
1912 | |||
1913 | /* Put symbol section at end of init part of module. */ | ||
1914 | symsect->sh_flags |= SHF_ALLOC; | ||
1915 | symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect, | ||
1916 | symindex) | INIT_OFFSET_MASK; | ||
1917 | DEBUGP("\t%s\n", secstrings + symsect->sh_name); | ||
1918 | |||
1919 | src = (void *)hdr + symsect->sh_offset; | ||
1920 | nsrc = symsect->sh_size / sizeof(*src); | ||
1921 | strtab = (void *)hdr + strsect->sh_offset; | ||
1922 | for (ndst = i = 1; i < nsrc; ++i, ++src) | ||
1923 | if (is_core_symbol(src, sechdrs, hdr->e_shnum)) { | ||
1924 | unsigned int j = src->st_name; | ||
1925 | |||
1926 | while(!__test_and_set_bit(j, strmap) && strtab[j]) | ||
1927 | ++j; | ||
1928 | ++ndst; | ||
1929 | } | ||
1930 | |||
1931 | /* Append room for core symbols at end of core part. */ | ||
1932 | symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); | ||
1933 | mod->core_size = symoffs + ndst * sizeof(Elf_Sym); | ||
1934 | |||
1935 | /* Put string table section at end of init part of module. */ | ||
1936 | strsect->sh_flags |= SHF_ALLOC; | ||
1937 | strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect, | ||
1938 | strindex) | INIT_OFFSET_MASK; | ||
1939 | DEBUGP("\t%s\n", secstrings + strsect->sh_name); | ||
1940 | |||
1941 | /* Append room for core symbols' strings at end of core part. */ | ||
1942 | *pstroffs = mod->core_size; | ||
1943 | __set_bit(0, strmap); | ||
1944 | mod->core_size += bitmap_weight(strmap, strsect->sh_size); | ||
1945 | |||
1946 | return symoffs; | ||
1947 | } | ||
1948 | |||
1860 | static void add_kallsyms(struct module *mod, | 1949 | static void add_kallsyms(struct module *mod, |
1861 | Elf_Shdr *sechdrs, | 1950 | Elf_Shdr *sechdrs, |
1951 | unsigned int shnum, | ||
1862 | unsigned int symindex, | 1952 | unsigned int symindex, |
1863 | unsigned int strindex, | 1953 | unsigned int strindex, |
1864 | const char *secstrings) | 1954 | unsigned long symoffs, |
1955 | unsigned long stroffs, | ||
1956 | const char *secstrings, | ||
1957 | unsigned long *strmap) | ||
1865 | { | 1958 | { |
1866 | unsigned int i; | 1959 | unsigned int i, ndst; |
1960 | const Elf_Sym *src; | ||
1961 | Elf_Sym *dst; | ||
1962 | char *s; | ||
1867 | 1963 | ||
1868 | mod->symtab = (void *)sechdrs[symindex].sh_addr; | 1964 | mod->symtab = (void *)sechdrs[symindex].sh_addr; |
1869 | mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym); | 1965 | mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym); |
@@ -1873,13 +1969,44 @@ static void add_kallsyms(struct module *mod, | |||
1873 | for (i = 0; i < mod->num_symtab; i++) | 1969 | for (i = 0; i < mod->num_symtab; i++) |
1874 | mod->symtab[i].st_info | 1970 | mod->symtab[i].st_info |
1875 | = elf_type(&mod->symtab[i], sechdrs, secstrings, mod); | 1971 | = elf_type(&mod->symtab[i], sechdrs, secstrings, mod); |
1972 | |||
1973 | mod->core_symtab = dst = mod->module_core + symoffs; | ||
1974 | src = mod->symtab; | ||
1975 | *dst = *src; | ||
1976 | for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { | ||
1977 | if (!is_core_symbol(src, sechdrs, shnum)) | ||
1978 | continue; | ||
1979 | dst[ndst] = *src; | ||
1980 | dst[ndst].st_name = bitmap_weight(strmap, dst[ndst].st_name); | ||
1981 | ++ndst; | ||
1982 | } | ||
1983 | mod->core_num_syms = ndst; | ||
1984 | |||
1985 | mod->core_strtab = s = mod->module_core + stroffs; | ||
1986 | for (*s = 0, i = 1; i < sechdrs[strindex].sh_size; ++i) | ||
1987 | if (test_bit(i, strmap)) | ||
1988 | *++s = mod->strtab[i]; | ||
1876 | } | 1989 | } |
1877 | #else | 1990 | #else |
1991 | static inline unsigned long layout_symtab(struct module *mod, | ||
1992 | Elf_Shdr *sechdrs, | ||
1993 | unsigned int symindex, | ||
1994 | unsigned int strindex, | ||
1995 | const Elf_Hdr *hdr, | ||
1996 | const char *secstrings, | ||
1997 | unsigned long *pstroffs, | ||
1998 | unsigned long *strmap) | ||
1999 | { | ||
2000 | } | ||
1878 | static inline void add_kallsyms(struct module *mod, | 2001 | static inline void add_kallsyms(struct module *mod, |
1879 | Elf_Shdr *sechdrs, | 2002 | Elf_Shdr *sechdrs, |
2003 | unsigned int shnum, | ||
1880 | unsigned int symindex, | 2004 | unsigned int symindex, |
1881 | unsigned int strindex, | 2005 | unsigned int strindex, |
1882 | const char *secstrings) | 2006 | unsigned long symoffs, |
2007 | unsigned long stroffs, | ||
2008 | const char *secstrings, | ||
2009 | const unsigned long *strmap) | ||
1883 | { | 2010 | { |
1884 | } | 2011 | } |
1885 | #endif /* CONFIG_KALLSYMS */ | 2012 | #endif /* CONFIG_KALLSYMS */ |
@@ -1954,6 +2081,9 @@ static noinline struct module *load_module(void __user *umod, | |||
1954 | struct module *mod; | 2081 | struct module *mod; |
1955 | long err = 0; | 2082 | long err = 0; |
1956 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 2083 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
2084 | #ifdef CONFIG_KALLSYMS | ||
2085 | unsigned long symoffs, stroffs, *strmap; | ||
2086 | #endif | ||
1957 | mm_segment_t old_fs; | 2087 | mm_segment_t old_fs; |
1958 | 2088 | ||
1959 | DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", | 2089 | DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", |
@@ -2035,11 +2165,6 @@ static noinline struct module *load_module(void __user *umod, | |||
2035 | /* Don't keep modinfo and version sections. */ | 2165 | /* Don't keep modinfo and version sections. */ |
2036 | sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; | 2166 | sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; |
2037 | sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC; | 2167 | sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC; |
2038 | #ifdef CONFIG_KALLSYMS | ||
2039 | /* Keep symbol and string tables for decoding later. */ | ||
2040 | sechdrs[symindex].sh_flags |= SHF_ALLOC; | ||
2041 | sechdrs[strindex].sh_flags |= SHF_ALLOC; | ||
2042 | #endif | ||
2043 | 2168 | ||
2044 | /* Check module struct version now, before we try to use module. */ | 2169 | /* Check module struct version now, before we try to use module. */ |
2045 | if (!check_modstruct_version(sechdrs, versindex, mod)) { | 2170 | if (!check_modstruct_version(sechdrs, versindex, mod)) { |
@@ -2075,6 +2200,13 @@ static noinline struct module *load_module(void __user *umod, | |||
2075 | goto free_hdr; | 2200 | goto free_hdr; |
2076 | } | 2201 | } |
2077 | 2202 | ||
2203 | strmap = kzalloc(BITS_TO_LONGS(sechdrs[strindex].sh_size) | ||
2204 | * sizeof(long), GFP_KERNEL); | ||
2205 | if (!strmap) { | ||
2206 | err = -ENOMEM; | ||
2207 | goto free_mod; | ||
2208 | } | ||
2209 | |||
2078 | if (find_module(mod->name)) { | 2210 | if (find_module(mod->name)) { |
2079 | err = -EEXIST; | 2211 | err = -EEXIST; |
2080 | goto free_mod; | 2212 | goto free_mod; |
@@ -2104,6 +2236,8 @@ static noinline struct module *load_module(void __user *umod, | |||
2104 | this is done generically; there doesn't appear to be any | 2236 | this is done generically; there doesn't appear to be any |
2105 | special cases for the architectures. */ | 2237 | special cases for the architectures. */ |
2106 | layout_sections(mod, hdr, sechdrs, secstrings); | 2238 | layout_sections(mod, hdr, sechdrs, secstrings); |
2239 | symoffs = layout_symtab(mod, sechdrs, symindex, strindex, hdr, | ||
2240 | secstrings, &stroffs, strmap); | ||
2107 | 2241 | ||
2108 | /* Do the allocs. */ | 2242 | /* Do the allocs. */ |
2109 | ptr = module_alloc_update_bounds(mod->core_size); | 2243 | ptr = module_alloc_update_bounds(mod->core_size); |
@@ -2237,10 +2371,6 @@ static noinline struct module *load_module(void __user *umod, | |||
2237 | sizeof(*mod->ctors), &mod->num_ctors); | 2371 | sizeof(*mod->ctors), &mod->num_ctors); |
2238 | #endif | 2372 | #endif |
2239 | 2373 | ||
2240 | #ifdef CONFIG_MARKERS | ||
2241 | mod->markers = section_objs(hdr, sechdrs, secstrings, "__markers", | ||
2242 | sizeof(*mod->markers), &mod->num_markers); | ||
2243 | #endif | ||
2244 | #ifdef CONFIG_TRACEPOINTS | 2374 | #ifdef CONFIG_TRACEPOINTS |
2245 | mod->tracepoints = section_objs(hdr, sechdrs, secstrings, | 2375 | mod->tracepoints = section_objs(hdr, sechdrs, secstrings, |
2246 | "__tracepoints", | 2376 | "__tracepoints", |
@@ -2312,7 +2442,10 @@ static noinline struct module *load_module(void __user *umod, | |||
2312 | percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr, | 2442 | percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr, |
2313 | sechdrs[pcpuindex].sh_size); | 2443 | sechdrs[pcpuindex].sh_size); |
2314 | 2444 | ||
2315 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); | 2445 | add_kallsyms(mod, sechdrs, hdr->e_shnum, symindex, strindex, |
2446 | symoffs, stroffs, secstrings, strmap); | ||
2447 | kfree(strmap); | ||
2448 | strmap = NULL; | ||
2316 | 2449 | ||
2317 | if (!mod->taints) { | 2450 | if (!mod->taints) { |
2318 | struct _ddebug *debug; | 2451 | struct _ddebug *debug; |
@@ -2384,13 +2517,14 @@ static noinline struct module *load_module(void __user *umod, | |||
2384 | synchronize_sched(); | 2517 | synchronize_sched(); |
2385 | module_arch_cleanup(mod); | 2518 | module_arch_cleanup(mod); |
2386 | cleanup: | 2519 | cleanup: |
2520 | free_modinfo(mod); | ||
2387 | kobject_del(&mod->mkobj.kobj); | 2521 | kobject_del(&mod->mkobj.kobj); |
2388 | kobject_put(&mod->mkobj.kobj); | 2522 | kobject_put(&mod->mkobj.kobj); |
2389 | free_unload: | 2523 | free_unload: |
2390 | module_unload_free(mod); | 2524 | module_unload_free(mod); |
2391 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | 2525 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) |
2392 | free_init: | ||
2393 | percpu_modfree(mod->refptr); | 2526 | percpu_modfree(mod->refptr); |
2527 | free_init: | ||
2394 | #endif | 2528 | #endif |
2395 | module_free(mod, mod->module_init); | 2529 | module_free(mod, mod->module_init); |
2396 | free_core: | 2530 | free_core: |
@@ -2401,6 +2535,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2401 | percpu_modfree(percpu); | 2535 | percpu_modfree(percpu); |
2402 | free_mod: | 2536 | free_mod: |
2403 | kfree(args); | 2537 | kfree(args); |
2538 | kfree(strmap); | ||
2404 | free_hdr: | 2539 | free_hdr: |
2405 | vfree(hdr); | 2540 | vfree(hdr); |
2406 | return ERR_PTR(err); | 2541 | return ERR_PTR(err); |
@@ -2490,6 +2625,11 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, | |||
2490 | /* Drop initial reference. */ | 2625 | /* Drop initial reference. */ |
2491 | module_put(mod); | 2626 | module_put(mod); |
2492 | trim_init_extable(mod); | 2627 | trim_init_extable(mod); |
2628 | #ifdef CONFIG_KALLSYMS | ||
2629 | mod->num_symtab = mod->core_num_syms; | ||
2630 | mod->symtab = mod->core_symtab; | ||
2631 | mod->strtab = mod->core_strtab; | ||
2632 | #endif | ||
2493 | module_free(mod, mod->module_init); | 2633 | module_free(mod, mod->module_init); |
2494 | mod->module_init = NULL; | 2634 | mod->module_init = NULL; |
2495 | mod->init_size = 0; | 2635 | mod->init_size = 0; |
@@ -2958,20 +3098,6 @@ void module_layout(struct module *mod, | |||
2958 | EXPORT_SYMBOL(module_layout); | 3098 | EXPORT_SYMBOL(module_layout); |
2959 | #endif | 3099 | #endif |
2960 | 3100 | ||
2961 | #ifdef CONFIG_MARKERS | ||
2962 | void module_update_markers(void) | ||
2963 | { | ||
2964 | struct module *mod; | ||
2965 | |||
2966 | mutex_lock(&module_mutex); | ||
2967 | list_for_each_entry(mod, &modules, list) | ||
2968 | if (!mod->taints) | ||
2969 | marker_update_probe_range(mod->markers, | ||
2970 | mod->markers + mod->num_markers); | ||
2971 | mutex_unlock(&module_mutex); | ||
2972 | } | ||
2973 | #endif | ||
2974 | |||
2975 | #ifdef CONFIG_TRACEPOINTS | 3101 | #ifdef CONFIG_TRACEPOINTS |
2976 | void module_update_tracepoints(void) | 3102 | void module_update_tracepoints(void) |
2977 | { | 3103 | { |