|
@@ -2107,6 +2107,71 @@ static inline void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+static void find_module_sections(struct module *mod, Elf_Ehdr *hdr,
|
|
|
+ Elf_Shdr *sechdrs, const char *secstrings)
|
|
|
+{
|
|
|
+ mod->kp = section_objs(hdr, sechdrs, secstrings, "__param",
|
|
|
+ sizeof(*mod->kp), &mod->num_kp);
|
|
|
+ mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
|
|
|
+ sizeof(*mod->syms), &mod->num_syms);
|
|
|
+ mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
|
|
|
+ mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl",
|
|
|
+ sizeof(*mod->gpl_syms),
|
|
|
+ &mod->num_gpl_syms);
|
|
|
+ mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl");
|
|
|
+ mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings,
|
|
|
+ "__ksymtab_gpl_future",
|
|
|
+ sizeof(*mod->gpl_future_syms),
|
|
|
+ &mod->num_gpl_future_syms);
|
|
|
+ mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings,
|
|
|
+ "__kcrctab_gpl_future");
|
|
|
+
|
|
|
+#ifdef CONFIG_UNUSED_SYMBOLS
|
|
|
+ mod->unused_syms = section_objs(hdr, sechdrs, secstrings,
|
|
|
+ "__ksymtab_unused",
|
|
|
+ sizeof(*mod->unused_syms),
|
|
|
+ &mod->num_unused_syms);
|
|
|
+ mod->unused_crcs = section_addr(hdr, sechdrs, secstrings,
|
|
|
+ "__kcrctab_unused");
|
|
|
+ mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings,
|
|
|
+ "__ksymtab_unused_gpl",
|
|
|
+ sizeof(*mod->unused_gpl_syms),
|
|
|
+ &mod->num_unused_gpl_syms);
|
|
|
+ mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings,
|
|
|
+ "__kcrctab_unused_gpl");
|
|
|
+#endif
|
|
|
+#ifdef CONFIG_CONSTRUCTORS
|
|
|
+ mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors",
|
|
|
+ sizeof(*mod->ctors), &mod->num_ctors);
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef CONFIG_TRACEPOINTS
|
|
|
+ mod->tracepoints = section_objs(hdr, sechdrs, secstrings,
|
|
|
+ "__tracepoints",
|
|
|
+ sizeof(*mod->tracepoints),
|
|
|
+ &mod->num_tracepoints);
|
|
|
+#endif
|
|
|
+#ifdef CONFIG_EVENT_TRACING
|
|
|
+ mod->trace_events = section_objs(hdr, sechdrs, secstrings,
|
|
|
+ "_ftrace_events",
|
|
|
+ sizeof(*mod->trace_events),
|
|
|
+ &mod->num_trace_events);
|
|
|
+ /*
|
|
|
+ * This section contains pointers to allocated objects in the trace
|
|
|
+ * code and not scanning it leads to false positives.
|
|
|
+ */
|
|
|
+ kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) *
|
|
|
+ mod->num_trace_events, GFP_KERNEL);
|
|
|
+#endif
|
|
|
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
|
|
|
+ /* sechdrs[0].sh_size is always zero */
|
|
|
+ mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings,
|
|
|
+ "__mcount_loc",
|
|
|
+ sizeof(*mod->ftrace_callsites),
|
|
|
+ &mod->num_ftrace_callsites);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
/* Allocate and load the module: note that size of section 0 is always
|
|
|
zero, and we rely on this for optional sections. */
|
|
|
static noinline struct module *load_module(void __user *umod,
|
|
@@ -2147,7 +2212,7 @@ static noinline struct module *load_module(void __user *umod,
|
|
|
}
|
|
|
|
|
|
/* Sanity checks against insmoding binaries or wrong arch,
|
|
|
- weird elf version */
|
|
|
+ weird elf version */
|
|
|
if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
|
|
|
|| hdr->e_type != ET_REL
|
|
|
|| !elf_check_arch(hdr)
|
|
@@ -2326,7 +2391,8 @@ static noinline struct module *load_module(void __user *umod,
|
|
|
sechdrs[i].sh_size);
|
|
|
/* Update sh_addr to point to copy in image. */
|
|
|
sechdrs[i].sh_addr = (unsigned long)dest;
|
|
|
- DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
|
|
|
+ DEBUGP("\t0x%lx %s\n",
|
|
|
+ sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
|
|
|
}
|
|
|
/* Module has been moved. */
|
|
|
mod = (void *)sechdrs[modindex].sh_addr;
|
|
@@ -2368,66 +2434,8 @@ static noinline struct module *load_module(void __user *umod,
|
|
|
|
|
|
/* Now we've got everything in the final locations, we can
|
|
|
* find optional sections. */
|
|
|
- mod->kp = section_objs(hdr, sechdrs, secstrings, "__param",
|
|
|
- sizeof(*mod->kp), &mod->num_kp);
|
|
|
- mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
|
|
|
- sizeof(*mod->syms), &mod->num_syms);
|
|
|
- mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
|
|
|
- mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl",
|
|
|
- sizeof(*mod->gpl_syms),
|
|
|
- &mod->num_gpl_syms);
|
|
|
- mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl");
|
|
|
- mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings,
|
|
|
- "__ksymtab_gpl_future",
|
|
|
- sizeof(*mod->gpl_future_syms),
|
|
|
- &mod->num_gpl_future_syms);
|
|
|
- mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings,
|
|
|
- "__kcrctab_gpl_future");
|
|
|
+ find_module_sections(mod, hdr, sechdrs, secstrings);
|
|
|
|
|
|
-#ifdef CONFIG_UNUSED_SYMBOLS
|
|
|
- mod->unused_syms = section_objs(hdr, sechdrs, secstrings,
|
|
|
- "__ksymtab_unused",
|
|
|
- sizeof(*mod->unused_syms),
|
|
|
- &mod->num_unused_syms);
|
|
|
- mod->unused_crcs = section_addr(hdr, sechdrs, secstrings,
|
|
|
- "__kcrctab_unused");
|
|
|
- mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings,
|
|
|
- "__ksymtab_unused_gpl",
|
|
|
- sizeof(*mod->unused_gpl_syms),
|
|
|
- &mod->num_unused_gpl_syms);
|
|
|
- mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings,
|
|
|
- "__kcrctab_unused_gpl");
|
|
|
-#endif
|
|
|
-#ifdef CONFIG_CONSTRUCTORS
|
|
|
- mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors",
|
|
|
- sizeof(*mod->ctors), &mod->num_ctors);
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef CONFIG_TRACEPOINTS
|
|
|
- mod->tracepoints = section_objs(hdr, sechdrs, secstrings,
|
|
|
- "__tracepoints",
|
|
|
- sizeof(*mod->tracepoints),
|
|
|
- &mod->num_tracepoints);
|
|
|
-#endif
|
|
|
-#ifdef CONFIG_EVENT_TRACING
|
|
|
- mod->trace_events = section_objs(hdr, sechdrs, secstrings,
|
|
|
- "_ftrace_events",
|
|
|
- sizeof(*mod->trace_events),
|
|
|
- &mod->num_trace_events);
|
|
|
- /*
|
|
|
- * This section contains pointers to allocated objects in the trace
|
|
|
- * code and not scanning it leads to false positives.
|
|
|
- */
|
|
|
- kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) *
|
|
|
- mod->num_trace_events, GFP_KERNEL);
|
|
|
-#endif
|
|
|
-#ifdef CONFIG_FTRACE_MCOUNT_RECORD
|
|
|
- /* sechdrs[0].sh_size is always zero */
|
|
|
- mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings,
|
|
|
- "__mcount_loc",
|
|
|
- sizeof(*mod->ftrace_callsites),
|
|
|
- &mod->num_ftrace_callsites);
|
|
|
-#endif
|
|
|
#ifdef CONFIG_MODVERSIONS
|
|
|
if ((mod->num_syms && !mod->crcs)
|
|
|
|| (mod->num_gpl_syms && !mod->gpl_crcs)
|