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; |
