diff options
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 130 |
1 files changed, 69 insertions, 61 deletions
diff --git a/kernel/module.c b/kernel/module.c index 404e722930fc..12905ed44393 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -2107,6 +2107,71 @@ static inline void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, | |||
| 2107 | } | 2107 | } |
| 2108 | #endif | 2108 | #endif |
| 2109 | 2109 | ||
| 2110 | static void find_module_sections(struct module *mod, Elf_Ehdr *hdr, | ||
| 2111 | Elf_Shdr *sechdrs, const char *secstrings) | ||
| 2112 | { | ||
| 2113 | mod->kp = section_objs(hdr, sechdrs, secstrings, "__param", | ||
| 2114 | sizeof(*mod->kp), &mod->num_kp); | ||
| 2115 | mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab", | ||
| 2116 | sizeof(*mod->syms), &mod->num_syms); | ||
| 2117 | mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab"); | ||
| 2118 | mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl", | ||
| 2119 | sizeof(*mod->gpl_syms), | ||
| 2120 | &mod->num_gpl_syms); | ||
| 2121 | mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl"); | ||
| 2122 | mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings, | ||
| 2123 | "__ksymtab_gpl_future", | ||
| 2124 | sizeof(*mod->gpl_future_syms), | ||
| 2125 | &mod->num_gpl_future_syms); | ||
| 2126 | mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings, | ||
| 2127 | "__kcrctab_gpl_future"); | ||
| 2128 | |||
| 2129 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
| 2130 | mod->unused_syms = section_objs(hdr, sechdrs, secstrings, | ||
| 2131 | "__ksymtab_unused", | ||
| 2132 | sizeof(*mod->unused_syms), | ||
| 2133 | &mod->num_unused_syms); | ||
| 2134 | mod->unused_crcs = section_addr(hdr, sechdrs, secstrings, | ||
| 2135 | "__kcrctab_unused"); | ||
| 2136 | mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings, | ||
| 2137 | "__ksymtab_unused_gpl", | ||
| 2138 | sizeof(*mod->unused_gpl_syms), | ||
| 2139 | &mod->num_unused_gpl_syms); | ||
| 2140 | mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings, | ||
| 2141 | "__kcrctab_unused_gpl"); | ||
| 2142 | #endif | ||
| 2143 | #ifdef CONFIG_CONSTRUCTORS | ||
| 2144 | mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors", | ||
| 2145 | sizeof(*mod->ctors), &mod->num_ctors); | ||
| 2146 | #endif | ||
| 2147 | |||
| 2148 | #ifdef CONFIG_TRACEPOINTS | ||
| 2149 | mod->tracepoints = section_objs(hdr, sechdrs, secstrings, | ||
| 2150 | "__tracepoints", | ||
| 2151 | sizeof(*mod->tracepoints), | ||
| 2152 | &mod->num_tracepoints); | ||
| 2153 | #endif | ||
| 2154 | #ifdef CONFIG_EVENT_TRACING | ||
| 2155 | mod->trace_events = section_objs(hdr, sechdrs, secstrings, | ||
| 2156 | "_ftrace_events", | ||
| 2157 | sizeof(*mod->trace_events), | ||
| 2158 | &mod->num_trace_events); | ||
| 2159 | /* | ||
| 2160 | * This section contains pointers to allocated objects in the trace | ||
| 2161 | * code and not scanning it leads to false positives. | ||
| 2162 | */ | ||
| 2163 | kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * | ||
| 2164 | mod->num_trace_events, GFP_KERNEL); | ||
| 2165 | #endif | ||
| 2166 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | ||
| 2167 | /* sechdrs[0].sh_size is always zero */ | ||
| 2168 | mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings, | ||
| 2169 | "__mcount_loc", | ||
| 2170 | sizeof(*mod->ftrace_callsites), | ||
| 2171 | &mod->num_ftrace_callsites); | ||
| 2172 | #endif | ||
| 2173 | } | ||
| 2174 | |||
| 2110 | /* Allocate and load the module: note that size of section 0 is always | 2175 | /* Allocate and load the module: note that size of section 0 is always |
| 2111 | zero, and we rely on this for optional sections. */ | 2176 | zero, and we rely on this for optional sections. */ |
| 2112 | static noinline struct module *load_module(void __user *umod, | 2177 | static noinline struct module *load_module(void __user *umod, |
| @@ -2147,7 +2212,7 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2147 | } | 2212 | } |
| 2148 | 2213 | ||
| 2149 | /* Sanity checks against insmoding binaries or wrong arch, | 2214 | /* Sanity checks against insmoding binaries or wrong arch, |
| 2150 | weird elf version */ | 2215 | weird elf version */ |
| 2151 | if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0 | 2216 | if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0 |
| 2152 | || hdr->e_type != ET_REL | 2217 | || hdr->e_type != ET_REL |
| 2153 | || !elf_check_arch(hdr) | 2218 | || !elf_check_arch(hdr) |
| @@ -2326,7 +2391,8 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2326 | sechdrs[i].sh_size); | 2391 | sechdrs[i].sh_size); |
| 2327 | /* Update sh_addr to point to copy in image. */ | 2392 | /* Update sh_addr to point to copy in image. */ |
| 2328 | sechdrs[i].sh_addr = (unsigned long)dest; | 2393 | sechdrs[i].sh_addr = (unsigned long)dest; |
| 2329 | DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name); | 2394 | DEBUGP("\t0x%lx %s\n", |
| 2395 | sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name); | ||
| 2330 | } | 2396 | } |
| 2331 | /* Module has been moved. */ | 2397 | /* Module has been moved. */ |
| 2332 | mod = (void *)sechdrs[modindex].sh_addr; | 2398 | mod = (void *)sechdrs[modindex].sh_addr; |
| @@ -2368,66 +2434,8 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2368 | 2434 | ||
| 2369 | /* Now we've got everything in the final locations, we can | 2435 | /* Now we've got everything in the final locations, we can |
| 2370 | * find optional sections. */ | 2436 | * find optional sections. */ |
| 2371 | mod->kp = section_objs(hdr, sechdrs, secstrings, "__param", | 2437 | find_module_sections(mod, hdr, sechdrs, secstrings); |
| 2372 | sizeof(*mod->kp), &mod->num_kp); | ||
| 2373 | mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab", | ||
| 2374 | sizeof(*mod->syms), &mod->num_syms); | ||
| 2375 | mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab"); | ||
| 2376 | mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl", | ||
| 2377 | sizeof(*mod->gpl_syms), | ||
| 2378 | &mod->num_gpl_syms); | ||
| 2379 | mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl"); | ||
| 2380 | mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings, | ||
| 2381 | "__ksymtab_gpl_future", | ||
| 2382 | sizeof(*mod->gpl_future_syms), | ||
| 2383 | &mod->num_gpl_future_syms); | ||
| 2384 | mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings, | ||
| 2385 | "__kcrctab_gpl_future"); | ||
| 2386 | 2438 | ||
| 2387 | #ifdef CONFIG_UNUSED_SYMBOLS | ||
| 2388 | mod->unused_syms = section_objs(hdr, sechdrs, secstrings, | ||
| 2389 | "__ksymtab_unused", | ||
| 2390 | sizeof(*mod->unused_syms), | ||
| 2391 | &mod->num_unused_syms); | ||
| 2392 | mod->unused_crcs = section_addr(hdr, sechdrs, secstrings, | ||
| 2393 | "__kcrctab_unused"); | ||
| 2394 | mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings, | ||
| 2395 | "__ksymtab_unused_gpl", | ||
| 2396 | sizeof(*mod->unused_gpl_syms), | ||
| 2397 | &mod->num_unused_gpl_syms); | ||
| 2398 | mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings, | ||
| 2399 | "__kcrctab_unused_gpl"); | ||
| 2400 | #endif | ||
| 2401 | #ifdef CONFIG_CONSTRUCTORS | ||
| 2402 | mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors", | ||
| 2403 | sizeof(*mod->ctors), &mod->num_ctors); | ||
| 2404 | #endif | ||
| 2405 | |||
| 2406 | #ifdef CONFIG_TRACEPOINTS | ||
| 2407 | mod->tracepoints = section_objs(hdr, sechdrs, secstrings, | ||
| 2408 | "__tracepoints", | ||
| 2409 | sizeof(*mod->tracepoints), | ||
| 2410 | &mod->num_tracepoints); | ||
| 2411 | #endif | ||
| 2412 | #ifdef CONFIG_EVENT_TRACING | ||
| 2413 | mod->trace_events = section_objs(hdr, sechdrs, secstrings, | ||
| 2414 | "_ftrace_events", | ||
| 2415 | sizeof(*mod->trace_events), | ||
| 2416 | &mod->num_trace_events); | ||
| 2417 | /* | ||
| 2418 | * This section contains pointers to allocated objects in the trace | ||
| 2419 | * code and not scanning it leads to false positives. | ||
| 2420 | */ | ||
| 2421 | kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * | ||
| 2422 | mod->num_trace_events, GFP_KERNEL); | ||
| 2423 | #endif | ||
| 2424 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | ||
| 2425 | /* sechdrs[0].sh_size is always zero */ | ||
| 2426 | mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings, | ||
| 2427 | "__mcount_loc", | ||
| 2428 | sizeof(*mod->ftrace_callsites), | ||
| 2429 | &mod->num_ftrace_callsites); | ||
| 2430 | #endif | ||
| 2431 | #ifdef CONFIG_MODVERSIONS | 2439 | #ifdef CONFIG_MODVERSIONS |
| 2432 | if ((mod->num_syms && !mod->crcs) | 2440 | if ((mod->num_syms && !mod->crcs) |
| 2433 | || (mod->num_gpl_syms && !mod->gpl_crcs) | 2441 | || (mod->num_gpl_syms && !mod->gpl_crcs) |
