diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 284 |
1 files changed, 246 insertions, 38 deletions
diff --git a/kernel/module.c b/kernel/module.c index ccd641991842..795bdc7f5c3f 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -55,6 +55,9 @@ | |||
55 | #include <linux/async.h> | 55 | #include <linux/async.h> |
56 | #include <linux/percpu.h> | 56 | #include <linux/percpu.h> |
57 | #include <linux/kmemleak.h> | 57 | #include <linux/kmemleak.h> |
58 | #include <linux/jump_label.h> | ||
59 | #include <linux/pfn.h> | ||
60 | #include <linux/bsearch.h> | ||
58 | 61 | ||
59 | #define CREATE_TRACE_POINTS | 62 | #define CREATE_TRACE_POINTS |
60 | #include <trace/events/module.h> | 63 | #include <trace/events/module.h> |
@@ -69,6 +72,26 @@ | |||
69 | #define ARCH_SHF_SMALL 0 | 72 | #define ARCH_SHF_SMALL 0 |
70 | #endif | 73 | #endif |
71 | 74 | ||
75 | /* | ||
76 | * Modules' sections will be aligned on page boundaries | ||
77 | * to ensure complete separation of code and data, but | ||
78 | * only when CONFIG_DEBUG_SET_MODULE_RONX=y | ||
79 | */ | ||
80 | #ifdef CONFIG_DEBUG_SET_MODULE_RONX | ||
81 | # define debug_align(X) ALIGN(X, PAGE_SIZE) | ||
82 | #else | ||
83 | # define debug_align(X) (X) | ||
84 | #endif | ||
85 | |||
86 | /* | ||
87 | * Given BASE and SIZE this macro calculates the number of pages the | ||
88 | * memory regions occupies | ||
89 | */ | ||
90 | #define MOD_NUMBER_OF_PAGES(BASE, SIZE) (((SIZE) > 0) ? \ | ||
91 | (PFN_DOWN((unsigned long)(BASE) + (SIZE) - 1) - \ | ||
92 | PFN_DOWN((unsigned long)BASE) + 1) \ | ||
93 | : (0UL)) | ||
94 | |||
72 | /* If this is set, the section belongs in the init part of the module */ | 95 | /* If this is set, the section belongs in the init part of the module */ |
73 | #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) | 96 | #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) |
74 | 97 | ||
@@ -218,23 +241,24 @@ static bool each_symbol_in_section(const struct symsearch *arr, | |||
218 | struct module *owner, | 241 | struct module *owner, |
219 | bool (*fn)(const struct symsearch *syms, | 242 | bool (*fn)(const struct symsearch *syms, |
220 | struct module *owner, | 243 | struct module *owner, |
221 | unsigned int symnum, void *data), | 244 | void *data), |
222 | void *data) | 245 | void *data) |
223 | { | 246 | { |
224 | unsigned int i, j; | 247 | unsigned int j; |
225 | 248 | ||
226 | for (j = 0; j < arrsize; j++) { | 249 | for (j = 0; j < arrsize; j++) { |
227 | for (i = 0; i < arr[j].stop - arr[j].start; i++) | 250 | if (fn(&arr[j], owner, data)) |
228 | if (fn(&arr[j], owner, i, data)) | 251 | return true; |
229 | return true; | ||
230 | } | 252 | } |
231 | 253 | ||
232 | return false; | 254 | return false; |
233 | } | 255 | } |
234 | 256 | ||
235 | /* Returns true as soon as fn returns true, otherwise false. */ | 257 | /* Returns true as soon as fn returns true, otherwise false. */ |
236 | bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner, | 258 | bool each_symbol_section(bool (*fn)(const struct symsearch *arr, |
237 | unsigned int symnum, void *data), void *data) | 259 | struct module *owner, |
260 | void *data), | ||
261 | void *data) | ||
238 | { | 262 | { |
239 | struct module *mod; | 263 | struct module *mod; |
240 | static const struct symsearch arr[] = { | 264 | static const struct symsearch arr[] = { |
@@ -287,7 +311,7 @@ bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner, | |||
287 | } | 311 | } |
288 | return false; | 312 | return false; |
289 | } | 313 | } |
290 | EXPORT_SYMBOL_GPL(each_symbol); | 314 | EXPORT_SYMBOL_GPL(each_symbol_section); |
291 | 315 | ||
292 | struct find_symbol_arg { | 316 | struct find_symbol_arg { |
293 | /* Input */ | 317 | /* Input */ |
@@ -301,15 +325,12 @@ struct find_symbol_arg { | |||
301 | const struct kernel_symbol *sym; | 325 | const struct kernel_symbol *sym; |
302 | }; | 326 | }; |
303 | 327 | ||
304 | static bool find_symbol_in_section(const struct symsearch *syms, | 328 | static bool check_symbol(const struct symsearch *syms, |
305 | struct module *owner, | 329 | struct module *owner, |
306 | unsigned int symnum, void *data) | 330 | unsigned int symnum, void *data) |
307 | { | 331 | { |
308 | struct find_symbol_arg *fsa = data; | 332 | struct find_symbol_arg *fsa = data; |
309 | 333 | ||
310 | if (strcmp(syms->start[symnum].name, fsa->name) != 0) | ||
311 | return false; | ||
312 | |||
313 | if (!fsa->gplok) { | 334 | if (!fsa->gplok) { |
314 | if (syms->licence == GPL_ONLY) | 335 | if (syms->licence == GPL_ONLY) |
315 | return false; | 336 | return false; |
@@ -343,6 +364,30 @@ static bool find_symbol_in_section(const struct symsearch *syms, | |||
343 | return true; | 364 | return true; |
344 | } | 365 | } |
345 | 366 | ||
367 | static int cmp_name(const void *va, const void *vb) | ||
368 | { | ||
369 | const char *a; | ||
370 | const struct kernel_symbol *b; | ||
371 | a = va; b = vb; | ||
372 | return strcmp(a, b->name); | ||
373 | } | ||
374 | |||
375 | static bool find_symbol_in_section(const struct symsearch *syms, | ||
376 | struct module *owner, | ||
377 | void *data) | ||
378 | { | ||
379 | struct find_symbol_arg *fsa = data; | ||
380 | struct kernel_symbol *sym; | ||
381 | |||
382 | sym = bsearch(fsa->name, syms->start, syms->stop - syms->start, | ||
383 | sizeof(struct kernel_symbol), cmp_name); | ||
384 | |||
385 | if (sym != NULL && check_symbol(syms, owner, sym - syms->start, data)) | ||
386 | return true; | ||
387 | |||
388 | return false; | ||
389 | } | ||
390 | |||
346 | /* Find a symbol and return it, along with, (optional) crc and | 391 | /* Find a symbol and return it, along with, (optional) crc and |
347 | * (optional) module which owns it. Needs preempt disabled or module_mutex. */ | 392 | * (optional) module which owns it. Needs preempt disabled or module_mutex. */ |
348 | const struct kernel_symbol *find_symbol(const char *name, | 393 | const struct kernel_symbol *find_symbol(const char *name, |
@@ -357,7 +402,7 @@ const struct kernel_symbol *find_symbol(const char *name, | |||
357 | fsa.gplok = gplok; | 402 | fsa.gplok = gplok; |
358 | fsa.warn = warn; | 403 | fsa.warn = warn; |
359 | 404 | ||
360 | if (each_symbol(find_symbol_in_section, &fsa)) { | 405 | if (each_symbol_section(find_symbol_in_section, &fsa)) { |
361 | if (owner) | 406 | if (owner) |
362 | *owner = fsa.owner; | 407 | *owner = fsa.owner; |
363 | if (crc) | 408 | if (crc) |
@@ -787,7 +832,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, | |||
787 | wait_for_zero_refcount(mod); | 832 | wait_for_zero_refcount(mod); |
788 | 833 | ||
789 | mutex_unlock(&module_mutex); | 834 | mutex_unlock(&module_mutex); |
790 | /* Final destruction now noone is using it. */ | 835 | /* Final destruction now no one is using it. */ |
791 | if (mod->exit != NULL) | 836 | if (mod->exit != NULL) |
792 | mod->exit(); | 837 | mod->exit(); |
793 | blocking_notifier_call_chain(&module_notify_list, | 838 | blocking_notifier_call_chain(&module_notify_list, |
@@ -1146,7 +1191,7 @@ static ssize_t module_sect_show(struct module_attribute *mattr, | |||
1146 | { | 1191 | { |
1147 | struct module_sect_attr *sattr = | 1192 | struct module_sect_attr *sattr = |
1148 | container_of(mattr, struct module_sect_attr, mattr); | 1193 | container_of(mattr, struct module_sect_attr, mattr); |
1149 | return sprintf(buf, "0x%lx\n", sattr->address); | 1194 | return sprintf(buf, "0x%pK\n", (void *)sattr->address); |
1150 | } | 1195 | } |
1151 | 1196 | ||
1152 | static void free_sect_attrs(struct module_sect_attrs *sect_attrs) | 1197 | static void free_sect_attrs(struct module_sect_attrs *sect_attrs) |
@@ -1541,6 +1586,117 @@ static int __unlink_module(void *_mod) | |||
1541 | return 0; | 1586 | return 0; |
1542 | } | 1587 | } |
1543 | 1588 | ||
1589 | #ifdef CONFIG_DEBUG_SET_MODULE_RONX | ||
1590 | /* | ||
1591 | * LKM RO/NX protection: protect module's text/ro-data | ||
1592 | * from modification and any data from execution. | ||
1593 | */ | ||
1594 | void set_page_attributes(void *start, void *end, int (*set)(unsigned long start, int num_pages)) | ||
1595 | { | ||
1596 | unsigned long begin_pfn = PFN_DOWN((unsigned long)start); | ||
1597 | unsigned long end_pfn = PFN_DOWN((unsigned long)end); | ||
1598 | |||
1599 | if (end_pfn > begin_pfn) | ||
1600 | set(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn); | ||
1601 | } | ||
1602 | |||
1603 | static void set_section_ro_nx(void *base, | ||
1604 | unsigned long text_size, | ||
1605 | unsigned long ro_size, | ||
1606 | unsigned long total_size) | ||
1607 | { | ||
1608 | /* begin and end PFNs of the current subsection */ | ||
1609 | unsigned long begin_pfn; | ||
1610 | unsigned long end_pfn; | ||
1611 | |||
1612 | /* | ||
1613 | * Set RO for module text and RO-data: | ||
1614 | * - Always protect first page. | ||
1615 | * - Do not protect last partial page. | ||
1616 | */ | ||
1617 | if (ro_size > 0) | ||
1618 | set_page_attributes(base, base + ro_size, set_memory_ro); | ||
1619 | |||
1620 | /* | ||
1621 | * Set NX permissions for module data: | ||
1622 | * - Do not protect first partial page. | ||
1623 | * - Always protect last page. | ||
1624 | */ | ||
1625 | if (total_size > text_size) { | ||
1626 | begin_pfn = PFN_UP((unsigned long)base + text_size); | ||
1627 | end_pfn = PFN_UP((unsigned long)base + total_size); | ||
1628 | if (end_pfn > begin_pfn) | ||
1629 | set_memory_nx(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn); | ||
1630 | } | ||
1631 | } | ||
1632 | |||
1633 | static void unset_module_core_ro_nx(struct module *mod) | ||
1634 | { | ||
1635 | set_page_attributes(mod->module_core + mod->core_text_size, | ||
1636 | mod->module_core + mod->core_size, | ||
1637 | set_memory_x); | ||
1638 | set_page_attributes(mod->module_core, | ||
1639 | mod->module_core + mod->core_ro_size, | ||
1640 | set_memory_rw); | ||
1641 | } | ||
1642 | |||
1643 | static void unset_module_init_ro_nx(struct module *mod) | ||
1644 | { | ||
1645 | set_page_attributes(mod->module_init + mod->init_text_size, | ||
1646 | mod->module_init + mod->init_size, | ||
1647 | set_memory_x); | ||
1648 | set_page_attributes(mod->module_init, | ||
1649 | mod->module_init + mod->init_ro_size, | ||
1650 | set_memory_rw); | ||
1651 | } | ||
1652 | |||
1653 | /* Iterate through all modules and set each module's text as RW */ | ||
1654 | void set_all_modules_text_rw(void) | ||
1655 | { | ||
1656 | struct module *mod; | ||
1657 | |||
1658 | mutex_lock(&module_mutex); | ||
1659 | list_for_each_entry_rcu(mod, &modules, list) { | ||
1660 | if ((mod->module_core) && (mod->core_text_size)) { | ||
1661 | set_page_attributes(mod->module_core, | ||
1662 | mod->module_core + mod->core_text_size, | ||
1663 | set_memory_rw); | ||
1664 | } | ||
1665 | if ((mod->module_init) && (mod->init_text_size)) { | ||
1666 | set_page_attributes(mod->module_init, | ||
1667 | mod->module_init + mod->init_text_size, | ||
1668 | set_memory_rw); | ||
1669 | } | ||
1670 | } | ||
1671 | mutex_unlock(&module_mutex); | ||
1672 | } | ||
1673 | |||
1674 | /* Iterate through all modules and set each module's text as RO */ | ||
1675 | void set_all_modules_text_ro(void) | ||
1676 | { | ||
1677 | struct module *mod; | ||
1678 | |||
1679 | mutex_lock(&module_mutex); | ||
1680 | list_for_each_entry_rcu(mod, &modules, list) { | ||
1681 | if ((mod->module_core) && (mod->core_text_size)) { | ||
1682 | set_page_attributes(mod->module_core, | ||
1683 | mod->module_core + mod->core_text_size, | ||
1684 | set_memory_ro); | ||
1685 | } | ||
1686 | if ((mod->module_init) && (mod->init_text_size)) { | ||
1687 | set_page_attributes(mod->module_init, | ||
1688 | mod->module_init + mod->init_text_size, | ||
1689 | set_memory_ro); | ||
1690 | } | ||
1691 | } | ||
1692 | mutex_unlock(&module_mutex); | ||
1693 | } | ||
1694 | #else | ||
1695 | static inline void set_section_ro_nx(void *base, unsigned long text_size, unsigned long ro_size, unsigned long total_size) { } | ||
1696 | static void unset_module_core_ro_nx(struct module *mod) { } | ||
1697 | static void unset_module_init_ro_nx(struct module *mod) { } | ||
1698 | #endif | ||
1699 | |||
1544 | /* Free a module, remove from lists, etc. */ | 1700 | /* Free a module, remove from lists, etc. */ |
1545 | static void free_module(struct module *mod) | 1701 | static void free_module(struct module *mod) |
1546 | { | 1702 | { |
@@ -1565,6 +1721,7 @@ static void free_module(struct module *mod) | |||
1565 | destroy_params(mod->kp, mod->num_kp); | 1721 | destroy_params(mod->kp, mod->num_kp); |
1566 | 1722 | ||
1567 | /* This may be NULL, but that's OK */ | 1723 | /* This may be NULL, but that's OK */ |
1724 | unset_module_init_ro_nx(mod); | ||
1568 | module_free(mod, mod->module_init); | 1725 | module_free(mod, mod->module_init); |
1569 | kfree(mod->args); | 1726 | kfree(mod->args); |
1570 | percpu_modfree(mod); | 1727 | percpu_modfree(mod); |
@@ -1573,6 +1730,7 @@ static void free_module(struct module *mod) | |||
1573 | lockdep_free_key_range(mod->module_core, mod->core_size); | 1730 | lockdep_free_key_range(mod->module_core, mod->core_size); |
1574 | 1731 | ||
1575 | /* Finally, free the core (containing the module structure) */ | 1732 | /* Finally, free the core (containing the module structure) */ |
1733 | unset_module_core_ro_nx(mod); | ||
1576 | module_free(mod, mod->module_core); | 1734 | module_free(mod, mod->module_core); |
1577 | 1735 | ||
1578 | #ifdef CONFIG_MPU | 1736 | #ifdef CONFIG_MPU |
@@ -1776,8 +1934,19 @@ static void layout_sections(struct module *mod, struct load_info *info) | |||
1776 | s->sh_entsize = get_offset(mod, &mod->core_size, s, i); | 1934 | s->sh_entsize = get_offset(mod, &mod->core_size, s, i); |
1777 | DEBUGP("\t%s\n", name); | 1935 | DEBUGP("\t%s\n", name); |
1778 | } | 1936 | } |
1779 | if (m == 0) | 1937 | switch (m) { |
1938 | case 0: /* executable */ | ||
1939 | mod->core_size = debug_align(mod->core_size); | ||
1780 | mod->core_text_size = mod->core_size; | 1940 | mod->core_text_size = mod->core_size; |
1941 | break; | ||
1942 | case 1: /* RO: text and ro-data */ | ||
1943 | mod->core_size = debug_align(mod->core_size); | ||
1944 | mod->core_ro_size = mod->core_size; | ||
1945 | break; | ||
1946 | case 3: /* whole core */ | ||
1947 | mod->core_size = debug_align(mod->core_size); | ||
1948 | break; | ||
1949 | } | ||
1781 | } | 1950 | } |
1782 | 1951 | ||
1783 | DEBUGP("Init section allocation order:\n"); | 1952 | DEBUGP("Init section allocation order:\n"); |
@@ -1795,8 +1964,19 @@ static void layout_sections(struct module *mod, struct load_info *info) | |||
1795 | | INIT_OFFSET_MASK); | 1964 | | INIT_OFFSET_MASK); |
1796 | DEBUGP("\t%s\n", sname); | 1965 | DEBUGP("\t%s\n", sname); |
1797 | } | 1966 | } |
1798 | if (m == 0) | 1967 | switch (m) { |
1968 | case 0: /* executable */ | ||
1969 | mod->init_size = debug_align(mod->init_size); | ||
1799 | mod->init_text_size = mod->init_size; | 1970 | mod->init_text_size = mod->init_size; |
1971 | break; | ||
1972 | case 1: /* RO: text and ro-data */ | ||
1973 | mod->init_size = debug_align(mod->init_size); | ||
1974 | mod->init_ro_size = mod->init_size; | ||
1975 | break; | ||
1976 | case 3: /* whole init */ | ||
1977 | mod->init_size = debug_align(mod->init_size); | ||
1978 | break; | ||
1979 | } | ||
1800 | } | 1980 | } |
1801 | } | 1981 | } |
1802 | 1982 | ||
@@ -1875,11 +2055,8 @@ static const struct kernel_symbol *lookup_symbol(const char *name, | |||
1875 | const struct kernel_symbol *start, | 2055 | const struct kernel_symbol *start, |
1876 | const struct kernel_symbol *stop) | 2056 | const struct kernel_symbol *stop) |
1877 | { | 2057 | { |
1878 | const struct kernel_symbol *ks = start; | 2058 | return bsearch(name, start, stop - start, |
1879 | for (; ks < stop; ks++) | 2059 | sizeof(struct kernel_symbol), cmp_name); |
1880 | if (strcmp(ks->name, name) == 0) | ||
1881 | return ks; | ||
1882 | return NULL; | ||
1883 | } | 2060 | } |
1884 | 2061 | ||
1885 | static int is_exported(const char *name, unsigned long value, | 2062 | static int is_exported(const char *name, unsigned long value, |
@@ -2036,7 +2213,7 @@ static inline void layout_symtab(struct module *mod, struct load_info *info) | |||
2036 | { | 2213 | { |
2037 | } | 2214 | } |
2038 | 2215 | ||
2039 | static void add_kallsyms(struct module *mod, struct load_info *info) | 2216 | static void add_kallsyms(struct module *mod, const struct load_info *info) |
2040 | { | 2217 | { |
2041 | } | 2218 | } |
2042 | #endif /* CONFIG_KALLSYMS */ | 2219 | #endif /* CONFIG_KALLSYMS */ |
@@ -2305,9 +2482,14 @@ static void find_module_sections(struct module *mod, struct load_info *info) | |||
2305 | #endif | 2482 | #endif |
2306 | 2483 | ||
2307 | #ifdef CONFIG_TRACEPOINTS | 2484 | #ifdef CONFIG_TRACEPOINTS |
2308 | mod->tracepoints = section_objs(info, "__tracepoints", | 2485 | mod->tracepoints_ptrs = section_objs(info, "__tracepoints_ptrs", |
2309 | sizeof(*mod->tracepoints), | 2486 | sizeof(*mod->tracepoints_ptrs), |
2310 | &mod->num_tracepoints); | 2487 | &mod->num_tracepoints); |
2488 | #endif | ||
2489 | #ifdef HAVE_JUMP_LABEL | ||
2490 | mod->jump_entries = section_objs(info, "__jump_table", | ||
2491 | sizeof(*mod->jump_entries), | ||
2492 | &mod->num_jump_entries); | ||
2311 | #endif | 2493 | #endif |
2312 | #ifdef CONFIG_EVENT_TRACING | 2494 | #ifdef CONFIG_EVENT_TRACING |
2313 | mod->trace_events = section_objs(info, "_ftrace_events", | 2495 | mod->trace_events = section_objs(info, "_ftrace_events", |
@@ -2320,6 +2502,18 @@ static void find_module_sections(struct module *mod, struct load_info *info) | |||
2320 | kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * | 2502 | kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * |
2321 | mod->num_trace_events, GFP_KERNEL); | 2503 | mod->num_trace_events, GFP_KERNEL); |
2322 | #endif | 2504 | #endif |
2505 | #ifdef CONFIG_TRACING | ||
2506 | mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt", | ||
2507 | sizeof(*mod->trace_bprintk_fmt_start), | ||
2508 | &mod->num_trace_bprintk_fmt); | ||
2509 | /* | ||
2510 | * This section contains pointers to allocated objects in the trace | ||
2511 | * code and not scanning it leads to false positives. | ||
2512 | */ | ||
2513 | kmemleak_scan_area(mod->trace_bprintk_fmt_start, | ||
2514 | sizeof(*mod->trace_bprintk_fmt_start) * | ||
2515 | mod->num_trace_bprintk_fmt, GFP_KERNEL); | ||
2516 | #endif | ||
2323 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | 2517 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
2324 | /* sechdrs[0].sh_size is always zero */ | 2518 | /* sechdrs[0].sh_size is always zero */ |
2325 | mod->ftrace_callsites = section_objs(info, "__mcount_loc", | 2519 | mod->ftrace_callsites = section_objs(info, "__mcount_loc", |
@@ -2605,7 +2799,7 @@ static struct module *load_module(void __user *umod, | |||
2605 | mod->state = MODULE_STATE_COMING; | 2799 | mod->state = MODULE_STATE_COMING; |
2606 | 2800 | ||
2607 | /* Now sew it into the lists so we can get lockdep and oops | 2801 | /* Now sew it into the lists so we can get lockdep and oops |
2608 | * info during argument parsing. Noone should access us, since | 2802 | * info during argument parsing. No one should access us, since |
2609 | * strong_try_module_get() will fail. | 2803 | * strong_try_module_get() will fail. |
2610 | * lockdep/oops can run asynchronous, so use the RCU list insertion | 2804 | * lockdep/oops can run asynchronous, so use the RCU list insertion |
2611 | * function to insert in a way safe to concurrent readers. | 2805 | * function to insert in a way safe to concurrent readers. |
@@ -2618,7 +2812,7 @@ static struct module *load_module(void __user *umod, | |||
2618 | } | 2812 | } |
2619 | 2813 | ||
2620 | /* This has to be done once we're sure module name is unique. */ | 2814 | /* This has to be done once we're sure module name is unique. */ |
2621 | if (!mod->taints) | 2815 | if (!mod->taints || mod->taints == (1U<<TAINT_CRAP)) |
2622 | dynamic_debug_setup(info.debug, info.num_debug); | 2816 | dynamic_debug_setup(info.debug, info.num_debug); |
2623 | 2817 | ||
2624 | /* Find duplicate symbols */ | 2818 | /* Find duplicate symbols */ |
@@ -2655,7 +2849,7 @@ static struct module *load_module(void __user *umod, | |||
2655 | module_bug_cleanup(mod); | 2849 | module_bug_cleanup(mod); |
2656 | 2850 | ||
2657 | ddebug: | 2851 | ddebug: |
2658 | if (!mod->taints) | 2852 | if (!mod->taints || mod->taints == (1U<<TAINT_CRAP)) |
2659 | dynamic_debug_remove(info.debug); | 2853 | dynamic_debug_remove(info.debug); |
2660 | unlock: | 2854 | unlock: |
2661 | mutex_unlock(&module_mutex); | 2855 | mutex_unlock(&module_mutex); |
@@ -2704,6 +2898,18 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, | |||
2704 | blocking_notifier_call_chain(&module_notify_list, | 2898 | blocking_notifier_call_chain(&module_notify_list, |
2705 | MODULE_STATE_COMING, mod); | 2899 | MODULE_STATE_COMING, mod); |
2706 | 2900 | ||
2901 | /* Set RO and NX regions for core */ | ||
2902 | set_section_ro_nx(mod->module_core, | ||
2903 | mod->core_text_size, | ||
2904 | mod->core_ro_size, | ||
2905 | mod->core_size); | ||
2906 | |||
2907 | /* Set RO and NX regions for init */ | ||
2908 | set_section_ro_nx(mod->module_init, | ||
2909 | mod->init_text_size, | ||
2910 | mod->init_ro_size, | ||
2911 | mod->init_size); | ||
2912 | |||
2707 | do_mod_ctors(mod); | 2913 | do_mod_ctors(mod); |
2708 | /* Start the module */ | 2914 | /* Start the module */ |
2709 | if (mod->init != NULL) | 2915 | if (mod->init != NULL) |
@@ -2747,9 +2953,11 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, | |||
2747 | mod->symtab = mod->core_symtab; | 2953 | mod->symtab = mod->core_symtab; |
2748 | mod->strtab = mod->core_strtab; | 2954 | mod->strtab = mod->core_strtab; |
2749 | #endif | 2955 | #endif |
2956 | unset_module_init_ro_nx(mod); | ||
2750 | module_free(mod, mod->module_init); | 2957 | module_free(mod, mod->module_init); |
2751 | mod->module_init = NULL; | 2958 | mod->module_init = NULL; |
2752 | mod->init_size = 0; | 2959 | mod->init_size = 0; |
2960 | mod->init_ro_size = 0; | ||
2753 | mod->init_text_size = 0; | 2961 | mod->init_text_size = 0; |
2754 | mutex_unlock(&module_mutex); | 2962 | mutex_unlock(&module_mutex); |
2755 | 2963 | ||
@@ -2786,7 +2994,7 @@ static const char *get_ksymbol(struct module *mod, | |||
2786 | else | 2994 | else |
2787 | nextval = (unsigned long)mod->module_core+mod->core_text_size; | 2995 | nextval = (unsigned long)mod->module_core+mod->core_text_size; |
2788 | 2996 | ||
2789 | /* Scan for closest preceeding symbol, and next symbol. (ELF | 2997 | /* Scan for closest preceding symbol, and next symbol. (ELF |
2790 | starts real symbols at 1). */ | 2998 | starts real symbols at 1). */ |
2791 | for (i = 1; i < mod->num_symtab; i++) { | 2999 | for (i = 1; i < mod->num_symtab; i++) { |
2792 | if (mod->symtab[i].st_shndx == SHN_UNDEF) | 3000 | if (mod->symtab[i].st_shndx == SHN_UNDEF) |
@@ -3039,7 +3247,7 @@ static int m_show(struct seq_file *m, void *p) | |||
3039 | mod->state == MODULE_STATE_COMING ? "Loading": | 3247 | mod->state == MODULE_STATE_COMING ? "Loading": |
3040 | "Live"); | 3248 | "Live"); |
3041 | /* Used by oprofile and other similar tools. */ | 3249 | /* Used by oprofile and other similar tools. */ |
3042 | seq_printf(m, " 0x%p", mod->module_core); | 3250 | seq_printf(m, " 0x%pK", mod->module_core); |
3043 | 3251 | ||
3044 | /* Taints info */ | 3252 | /* Taints info */ |
3045 | if (mod->taints) | 3253 | if (mod->taints) |
@@ -3208,7 +3416,7 @@ void module_layout(struct module *mod, | |||
3208 | struct modversion_info *ver, | 3416 | struct modversion_info *ver, |
3209 | struct kernel_param *kp, | 3417 | struct kernel_param *kp, |
3210 | struct kernel_symbol *ks, | 3418 | struct kernel_symbol *ks, |
3211 | struct tracepoint *tp) | 3419 | struct tracepoint * const *tp) |
3212 | { | 3420 | { |
3213 | } | 3421 | } |
3214 | EXPORT_SYMBOL(module_layout); | 3422 | EXPORT_SYMBOL(module_layout); |
@@ -3222,8 +3430,8 @@ void module_update_tracepoints(void) | |||
3222 | mutex_lock(&module_mutex); | 3430 | mutex_lock(&module_mutex); |
3223 | list_for_each_entry(mod, &modules, list) | 3431 | list_for_each_entry(mod, &modules, list) |
3224 | if (!mod->taints) | 3432 | if (!mod->taints) |
3225 | tracepoint_update_probe_range(mod->tracepoints, | 3433 | tracepoint_update_probe_range(mod->tracepoints_ptrs, |
3226 | mod->tracepoints + mod->num_tracepoints); | 3434 | mod->tracepoints_ptrs + mod->num_tracepoints); |
3227 | mutex_unlock(&module_mutex); | 3435 | mutex_unlock(&module_mutex); |
3228 | } | 3436 | } |
3229 | 3437 | ||
@@ -3247,8 +3455,8 @@ int module_get_iter_tracepoints(struct tracepoint_iter *iter) | |||
3247 | else if (iter_mod > iter->module) | 3455 | else if (iter_mod > iter->module) |
3248 | iter->tracepoint = NULL; | 3456 | iter->tracepoint = NULL; |
3249 | found = tracepoint_get_iter_range(&iter->tracepoint, | 3457 | found = tracepoint_get_iter_range(&iter->tracepoint, |
3250 | iter_mod->tracepoints, | 3458 | iter_mod->tracepoints_ptrs, |
3251 | iter_mod->tracepoints | 3459 | iter_mod->tracepoints_ptrs |
3252 | + iter_mod->num_tracepoints); | 3460 | + iter_mod->num_tracepoints); |
3253 | if (found) { | 3461 | if (found) { |
3254 | iter->module = iter_mod; | 3462 | iter->module = iter_mod; |