.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | Copyright (C) 2002 Richard Henderson |
---|
3 | 4 | Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM. |
---|
4 | 5 | |
---|
5 | | - This program is free software; you can redistribute it and/or modify |
---|
6 | | - it under the terms of the GNU General Public License as published by |
---|
7 | | - the Free Software Foundation; either version 2 of the License, or |
---|
8 | | - (at your option) any later version. |
---|
9 | | - |
---|
10 | | - This program is distributed in the hope that it will be useful, |
---|
11 | | - but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
13 | | - GNU General Public License for more details. |
---|
14 | | - |
---|
15 | | - You should have received a copy of the GNU General Public License |
---|
16 | | - along with this program; if not, write to the Free Software |
---|
17 | | - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
18 | 6 | */ |
---|
| 7 | + |
---|
| 8 | +#define INCLUDE_VERMAGIC |
---|
| 9 | + |
---|
19 | 10 | #include <linux/export.h> |
---|
20 | 11 | #include <linux/extable.h> |
---|
21 | 12 | #include <linux/moduleloader.h> |
---|
| 13 | +#include <linux/module_signature.h> |
---|
22 | 14 | #include <linux/trace_events.h> |
---|
23 | 15 | #include <linux/init.h> |
---|
24 | 16 | #include <linux/kallsyms.h> |
---|
.. | .. |
---|
26 | 18 | #include <linux/fs.h> |
---|
27 | 19 | #include <linux/sysfs.h> |
---|
28 | 20 | #include <linux/kernel.h> |
---|
| 21 | +#include <linux/kernel_read_file.h> |
---|
29 | 22 | #include <linux/slab.h> |
---|
30 | 23 | #include <linux/vmalloc.h> |
---|
31 | 24 | #include <linux/elf.h> |
---|
.. | .. |
---|
70 | 63 | #define CREATE_TRACE_POINTS |
---|
71 | 64 | #include <trace/events/module.h> |
---|
72 | 65 | |
---|
| 66 | +#undef CREATE_TRACE_POINTS |
---|
| 67 | +#include <trace/hooks/module.h> |
---|
| 68 | +#include <trace/hooks/memory.h> |
---|
| 69 | + |
---|
73 | 70 | #ifndef ARCH_SHF_SMALL |
---|
74 | 71 | #define ARCH_SHF_SMALL 0 |
---|
75 | 72 | #endif |
---|
76 | 73 | |
---|
77 | 74 | /* |
---|
78 | 75 | * Modules' sections will be aligned on page boundaries |
---|
79 | | - * to ensure complete separation of code and data |
---|
| 76 | + * to ensure complete separation of code and data, but |
---|
| 77 | + * only when CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y |
---|
80 | 78 | */ |
---|
| 79 | +#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX |
---|
81 | 80 | # define debug_align(X) ALIGN(X, PAGE_SIZE) |
---|
| 81 | +#else |
---|
| 82 | +# define debug_align(X) (X) |
---|
| 83 | +#endif |
---|
82 | 84 | |
---|
83 | 85 | /* If this is set, the section belongs in the init part of the module */ |
---|
84 | 86 | #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) |
---|
.. | .. |
---|
90 | 92 | * 3) module_addr_min/module_addr_max. |
---|
91 | 93 | * (delete and add uses RCU list operations). */ |
---|
92 | 94 | DEFINE_MUTEX(module_mutex); |
---|
93 | | -EXPORT_SYMBOL_GPL(module_mutex); |
---|
94 | 95 | static LIST_HEAD(modules); |
---|
| 96 | + |
---|
| 97 | +/* Work queue for freeing init sections in success case */ |
---|
| 98 | +static void do_free_init(struct work_struct *w); |
---|
| 99 | +static DECLARE_WORK(init_free_wq, do_free_init); |
---|
| 100 | +static LLIST_HEAD(init_free_list); |
---|
95 | 101 | |
---|
96 | 102 | #ifdef CONFIG_MODULES_TREE_LOOKUP |
---|
97 | 103 | |
---|
.. | .. |
---|
216 | 222 | { |
---|
217 | 223 | struct module *mod; |
---|
218 | 224 | |
---|
219 | | - list_for_each_entry_rcu(mod, &modules, list) { |
---|
| 225 | + list_for_each_entry_rcu(mod, &modules, list, |
---|
| 226 | + lockdep_is_held(&module_mutex)) { |
---|
220 | 227 | if (within_module(addr, mod)) |
---|
221 | 228 | return mod; |
---|
222 | 229 | } |
---|
.. | .. |
---|
454 | 461 | if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data)) |
---|
455 | 462 | return true; |
---|
456 | 463 | |
---|
457 | | - list_for_each_entry_rcu(mod, &modules, list) { |
---|
| 464 | + list_for_each_entry_rcu(mod, &modules, list, |
---|
| 465 | + lockdep_is_held(&module_mutex)) { |
---|
458 | 466 | struct symsearch arr[] = { |
---|
459 | 467 | { mod->syms, mod->syms + mod->num_syms, mod->crcs, |
---|
460 | 468 | NOT_GPL_ONLY, false }, |
---|
.. | .. |
---|
499 | 507 | enum mod_license license; |
---|
500 | 508 | }; |
---|
501 | 509 | |
---|
502 | | -static bool check_symbol(const struct symsearch *syms, |
---|
503 | | - struct module *owner, |
---|
504 | | - unsigned int symnum, void *data) |
---|
| 510 | +static bool check_exported_symbol(const struct symsearch *syms, |
---|
| 511 | + struct module *owner, |
---|
| 512 | + unsigned int symnum, void *data) |
---|
505 | 513 | { |
---|
506 | 514 | struct find_symbol_arg *fsa = data; |
---|
507 | 515 | |
---|
.. | .. |
---|
552 | 560 | #endif |
---|
553 | 561 | } |
---|
554 | 562 | |
---|
555 | | -static int cmp_name(const void *va, const void *vb) |
---|
| 563 | +static const char *kernel_symbol_namespace(const struct kernel_symbol *sym) |
---|
556 | 564 | { |
---|
557 | | - const char *a; |
---|
558 | | - const struct kernel_symbol *b; |
---|
559 | | - a = va; b = vb; |
---|
560 | | - return strcmp(a, kernel_symbol_name(b)); |
---|
| 565 | +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS |
---|
| 566 | + if (!sym->namespace_offset) |
---|
| 567 | + return NULL; |
---|
| 568 | + return offset_to_ptr(&sym->namespace_offset); |
---|
| 569 | +#else |
---|
| 570 | + return sym->namespace; |
---|
| 571 | +#endif |
---|
561 | 572 | } |
---|
562 | 573 | |
---|
563 | | -static bool find_symbol_in_section(const struct symsearch *syms, |
---|
564 | | - struct module *owner, |
---|
565 | | - void *data) |
---|
| 574 | +static int cmp_name(const void *name, const void *sym) |
---|
| 575 | +{ |
---|
| 576 | + return strcmp(name, kernel_symbol_name(sym)); |
---|
| 577 | +} |
---|
| 578 | + |
---|
| 579 | +static bool find_exported_symbol_in_section(const struct symsearch *syms, |
---|
| 580 | + struct module *owner, |
---|
| 581 | + void *data) |
---|
566 | 582 | { |
---|
567 | 583 | struct find_symbol_arg *fsa = data; |
---|
568 | 584 | struct kernel_symbol *sym; |
---|
.. | .. |
---|
570 | 586 | sym = bsearch(fsa->name, syms->start, syms->stop - syms->start, |
---|
571 | 587 | sizeof(struct kernel_symbol), cmp_name); |
---|
572 | 588 | |
---|
573 | | - if (sym != NULL && check_symbol(syms, owner, sym - syms->start, data)) |
---|
| 589 | + if (sym != NULL && check_exported_symbol(syms, owner, |
---|
| 590 | + sym - syms->start, data)) |
---|
574 | 591 | return true; |
---|
575 | 592 | |
---|
576 | 593 | return false; |
---|
577 | 594 | } |
---|
578 | 595 | |
---|
579 | | -/* Find a symbol and return it, along with, (optional) crc and |
---|
| 596 | +/* Find an exported symbol and return it, along with, (optional) crc and |
---|
580 | 597 | * (optional) module which owns it. Needs preempt disabled or module_mutex. */ |
---|
581 | 598 | static const struct kernel_symbol *find_symbol(const char *name, |
---|
582 | 599 | struct module **owner, |
---|
.. | .. |
---|
591 | 608 | fsa.gplok = gplok; |
---|
592 | 609 | fsa.warn = warn; |
---|
593 | 610 | |
---|
594 | | - if (each_symbol_section(find_symbol_in_section, &fsa)) { |
---|
| 611 | + if (each_symbol_section(find_exported_symbol_in_section, &fsa)) { |
---|
595 | 612 | if (owner) |
---|
596 | 613 | *owner = fsa.owner; |
---|
597 | 614 | if (crc) |
---|
.. | .. |
---|
616 | 633 | |
---|
617 | 634 | module_assert_mutex_or_preempt(); |
---|
618 | 635 | |
---|
619 | | - list_for_each_entry_rcu(mod, &modules, list) { |
---|
| 636 | + list_for_each_entry_rcu(mod, &modules, list, |
---|
| 637 | + lockdep_is_held(&module_mutex)) { |
---|
620 | 638 | if (!even_unformed && mod->state == MODULE_STATE_UNFORMED) |
---|
621 | 639 | continue; |
---|
622 | 640 | if (strlen(mod->name) == len && !memcmp(mod->name, name, len)) |
---|
.. | .. |
---|
630 | 648 | module_assert_mutex(); |
---|
631 | 649 | return find_module_all(name, strlen(name), false); |
---|
632 | 650 | } |
---|
633 | | -EXPORT_SYMBOL_GPL(find_module); |
---|
634 | 651 | |
---|
635 | 652 | #ifdef CONFIG_SMP |
---|
636 | 653 | |
---|
.. | .. |
---|
796 | 813 | |
---|
797 | 814 | MODINFO_ATTR(version); |
---|
798 | 815 | MODINFO_ATTR(srcversion); |
---|
| 816 | +MODINFO_ATTR(scmversion); |
---|
799 | 817 | |
---|
800 | 818 | static char last_unloaded_module[MODULE_NAME_LEN+1]; |
---|
801 | 819 | |
---|
.. | .. |
---|
1258 | 1276 | &module_uevent, |
---|
1259 | 1277 | &modinfo_version, |
---|
1260 | 1278 | &modinfo_srcversion, |
---|
| 1279 | + &modinfo_scmversion, |
---|
1261 | 1280 | &modinfo_initstate, |
---|
1262 | 1281 | &modinfo_coresize, |
---|
1263 | 1282 | &modinfo_initsize, |
---|
.. | .. |
---|
1388 | 1407 | } |
---|
1389 | 1408 | #endif /* CONFIG_MODVERSIONS */ |
---|
1390 | 1409 | |
---|
| 1410 | +static char *get_modinfo(const struct load_info *info, const char *tag); |
---|
| 1411 | +static char *get_next_modinfo(const struct load_info *info, const char *tag, |
---|
| 1412 | + char *prev); |
---|
| 1413 | + |
---|
| 1414 | +static int verify_namespace_is_imported(const struct load_info *info, |
---|
| 1415 | + const struct kernel_symbol *sym, |
---|
| 1416 | + struct module *mod) |
---|
| 1417 | +{ |
---|
| 1418 | + const char *namespace; |
---|
| 1419 | + char *imported_namespace; |
---|
| 1420 | + |
---|
| 1421 | + namespace = kernel_symbol_namespace(sym); |
---|
| 1422 | + if (namespace && namespace[0]) { |
---|
| 1423 | + imported_namespace = get_modinfo(info, "import_ns"); |
---|
| 1424 | + while (imported_namespace) { |
---|
| 1425 | + if (strcmp(namespace, imported_namespace) == 0) |
---|
| 1426 | + return 0; |
---|
| 1427 | + imported_namespace = get_next_modinfo( |
---|
| 1428 | + info, "import_ns", imported_namespace); |
---|
| 1429 | + } |
---|
| 1430 | +#ifdef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS |
---|
| 1431 | + pr_warn( |
---|
| 1432 | +#else |
---|
| 1433 | + pr_err( |
---|
| 1434 | +#endif |
---|
| 1435 | + "%s: module uses symbol (%s) from namespace %s, but does not import it.\n", |
---|
| 1436 | + mod->name, kernel_symbol_name(sym), namespace); |
---|
| 1437 | +#ifndef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS |
---|
| 1438 | + return -EINVAL; |
---|
| 1439 | +#endif |
---|
| 1440 | + } |
---|
| 1441 | + return 0; |
---|
| 1442 | +} |
---|
| 1443 | + |
---|
| 1444 | +static bool inherit_taint(struct module *mod, struct module *owner) |
---|
| 1445 | +{ |
---|
| 1446 | + if (!owner || !test_bit(TAINT_PROPRIETARY_MODULE, &owner->taints)) |
---|
| 1447 | + return true; |
---|
| 1448 | + |
---|
| 1449 | + if (mod->using_gplonly_symbols) { |
---|
| 1450 | + pr_err("%s: module using GPL-only symbols uses symbols from proprietary module %s.\n", |
---|
| 1451 | + mod->name, owner->name); |
---|
| 1452 | + return false; |
---|
| 1453 | + } |
---|
| 1454 | + |
---|
| 1455 | + if (!test_bit(TAINT_PROPRIETARY_MODULE, &mod->taints)) { |
---|
| 1456 | + pr_warn("%s: module uses symbols from proprietary module %s, inheriting taint.\n", |
---|
| 1457 | + mod->name, owner->name); |
---|
| 1458 | + set_bit(TAINT_PROPRIETARY_MODULE, &mod->taints); |
---|
| 1459 | + } |
---|
| 1460 | + return true; |
---|
| 1461 | +} |
---|
| 1462 | + |
---|
1391 | 1463 | /* Resolve a symbol for this module. I.e. if we find one, record usage. */ |
---|
1392 | 1464 | static const struct kernel_symbol *resolve_symbol(struct module *mod, |
---|
1393 | 1465 | const struct load_info *info, |
---|
.. | .. |
---|
1412 | 1484 | if (!sym) |
---|
1413 | 1485 | goto unlock; |
---|
1414 | 1486 | |
---|
| 1487 | + if (license == GPL_ONLY) |
---|
| 1488 | + mod->using_gplonly_symbols = true; |
---|
| 1489 | + |
---|
| 1490 | + if (!inherit_taint(mod, owner)) { |
---|
| 1491 | + sym = NULL; |
---|
| 1492 | + goto getname; |
---|
| 1493 | + } |
---|
| 1494 | + |
---|
1415 | 1495 | if (!check_version(info, name, mod, crc)) { |
---|
1416 | 1496 | sym = ERR_PTR(-EINVAL); |
---|
| 1497 | + goto getname; |
---|
| 1498 | + } |
---|
| 1499 | + |
---|
| 1500 | + err = verify_namespace_is_imported(info, sym, mod); |
---|
| 1501 | + if (err) { |
---|
| 1502 | + sym = ERR_PTR(err); |
---|
1417 | 1503 | goto getname; |
---|
1418 | 1504 | } |
---|
1419 | 1505 | |
---|
.. | .. |
---|
1469 | 1555 | struct module_sect_attrs { |
---|
1470 | 1556 | struct attribute_group grp; |
---|
1471 | 1557 | unsigned int nsections; |
---|
1472 | | - struct module_sect_attr attrs[0]; |
---|
| 1558 | + struct module_sect_attr attrs[]; |
---|
1473 | 1559 | }; |
---|
1474 | 1560 | |
---|
1475 | 1561 | #define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4)) |
---|
.. | .. |
---|
1582 | 1668 | struct module_notes_attrs { |
---|
1583 | 1669 | struct kobject *dir; |
---|
1584 | 1670 | unsigned int notes; |
---|
1585 | | - struct bin_attribute attrs[0]; |
---|
| 1671 | + struct bin_attribute attrs[]; |
---|
1586 | 1672 | }; |
---|
1587 | 1673 | |
---|
1588 | 1674 | static ssize_t module_notes_read(struct file *filp, struct kobject *kobj, |
---|
.. | .. |
---|
1915 | 2001 | mod_sysfs_fini(mod); |
---|
1916 | 2002 | } |
---|
1917 | 2003 | |
---|
1918 | | -#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX |
---|
1919 | 2004 | /* |
---|
1920 | 2005 | * LKM RO/NX protection: protect module's text/ro-data |
---|
1921 | 2006 | * from modification and any data from execution. |
---|
.. | .. |
---|
1929 | 2014 | * |
---|
1930 | 2015 | * These values are always page-aligned (as is base) |
---|
1931 | 2016 | */ |
---|
| 2017 | + |
---|
| 2018 | +/* |
---|
| 2019 | + * Since some arches are moving towards PAGE_KERNEL module allocations instead |
---|
| 2020 | + * of PAGE_KERNEL_EXEC, keep frob_text() and module_enable_x() outside of the |
---|
| 2021 | + * CONFIG_STRICT_MODULE_RWX block below because they are needed regardless of |
---|
| 2022 | + * whether we are strict. |
---|
| 2023 | + */ |
---|
| 2024 | +#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX |
---|
1932 | 2025 | static void frob_text(const struct module_layout *layout, |
---|
1933 | 2026 | int (*set_memory)(unsigned long start, int num_pages)) |
---|
1934 | 2027 | { |
---|
.. | .. |
---|
1937 | 2030 | set_memory((unsigned long)layout->base, |
---|
1938 | 2031 | layout->text_size >> PAGE_SHIFT); |
---|
1939 | 2032 | } |
---|
| 2033 | + |
---|
| 2034 | +static void module_enable_x(const struct module *mod) |
---|
| 2035 | +{ |
---|
| 2036 | + frob_text(&mod->core_layout, set_memory_x); |
---|
| 2037 | + frob_text(&mod->init_layout, set_memory_x); |
---|
| 2038 | +} |
---|
| 2039 | +#else /* !CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ |
---|
| 2040 | +static void module_enable_x(const struct module *mod) { } |
---|
| 2041 | +#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ |
---|
1940 | 2042 | |
---|
1941 | 2043 | #ifdef CONFIG_STRICT_MODULE_RWX |
---|
1942 | 2044 | static void frob_rodata(const struct module_layout *layout, |
---|
.. | .. |
---|
1969 | 2071 | (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT); |
---|
1970 | 2072 | } |
---|
1971 | 2073 | |
---|
1972 | | -/* livepatching wants to disable read-only so it can frob module. */ |
---|
1973 | | -void module_disable_ro(const struct module *mod) |
---|
| 2074 | +static void module_enable_ro(const struct module *mod, bool after_init) |
---|
1974 | 2075 | { |
---|
1975 | 2076 | if (!rodata_enabled) |
---|
1976 | 2077 | return; |
---|
1977 | 2078 | |
---|
1978 | | - frob_text(&mod->core_layout, set_memory_rw); |
---|
1979 | | - frob_rodata(&mod->core_layout, set_memory_rw); |
---|
1980 | | - frob_ro_after_init(&mod->core_layout, set_memory_rw); |
---|
1981 | | - frob_text(&mod->init_layout, set_memory_rw); |
---|
1982 | | - frob_rodata(&mod->init_layout, set_memory_rw); |
---|
1983 | | -} |
---|
1984 | | - |
---|
1985 | | -void module_enable_ro(const struct module *mod, bool after_init) |
---|
1986 | | -{ |
---|
1987 | | - if (!rodata_enabled) |
---|
1988 | | - return; |
---|
1989 | | - |
---|
| 2079 | + set_vm_flush_reset_perms(mod->core_layout.base); |
---|
| 2080 | + set_vm_flush_reset_perms(mod->init_layout.base); |
---|
1990 | 2081 | frob_text(&mod->core_layout, set_memory_ro); |
---|
1991 | 2082 | |
---|
1992 | 2083 | frob_rodata(&mod->core_layout, set_memory_ro); |
---|
.. | .. |
---|
2006 | 2097 | frob_writable_data(&mod->init_layout, set_memory_nx); |
---|
2007 | 2098 | } |
---|
2008 | 2099 | |
---|
2009 | | -static void module_disable_nx(const struct module *mod) |
---|
| 2100 | +static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, |
---|
| 2101 | + char *secstrings, struct module *mod) |
---|
2010 | 2102 | { |
---|
2011 | | - frob_rodata(&mod->core_layout, set_memory_x); |
---|
2012 | | - frob_ro_after_init(&mod->core_layout, set_memory_x); |
---|
2013 | | - frob_writable_data(&mod->core_layout, set_memory_x); |
---|
2014 | | - frob_rodata(&mod->init_layout, set_memory_x); |
---|
2015 | | - frob_writable_data(&mod->init_layout, set_memory_x); |
---|
2016 | | -} |
---|
| 2103 | + const unsigned long shf_wx = SHF_WRITE|SHF_EXECINSTR; |
---|
| 2104 | + int i; |
---|
2017 | 2105 | |
---|
2018 | | -/* Iterate through all modules and set each module's text as RW */ |
---|
2019 | | -void set_all_modules_text_rw(void) |
---|
2020 | | -{ |
---|
2021 | | - struct module *mod; |
---|
2022 | | - |
---|
2023 | | - if (!rodata_enabled) |
---|
2024 | | - return; |
---|
2025 | | - |
---|
2026 | | - mutex_lock(&module_mutex); |
---|
2027 | | - list_for_each_entry_rcu(mod, &modules, list) { |
---|
2028 | | - if (mod->state == MODULE_STATE_UNFORMED) |
---|
2029 | | - continue; |
---|
2030 | | - |
---|
2031 | | - frob_text(&mod->core_layout, set_memory_rw); |
---|
2032 | | - frob_text(&mod->init_layout, set_memory_rw); |
---|
| 2106 | + for (i = 0; i < hdr->e_shnum; i++) { |
---|
| 2107 | + if ((sechdrs[i].sh_flags & shf_wx) == shf_wx) { |
---|
| 2108 | + pr_err("%s: section %s (index %d) has invalid WRITE|EXEC flags\n", |
---|
| 2109 | + mod->name, secstrings + sechdrs[i].sh_name, i); |
---|
| 2110 | + return -ENOEXEC; |
---|
| 2111 | + } |
---|
2033 | 2112 | } |
---|
2034 | | - mutex_unlock(&module_mutex); |
---|
2035 | | -} |
---|
2036 | 2113 | |
---|
2037 | | -/* Iterate through all modules and set each module's text as RO */ |
---|
2038 | | -void set_all_modules_text_ro(void) |
---|
2039 | | -{ |
---|
2040 | | - struct module *mod; |
---|
2041 | | - |
---|
2042 | | - if (!rodata_enabled) |
---|
2043 | | - return; |
---|
2044 | | - |
---|
2045 | | - mutex_lock(&module_mutex); |
---|
2046 | | - list_for_each_entry_rcu(mod, &modules, list) { |
---|
2047 | | - /* |
---|
2048 | | - * Ignore going modules since it's possible that ro |
---|
2049 | | - * protection has already been disabled, otherwise we'll |
---|
2050 | | - * run into protection faults at module deallocation. |
---|
2051 | | - */ |
---|
2052 | | - if (mod->state == MODULE_STATE_UNFORMED || |
---|
2053 | | - mod->state == MODULE_STATE_GOING) |
---|
2054 | | - continue; |
---|
2055 | | - |
---|
2056 | | - frob_text(&mod->core_layout, set_memory_ro); |
---|
2057 | | - frob_text(&mod->init_layout, set_memory_ro); |
---|
2058 | | - } |
---|
2059 | | - mutex_unlock(&module_mutex); |
---|
2060 | | -} |
---|
2061 | | - |
---|
2062 | | -static void disable_ro_nx(const struct module_layout *layout) |
---|
2063 | | -{ |
---|
2064 | | - if (rodata_enabled) { |
---|
2065 | | - frob_text(layout, set_memory_rw); |
---|
2066 | | - frob_rodata(layout, set_memory_rw); |
---|
2067 | | - frob_ro_after_init(layout, set_memory_rw); |
---|
2068 | | - } |
---|
2069 | | - frob_rodata(layout, set_memory_x); |
---|
2070 | | - frob_ro_after_init(layout, set_memory_x); |
---|
2071 | | - frob_writable_data(layout, set_memory_x); |
---|
| 2114 | + return 0; |
---|
2072 | 2115 | } |
---|
2073 | 2116 | |
---|
2074 | 2117 | #else /* !CONFIG_STRICT_MODULE_RWX */ |
---|
2075 | | -static void disable_ro_nx(const struct module_layout *layout) { } |
---|
2076 | 2118 | static void module_enable_nx(const struct module *mod) { } |
---|
2077 | | -static void module_disable_nx(const struct module *mod) { } |
---|
2078 | | -#endif /* CONFIG_STRICT_MODULE_RWX */ |
---|
2079 | | - |
---|
2080 | | -static void module_enable_x(const struct module *mod) |
---|
| 2119 | +static void module_enable_ro(const struct module *mod, bool after_init) {} |
---|
| 2120 | +static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, |
---|
| 2121 | + char *secstrings, struct module *mod) |
---|
2081 | 2122 | { |
---|
2082 | | - frob_text(&mod->core_layout, set_memory_x); |
---|
2083 | | - frob_text(&mod->init_layout, set_memory_x); |
---|
| 2123 | + return 0; |
---|
2084 | 2124 | } |
---|
2085 | | -#else /* !CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ |
---|
2086 | | -static void disable_ro_nx(const struct module_layout *layout) { } |
---|
2087 | | -static void module_enable_nx(const struct module *mod) { } |
---|
2088 | | -static void module_disable_nx(const struct module *mod) { } |
---|
2089 | | -static void module_enable_x(const struct module *mod) { } |
---|
2090 | | -#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ |
---|
| 2125 | +#endif /* CONFIG_STRICT_MODULE_RWX */ |
---|
2091 | 2126 | |
---|
2092 | 2127 | #ifdef CONFIG_LIVEPATCH |
---|
2093 | 2128 | /* |
---|
.. | .. |
---|
2166 | 2201 | |
---|
2167 | 2202 | void __weak module_memfree(void *module_region) |
---|
2168 | 2203 | { |
---|
| 2204 | + /* |
---|
| 2205 | + * This memory may be RO, and freeing RO memory in an interrupt is not |
---|
| 2206 | + * supported by vmalloc. |
---|
| 2207 | + */ |
---|
| 2208 | + WARN_ON(in_interrupt()); |
---|
2169 | 2209 | vfree(module_region); |
---|
2170 | 2210 | } |
---|
2171 | 2211 | |
---|
.. | .. |
---|
2215 | 2255 | /* Remove this module from bug list, this uses list_del_rcu */ |
---|
2216 | 2256 | module_bug_cleanup(mod); |
---|
2217 | 2257 | /* Wait for RCU-sched synchronizing before releasing mod->list and buglist. */ |
---|
2218 | | - synchronize_sched(); |
---|
| 2258 | + synchronize_rcu(); |
---|
2219 | 2259 | mutex_unlock(&module_mutex); |
---|
2220 | | - |
---|
2221 | | - /* This may be empty, but that's OK */ |
---|
2222 | | - disable_ro_nx(&mod->init_layout); |
---|
2223 | 2260 | |
---|
2224 | 2261 | /* Clean up CFI for the module. */ |
---|
2225 | 2262 | cfi_cleanup(mod); |
---|
2226 | 2263 | |
---|
| 2264 | + /* This may be empty, but that's OK */ |
---|
2227 | 2265 | module_arch_freeing_init(mod); |
---|
| 2266 | + trace_android_vh_set_memory_rw((unsigned long)mod->init_layout.base, |
---|
| 2267 | + (mod->init_layout.size)>>PAGE_SHIFT); |
---|
| 2268 | + trace_android_vh_set_memory_nx((unsigned long)mod->init_layout.base, |
---|
| 2269 | + (mod->init_layout.size)>>PAGE_SHIFT); |
---|
2228 | 2270 | module_memfree(mod->init_layout.base); |
---|
2229 | 2271 | kfree(mod->args); |
---|
2230 | 2272 | percpu_modfree(mod); |
---|
.. | .. |
---|
2233 | 2275 | lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size); |
---|
2234 | 2276 | |
---|
2235 | 2277 | /* Finally, free the core (containing the module structure) */ |
---|
2236 | | - disable_ro_nx(&mod->core_layout); |
---|
| 2278 | + trace_android_vh_set_memory_rw((unsigned long)mod->core_layout.base, |
---|
| 2279 | + (mod->core_layout.size)>>PAGE_SHIFT); |
---|
| 2280 | + trace_android_vh_set_memory_nx((unsigned long)mod->core_layout.base, |
---|
| 2281 | + (mod->core_layout.size)>>PAGE_SHIFT); |
---|
2237 | 2282 | module_memfree(mod->core_layout.base); |
---|
2238 | 2283 | } |
---|
2239 | 2284 | |
---|
2240 | 2285 | void *__symbol_get(const char *symbol) |
---|
2241 | 2286 | { |
---|
2242 | 2287 | struct module *owner; |
---|
| 2288 | + enum mod_license license; |
---|
2243 | 2289 | const struct kernel_symbol *sym; |
---|
2244 | 2290 | |
---|
2245 | 2291 | preempt_disable(); |
---|
2246 | | - sym = find_symbol(symbol, &owner, NULL, NULL, true, true); |
---|
2247 | | - if (sym && strong_try_module_get(owner)) |
---|
| 2292 | + sym = find_symbol(symbol, &owner, NULL, &license, true, true); |
---|
| 2293 | + if (!sym) |
---|
| 2294 | + goto fail; |
---|
| 2295 | + if (license != GPL_ONLY) { |
---|
| 2296 | + pr_warn("failing symbol_get of non-GPLONLY symbol %s.\n", |
---|
| 2297 | + symbol); |
---|
| 2298 | + goto fail; |
---|
| 2299 | + } |
---|
| 2300 | + if (strong_try_module_get(owner)) |
---|
2248 | 2301 | sym = NULL; |
---|
2249 | 2302 | preempt_enable(); |
---|
2250 | 2303 | |
---|
2251 | 2304 | return sym ? (void *)kernel_symbol_value(sym) : NULL; |
---|
| 2305 | +fail: |
---|
| 2306 | + preempt_enable(); |
---|
| 2307 | + return NULL; |
---|
2252 | 2308 | } |
---|
2253 | 2309 | EXPORT_SYMBOL_GPL(__symbol_get); |
---|
| 2310 | + |
---|
| 2311 | +bool module_init_layout_section(const char *sname) |
---|
| 2312 | +{ |
---|
| 2313 | +#ifndef CONFIG_MODULE_UNLOAD |
---|
| 2314 | + if (module_exit_section(sname)) |
---|
| 2315 | + return true; |
---|
| 2316 | +#endif |
---|
| 2317 | + return module_init_section(sname); |
---|
| 2318 | +} |
---|
2254 | 2319 | |
---|
2255 | 2320 | /* |
---|
2256 | 2321 | * Ensure that an exported symbol [global namespace] does not already exist |
---|
.. | .. |
---|
2258 | 2323 | * |
---|
2259 | 2324 | * You must hold the module_mutex. |
---|
2260 | 2325 | */ |
---|
2261 | | -static int verify_export_symbols(struct module *mod) |
---|
| 2326 | +static int verify_exported_symbols(struct module *mod) |
---|
2262 | 2327 | { |
---|
2263 | 2328 | unsigned int i; |
---|
2264 | 2329 | struct module *owner; |
---|
.. | .. |
---|
2393 | 2458 | if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC)) |
---|
2394 | 2459 | continue; |
---|
2395 | 2460 | |
---|
2396 | | - /* Livepatch relocation sections are applied by livepatch */ |
---|
2397 | 2461 | if (info->sechdrs[i].sh_flags & SHF_RELA_LIVEPATCH) |
---|
2398 | | - continue; |
---|
2399 | | - |
---|
2400 | | - if (info->sechdrs[i].sh_type == SHT_REL) |
---|
| 2462 | + err = klp_apply_section_relocs(mod, info->sechdrs, |
---|
| 2463 | + info->secstrings, |
---|
| 2464 | + info->strtab, |
---|
| 2465 | + info->index.sym, i, |
---|
| 2466 | + NULL); |
---|
| 2467 | + else if (info->sechdrs[i].sh_type == SHT_REL) |
---|
2401 | 2468 | err = apply_relocate(info->sechdrs, info->strtab, |
---|
2402 | 2469 | info->index.sym, i, mod); |
---|
2403 | 2470 | else if (info->sechdrs[i].sh_type == SHT_RELA) |
---|
.. | .. |
---|
2459 | 2526 | if ((s->sh_flags & masks[m][0]) != masks[m][0] |
---|
2460 | 2527 | || (s->sh_flags & masks[m][1]) |
---|
2461 | 2528 | || s->sh_entsize != ~0UL |
---|
2462 | | - || strstarts(sname, ".init")) |
---|
| 2529 | + || module_init_layout_section(sname)) |
---|
2463 | 2530 | continue; |
---|
2464 | 2531 | s->sh_entsize = get_offset(mod, &mod->core_layout.size, s, i); |
---|
2465 | 2532 | pr_debug("\t%s\n", sname); |
---|
.. | .. |
---|
2492 | 2559 | if ((s->sh_flags & masks[m][0]) != masks[m][0] |
---|
2493 | 2560 | || (s->sh_flags & masks[m][1]) |
---|
2494 | 2561 | || s->sh_entsize != ~0UL |
---|
2495 | | - || !strstarts(sname, ".init")) |
---|
| 2562 | + || !module_init_layout_section(sname)) |
---|
2496 | 2563 | continue; |
---|
2497 | 2564 | s->sh_entsize = (get_offset(mod, &mod->init_layout.size, s, i) |
---|
2498 | 2565 | | INIT_OFFSET_MASK); |
---|
.. | .. |
---|
2554 | 2621 | return string; |
---|
2555 | 2622 | } |
---|
2556 | 2623 | |
---|
2557 | | -static char *get_modinfo(struct load_info *info, const char *tag) |
---|
| 2624 | +static char *get_next_modinfo(const struct load_info *info, const char *tag, |
---|
| 2625 | + char *prev) |
---|
2558 | 2626 | { |
---|
2559 | 2627 | char *p; |
---|
2560 | 2628 | unsigned int taglen = strlen(tag); |
---|
.. | .. |
---|
2565 | 2633 | * get_modinfo() calls made before rewrite_section_headers() |
---|
2566 | 2634 | * must use sh_offset, as sh_addr isn't set! |
---|
2567 | 2635 | */ |
---|
2568 | | - for (p = (char *)info->hdr + infosec->sh_offset; p; p = next_string(p, &size)) { |
---|
| 2636 | + char *modinfo = (char *)info->hdr + infosec->sh_offset; |
---|
| 2637 | + |
---|
| 2638 | + if (prev) { |
---|
| 2639 | + size -= prev - modinfo; |
---|
| 2640 | + modinfo = next_string(prev, &size); |
---|
| 2641 | + } |
---|
| 2642 | + |
---|
| 2643 | + for (p = modinfo; p; p = next_string(p, &size)) { |
---|
2569 | 2644 | if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') |
---|
2570 | 2645 | return p + taglen + 1; |
---|
2571 | 2646 | } |
---|
2572 | 2647 | return NULL; |
---|
| 2648 | +} |
---|
| 2649 | + |
---|
| 2650 | +static char *get_modinfo(const struct load_info *info, const char *tag) |
---|
| 2651 | +{ |
---|
| 2652 | + return get_next_modinfo(info, tag, NULL); |
---|
2573 | 2653 | } |
---|
2574 | 2654 | |
---|
2575 | 2655 | static void setup_modinfo(struct module *mod, struct load_info *info) |
---|
.. | .. |
---|
2596 | 2676 | |
---|
2597 | 2677 | #ifdef CONFIG_KALLSYMS |
---|
2598 | 2678 | |
---|
2599 | | -/* lookup symbol in given range of kernel_symbols */ |
---|
2600 | | -static const struct kernel_symbol *lookup_symbol(const char *name, |
---|
2601 | | - const struct kernel_symbol *start, |
---|
2602 | | - const struct kernel_symbol *stop) |
---|
| 2679 | +/* Lookup exported symbol in given range of kernel_symbols */ |
---|
| 2680 | +static const struct kernel_symbol *lookup_exported_symbol(const char *name, |
---|
| 2681 | + const struct kernel_symbol *start, |
---|
| 2682 | + const struct kernel_symbol *stop) |
---|
2603 | 2683 | { |
---|
2604 | 2684 | return bsearch(name, start, stop - start, |
---|
2605 | 2685 | sizeof(struct kernel_symbol), cmp_name); |
---|
.. | .. |
---|
2610 | 2690 | { |
---|
2611 | 2691 | const struct kernel_symbol *ks; |
---|
2612 | 2692 | if (!mod) |
---|
2613 | | - ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab); |
---|
| 2693 | + ks = lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab); |
---|
2614 | 2694 | else |
---|
2615 | | - ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms); |
---|
| 2695 | + ks = lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms); |
---|
| 2696 | + |
---|
2616 | 2697 | return ks != NULL && kernel_symbol_value(ks) == value; |
---|
2617 | 2698 | } |
---|
2618 | 2699 | |
---|
.. | .. |
---|
2720 | 2801 | info->symoffs = ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1); |
---|
2721 | 2802 | info->stroffs = mod->core_layout.size = info->symoffs + ndst * sizeof(Elf_Sym); |
---|
2722 | 2803 | mod->core_layout.size += strtab_size; |
---|
| 2804 | + info->core_typeoffs = mod->core_layout.size; |
---|
| 2805 | + mod->core_layout.size += ndst * sizeof(char); |
---|
2723 | 2806 | mod->core_layout.size = debug_align(mod->core_layout.size); |
---|
2724 | 2807 | |
---|
2725 | 2808 | /* Put string table section at end of init part of module. */ |
---|
.. | .. |
---|
2733 | 2816 | __alignof__(struct mod_kallsyms)); |
---|
2734 | 2817 | info->mod_kallsyms_init_off = mod->init_layout.size; |
---|
2735 | 2818 | mod->init_layout.size += sizeof(struct mod_kallsyms); |
---|
| 2819 | + info->init_typeoffs = mod->init_layout.size; |
---|
| 2820 | + mod->init_layout.size += nsrc * sizeof(char); |
---|
2736 | 2821 | mod->init_layout.size = debug_align(mod->init_layout.size); |
---|
2737 | 2822 | } |
---|
2738 | 2823 | |
---|
.. | .. |
---|
2756 | 2841 | mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym); |
---|
2757 | 2842 | /* Make sure we get permanent strtab: don't use info->strtab. */ |
---|
2758 | 2843 | mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr; |
---|
| 2844 | + mod->kallsyms->typetab = mod->init_layout.base + info->init_typeoffs; |
---|
2759 | 2845 | |
---|
2760 | | - /* Set types up while we still have access to sections. */ |
---|
2761 | | - for (i = 0; i < mod->kallsyms->num_symtab; i++) |
---|
2762 | | - mod->kallsyms->symtab[i].st_info |
---|
2763 | | - = elf_type(&mod->kallsyms->symtab[i], info); |
---|
2764 | | - |
---|
2765 | | - /* Now populate the cut down core kallsyms for after init. */ |
---|
| 2846 | + /* |
---|
| 2847 | + * Now populate the cut down core kallsyms for after init |
---|
| 2848 | + * and set types up while we still have access to sections. |
---|
| 2849 | + */ |
---|
2766 | 2850 | mod->core_kallsyms.symtab = dst = mod->core_layout.base + info->symoffs; |
---|
2767 | 2851 | mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs; |
---|
| 2852 | + mod->core_kallsyms.typetab = mod->core_layout.base + info->core_typeoffs; |
---|
2768 | 2853 | src = mod->kallsyms->symtab; |
---|
2769 | 2854 | for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) { |
---|
| 2855 | + mod->kallsyms->typetab[i] = elf_type(src + i, info); |
---|
2770 | 2856 | if (i == 0 || is_livepatch_module(mod) || |
---|
2771 | 2857 | is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, |
---|
2772 | 2858 | info->index.pcpu)) { |
---|
| 2859 | + mod->core_kallsyms.typetab[ndst] = |
---|
| 2860 | + mod->kallsyms->typetab[i]; |
---|
2773 | 2861 | dst[ndst] = src[i]; |
---|
2774 | 2862 | dst[ndst++].st_name = s - mod->core_kallsyms.strtab; |
---|
2775 | 2863 | s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name], |
---|
.. | .. |
---|
2792 | 2880 | { |
---|
2793 | 2881 | if (!debug) |
---|
2794 | 2882 | return; |
---|
2795 | | -#ifdef CONFIG_DYNAMIC_DEBUG |
---|
2796 | | - if (ddebug_add_module(debug, num, mod->name)) |
---|
2797 | | - pr_err("dynamic debug error adding module: %s\n", |
---|
2798 | | - debug->modname); |
---|
2799 | | -#endif |
---|
| 2883 | + ddebug_add_module(debug, num, mod->name); |
---|
2800 | 2884 | } |
---|
2801 | 2885 | |
---|
2802 | 2886 | static void dynamic_debug_remove(struct module *mod, struct _ddebug *debug) |
---|
.. | .. |
---|
2807 | 2891 | |
---|
2808 | 2892 | void * __weak module_alloc(unsigned long size) |
---|
2809 | 2893 | { |
---|
2810 | | - return vmalloc_exec(size); |
---|
| 2894 | + return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END, |
---|
| 2895 | + GFP_KERNEL, PAGE_KERNEL_EXEC, VM_FLUSH_RESET_PERMS, |
---|
| 2896 | + NUMA_NO_NODE, __builtin_return_address(0)); |
---|
| 2897 | +} |
---|
| 2898 | + |
---|
| 2899 | +bool __weak module_init_section(const char *name) |
---|
| 2900 | +{ |
---|
| 2901 | + return strstarts(name, ".init"); |
---|
| 2902 | +} |
---|
| 2903 | + |
---|
| 2904 | +bool __weak module_exit_section(const char *name) |
---|
| 2905 | +{ |
---|
| 2906 | + return strstarts(name, ".exit"); |
---|
2811 | 2907 | } |
---|
2812 | 2908 | |
---|
2813 | 2909 | #ifdef CONFIG_DEBUG_KMEMLEAK |
---|
.. | .. |
---|
2840 | 2936 | #ifdef CONFIG_MODULE_SIG |
---|
2841 | 2937 | static int module_sig_check(struct load_info *info, int flags) |
---|
2842 | 2938 | { |
---|
2843 | | - int err = -ENOKEY; |
---|
| 2939 | + int err = -ENODATA; |
---|
2844 | 2940 | const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; |
---|
| 2941 | + const char *reason; |
---|
2845 | 2942 | const void *mod = info->hdr; |
---|
2846 | 2943 | |
---|
2847 | 2944 | /* |
---|
.. | .. |
---|
2856 | 2953 | err = mod_verify_sig(mod, info); |
---|
2857 | 2954 | } |
---|
2858 | 2955 | |
---|
2859 | | - if (!err) { |
---|
| 2956 | + switch (err) { |
---|
| 2957 | + case 0: |
---|
2860 | 2958 | info->sig_ok = true; |
---|
2861 | 2959 | return 0; |
---|
| 2960 | + |
---|
| 2961 | + /* We don't permit modules to be loaded into trusted kernels |
---|
| 2962 | + * without a valid signature on them, but if we're not |
---|
| 2963 | + * enforcing, certain errors are non-fatal. |
---|
| 2964 | + */ |
---|
| 2965 | + case -ENODATA: |
---|
| 2966 | + reason = "unsigned module"; |
---|
| 2967 | + break; |
---|
| 2968 | + case -ENOPKG: |
---|
| 2969 | + reason = "module with unsupported crypto"; |
---|
| 2970 | + break; |
---|
| 2971 | + case -ENOKEY: |
---|
| 2972 | + reason = "module with unavailable key"; |
---|
| 2973 | + break; |
---|
| 2974 | + |
---|
| 2975 | + /* All other errors are fatal, including nomem, unparseable |
---|
| 2976 | + * signatures and signature check failures - even if signatures |
---|
| 2977 | + * aren't required. |
---|
| 2978 | + */ |
---|
| 2979 | + default: |
---|
| 2980 | + return err; |
---|
2862 | 2981 | } |
---|
2863 | 2982 | |
---|
2864 | | - /* Not having a signature is only an error if we're strict. */ |
---|
2865 | | - if (err == -ENOKEY && !is_module_sig_enforced()) |
---|
2866 | | - err = 0; |
---|
| 2983 | + if (is_module_sig_enforced()) { |
---|
| 2984 | + pr_notice("Loading of %s is rejected\n", reason); |
---|
| 2985 | + return -EKEYREJECTED; |
---|
| 2986 | + } |
---|
2867 | 2987 | |
---|
2868 | | - return err; |
---|
| 2988 | + return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); |
---|
2869 | 2989 | } |
---|
2870 | 2990 | #else /* !CONFIG_MODULE_SIG */ |
---|
2871 | 2991 | static int module_sig_check(struct load_info *info, int flags) |
---|
.. | .. |
---|
2874 | 2994 | } |
---|
2875 | 2995 | #endif /* !CONFIG_MODULE_SIG */ |
---|
2876 | 2996 | |
---|
2877 | | -/* Sanity checks against invalid binaries, wrong arch, weird elf version. */ |
---|
2878 | | -static int elf_header_check(struct load_info *info) |
---|
| 2997 | +static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr) |
---|
2879 | 2998 | { |
---|
| 2999 | + unsigned long secend; |
---|
| 3000 | + |
---|
| 3001 | + /* |
---|
| 3002 | + * Check for both overflow and offset/size being |
---|
| 3003 | + * too large. |
---|
| 3004 | + */ |
---|
| 3005 | + secend = shdr->sh_offset + shdr->sh_size; |
---|
| 3006 | + if (secend < shdr->sh_offset || secend > info->len) |
---|
| 3007 | + return -ENOEXEC; |
---|
| 3008 | + |
---|
| 3009 | + return 0; |
---|
| 3010 | +} |
---|
| 3011 | + |
---|
| 3012 | +/* |
---|
| 3013 | + * Sanity checks against invalid binaries, wrong arch, weird elf version. |
---|
| 3014 | + * |
---|
| 3015 | + * Also do basic validity checks against section offsets and sizes, the |
---|
| 3016 | + * section name string table, and the indices used for it (sh_name). |
---|
| 3017 | + */ |
---|
| 3018 | +static int elf_validity_check(struct load_info *info) |
---|
| 3019 | +{ |
---|
| 3020 | + unsigned int i; |
---|
| 3021 | + Elf_Shdr *shdr, *strhdr; |
---|
| 3022 | + int err; |
---|
| 3023 | + |
---|
2880 | 3024 | if (info->len < sizeof(*(info->hdr))) |
---|
2881 | 3025 | return -ENOEXEC; |
---|
2882 | 3026 | |
---|
.. | .. |
---|
2886 | 3030 | || info->hdr->e_shentsize != sizeof(Elf_Shdr)) |
---|
2887 | 3031 | return -ENOEXEC; |
---|
2888 | 3032 | |
---|
| 3033 | + /* |
---|
| 3034 | + * e_shnum is 16 bits, and sizeof(Elf_Shdr) is |
---|
| 3035 | + * known and small. So e_shnum * sizeof(Elf_Shdr) |
---|
| 3036 | + * will not overflow unsigned long on any platform. |
---|
| 3037 | + */ |
---|
2889 | 3038 | if (info->hdr->e_shoff >= info->len |
---|
2890 | 3039 | || (info->hdr->e_shnum * sizeof(Elf_Shdr) > |
---|
2891 | 3040 | info->len - info->hdr->e_shoff)) |
---|
2892 | 3041 | return -ENOEXEC; |
---|
| 3042 | + |
---|
| 3043 | + info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; |
---|
| 3044 | + |
---|
| 3045 | + /* |
---|
| 3046 | + * Verify if the section name table index is valid. |
---|
| 3047 | + */ |
---|
| 3048 | + if (info->hdr->e_shstrndx == SHN_UNDEF |
---|
| 3049 | + || info->hdr->e_shstrndx >= info->hdr->e_shnum) |
---|
| 3050 | + return -ENOEXEC; |
---|
| 3051 | + |
---|
| 3052 | + strhdr = &info->sechdrs[info->hdr->e_shstrndx]; |
---|
| 3053 | + err = validate_section_offset(info, strhdr); |
---|
| 3054 | + if (err < 0) |
---|
| 3055 | + return err; |
---|
| 3056 | + |
---|
| 3057 | + /* |
---|
| 3058 | + * The section name table must be NUL-terminated, as required |
---|
| 3059 | + * by the spec. This makes strcmp and pr_* calls that access |
---|
| 3060 | + * strings in the section safe. |
---|
| 3061 | + */ |
---|
| 3062 | + info->secstrings = (void *)info->hdr + strhdr->sh_offset; |
---|
| 3063 | + if (info->secstrings[strhdr->sh_size - 1] != '\0') |
---|
| 3064 | + return -ENOEXEC; |
---|
| 3065 | + |
---|
| 3066 | + /* |
---|
| 3067 | + * The code assumes that section 0 has a length of zero and |
---|
| 3068 | + * an addr of zero, so check for it. |
---|
| 3069 | + */ |
---|
| 3070 | + if (info->sechdrs[0].sh_type != SHT_NULL |
---|
| 3071 | + || info->sechdrs[0].sh_size != 0 |
---|
| 3072 | + || info->sechdrs[0].sh_addr != 0) |
---|
| 3073 | + return -ENOEXEC; |
---|
| 3074 | + |
---|
| 3075 | + for (i = 1; i < info->hdr->e_shnum; i++) { |
---|
| 3076 | + shdr = &info->sechdrs[i]; |
---|
| 3077 | + switch (shdr->sh_type) { |
---|
| 3078 | + case SHT_NULL: |
---|
| 3079 | + case SHT_NOBITS: |
---|
| 3080 | + continue; |
---|
| 3081 | + case SHT_SYMTAB: |
---|
| 3082 | + if (shdr->sh_link == SHN_UNDEF |
---|
| 3083 | + || shdr->sh_link >= info->hdr->e_shnum) |
---|
| 3084 | + return -ENOEXEC; |
---|
| 3085 | + fallthrough; |
---|
| 3086 | + default: |
---|
| 3087 | + err = validate_section_offset(info, shdr); |
---|
| 3088 | + if (err < 0) { |
---|
| 3089 | + pr_err("Invalid ELF section in module (section %u type %u)\n", |
---|
| 3090 | + i, shdr->sh_type); |
---|
| 3091 | + return err; |
---|
| 3092 | + } |
---|
| 3093 | + |
---|
| 3094 | + if (shdr->sh_flags & SHF_ALLOC) { |
---|
| 3095 | + if (shdr->sh_name >= strhdr->sh_size) { |
---|
| 3096 | + pr_err("Invalid ELF section name in module (section %u type %u)\n", |
---|
| 3097 | + i, shdr->sh_type); |
---|
| 3098 | + return -ENOEXEC; |
---|
| 3099 | + } |
---|
| 3100 | + } |
---|
| 3101 | + break; |
---|
| 3102 | + } |
---|
| 3103 | + } |
---|
2893 | 3104 | |
---|
2894 | 3105 | return 0; |
---|
2895 | 3106 | } |
---|
.. | .. |
---|
2955 | 3166 | if (info->len < sizeof(*(info->hdr))) |
---|
2956 | 3167 | return -ENOEXEC; |
---|
2957 | 3168 | |
---|
2958 | | - err = security_kernel_load_data(LOADING_MODULE); |
---|
| 3169 | + err = security_kernel_load_data(LOADING_MODULE, true); |
---|
2959 | 3170 | if (err) |
---|
2960 | 3171 | return err; |
---|
2961 | 3172 | |
---|
2962 | 3173 | /* Suck in entire file: we'll want most of it. */ |
---|
2963 | | - info->hdr = __vmalloc(info->len, |
---|
2964 | | - GFP_KERNEL | __GFP_NOWARN, PAGE_KERNEL); |
---|
| 3174 | + info->hdr = __vmalloc(info->len, GFP_KERNEL | __GFP_NOWARN); |
---|
2965 | 3175 | if (!info->hdr) |
---|
2966 | 3176 | return -ENOMEM; |
---|
2967 | 3177 | |
---|
2968 | 3178 | if (copy_chunked_from_user(info->hdr, umod, info->len) != 0) { |
---|
2969 | | - vfree(info->hdr); |
---|
2970 | | - return -EFAULT; |
---|
| 3179 | + err = -EFAULT; |
---|
| 3180 | + goto out; |
---|
2971 | 3181 | } |
---|
2972 | 3182 | |
---|
2973 | | - return 0; |
---|
| 3183 | + err = security_kernel_post_load_data((char *)info->hdr, info->len, |
---|
| 3184 | + LOADING_MODULE, "init_module"); |
---|
| 3185 | +out: |
---|
| 3186 | + if (err) |
---|
| 3187 | + vfree(info->hdr); |
---|
| 3188 | + |
---|
| 3189 | + return err; |
---|
2974 | 3190 | } |
---|
2975 | 3191 | |
---|
2976 | 3192 | static void free_copy(struct load_info *info) |
---|
.. | .. |
---|
2987 | 3203 | |
---|
2988 | 3204 | for (i = 1; i < info->hdr->e_shnum; i++) { |
---|
2989 | 3205 | Elf_Shdr *shdr = &info->sechdrs[i]; |
---|
2990 | | - if (shdr->sh_type != SHT_NOBITS |
---|
2991 | | - && info->len < shdr->sh_offset + shdr->sh_size) { |
---|
2992 | | - pr_err("Module len %lu truncated\n", info->len); |
---|
2993 | | - return -ENOEXEC; |
---|
2994 | | - } |
---|
2995 | 3206 | |
---|
2996 | 3207 | /* Mark all sections sh_addr with their address in the |
---|
2997 | 3208 | temporary image. */ |
---|
2998 | 3209 | shdr->sh_addr = (size_t)info->hdr + shdr->sh_offset; |
---|
2999 | 3210 | |
---|
3000 | | -#ifndef CONFIG_MODULE_UNLOAD |
---|
3001 | | - /* Don't load .exit sections */ |
---|
3002 | | - if (strstarts(info->secstrings+shdr->sh_name, ".exit")) |
---|
3003 | | - shdr->sh_flags &= ~(unsigned long)SHF_ALLOC; |
---|
3004 | | -#endif |
---|
3005 | 3211 | } |
---|
3006 | 3212 | |
---|
3007 | 3213 | /* Track but don't keep modinfo and version sections. */ |
---|
.. | .. |
---|
3022 | 3228 | static int setup_load_info(struct load_info *info, int flags) |
---|
3023 | 3229 | { |
---|
3024 | 3230 | unsigned int i; |
---|
3025 | | - |
---|
3026 | | - /* Set up the convenience variables */ |
---|
3027 | | - info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; |
---|
3028 | | - info->secstrings = (void *)info->hdr |
---|
3029 | | - + info->sechdrs[info->hdr->e_shstrndx].sh_offset; |
---|
3030 | 3231 | |
---|
3031 | 3232 | /* Try to find a name early so we can log errors with a module name */ |
---|
3032 | 3233 | info->index.info = find_sec(info, ".modinfo"); |
---|
.. | .. |
---|
3164 | 3365 | } |
---|
3165 | 3366 | #endif |
---|
3166 | 3367 | |
---|
| 3368 | + mod->noinstr_text_start = section_objs(info, ".noinstr.text", 1, |
---|
| 3369 | + &mod->noinstr_text_size); |
---|
| 3370 | + |
---|
3167 | 3371 | #ifdef CONFIG_TRACEPOINTS |
---|
3168 | 3372 | mod->tracepoints_ptrs = section_objs(info, "__tracepoints_ptrs", |
---|
3169 | 3373 | sizeof(*mod->tracepoints_ptrs), |
---|
3170 | 3374 | &mod->num_tracepoints); |
---|
| 3375 | +#endif |
---|
| 3376 | +#ifdef CONFIG_TREE_SRCU |
---|
| 3377 | + mod->srcu_struct_ptrs = section_objs(info, "___srcu_struct_ptrs", |
---|
| 3378 | + sizeof(*mod->srcu_struct_ptrs), |
---|
| 3379 | + &mod->num_srcu_structs); |
---|
| 3380 | +#endif |
---|
| 3381 | +#ifdef CONFIG_BPF_EVENTS |
---|
| 3382 | + mod->bpf_raw_events = section_objs(info, "__bpf_raw_tp_map", |
---|
| 3383 | + sizeof(*mod->bpf_raw_events), |
---|
| 3384 | + &mod->num_bpf_raw_events); |
---|
3171 | 3385 | #endif |
---|
3172 | 3386 | #ifdef CONFIG_JUMP_LABEL |
---|
3173 | 3387 | mod->jump_entries = section_objs(info, "__jump_table", |
---|
.. | .. |
---|
3189 | 3403 | #endif |
---|
3190 | 3404 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
---|
3191 | 3405 | /* sechdrs[0].sh_size is always zero */ |
---|
3192 | | - mod->ftrace_callsites = section_objs(info, "__mcount_loc", |
---|
| 3406 | + mod->ftrace_callsites = section_objs(info, FTRACE_CALLSITE_SECTION, |
---|
3193 | 3407 | sizeof(*mod->ftrace_callsites), |
---|
3194 | 3408 | &mod->num_ftrace_callsites); |
---|
3195 | 3409 | #endif |
---|
.. | .. |
---|
3198 | 3412 | sizeof(*mod->ei_funcs), |
---|
3199 | 3413 | &mod->num_ei_funcs); |
---|
3200 | 3414 | #endif |
---|
| 3415 | +#ifdef CONFIG_KPROBES |
---|
| 3416 | + mod->kprobes_text_start = section_objs(info, ".kprobes.text", 1, |
---|
| 3417 | + &mod->kprobes_text_size); |
---|
| 3418 | + mod->kprobe_blacklist = section_objs(info, "_kprobe_blacklist", |
---|
| 3419 | + sizeof(unsigned long), |
---|
| 3420 | + &mod->num_kprobe_blacklist); |
---|
| 3421 | +#endif |
---|
| 3422 | +#ifdef CONFIG_HAVE_STATIC_CALL_INLINE |
---|
| 3423 | + mod->static_call_sites = section_objs(info, ".static_call_sites", |
---|
| 3424 | + sizeof(*mod->static_call_sites), |
---|
| 3425 | + &mod->num_static_call_sites); |
---|
| 3426 | +#endif |
---|
3201 | 3427 | mod->extable = section_objs(info, "__ex_table", |
---|
3202 | 3428 | sizeof(*mod->extable), &mod->num_exentries); |
---|
3203 | 3429 | |
---|
3204 | 3430 | if (section_addr(info, "__obsparm")) |
---|
3205 | 3431 | pr_warn("%s: Ignoring obsolete parameters\n", mod->name); |
---|
3206 | 3432 | |
---|
3207 | | - info->debug = section_objs(info, "__verbose", |
---|
| 3433 | + info->debug = section_objs(info, "__dyndbg", |
---|
3208 | 3434 | sizeof(*info->debug), &info->num_debug); |
---|
3209 | 3435 | |
---|
3210 | 3436 | return 0; |
---|
.. | .. |
---|
3316 | 3542 | |
---|
3317 | 3543 | static void flush_module_icache(const struct module *mod) |
---|
3318 | 3544 | { |
---|
3319 | | - mm_segment_t old_fs; |
---|
3320 | | - |
---|
3321 | | - /* flush the icache in correct context */ |
---|
3322 | | - old_fs = get_fs(); |
---|
3323 | | - set_fs(KERNEL_DS); |
---|
3324 | | - |
---|
3325 | 3545 | /* |
---|
3326 | 3546 | * Flush the instruction cache, since we've played with text. |
---|
3327 | 3547 | * Do it before processing of module parameters, so the module |
---|
.. | .. |
---|
3333 | 3553 | + mod->init_layout.size); |
---|
3334 | 3554 | flush_icache_range((unsigned long)mod->core_layout.base, |
---|
3335 | 3555 | (unsigned long)mod->core_layout.base + mod->core_layout.size); |
---|
3336 | | - |
---|
3337 | | - set_fs(old_fs); |
---|
3338 | 3556 | } |
---|
3339 | 3557 | |
---|
3340 | 3558 | int __weak module_frob_arch_sections(Elf_Ehdr *hdr, |
---|
.. | .. |
---|
3382 | 3600 | if (err < 0) |
---|
3383 | 3601 | return ERR_PTR(err); |
---|
3384 | 3602 | |
---|
| 3603 | + err = module_enforce_rwx_sections(info->hdr, info->sechdrs, |
---|
| 3604 | + info->secstrings, info->mod); |
---|
| 3605 | + if (err < 0) |
---|
| 3606 | + return ERR_PTR(err); |
---|
| 3607 | + |
---|
3385 | 3608 | /* We will do a special allocation for per-cpu sections later. */ |
---|
3386 | 3609 | info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC; |
---|
3387 | 3610 | |
---|
.. | .. |
---|
3391 | 3614 | * Note: ro_after_init sections also have SHF_{WRITE,ALLOC} set. |
---|
3392 | 3615 | */ |
---|
3393 | 3616 | ndx = find_sec(info, ".data..ro_after_init"); |
---|
| 3617 | + if (ndx) |
---|
| 3618 | + info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT; |
---|
| 3619 | + /* |
---|
| 3620 | + * Mark the __jump_table section as ro_after_init as well: these data |
---|
| 3621 | + * structures are never modified, with the exception of entries that |
---|
| 3622 | + * refer to code in the __init section, which are annotated as such |
---|
| 3623 | + * at module load time. |
---|
| 3624 | + */ |
---|
| 3625 | + ndx = find_sec(info, "__jump_table"); |
---|
3394 | 3626 | if (ndx) |
---|
3395 | 3627 | info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT; |
---|
3396 | 3628 | |
---|
.. | .. |
---|
3416 | 3648 | { |
---|
3417 | 3649 | percpu_modfree(mod); |
---|
3418 | 3650 | module_arch_freeing_init(mod); |
---|
| 3651 | + trace_android_vh_set_memory_rw((unsigned long)mod->init_layout.base, |
---|
| 3652 | + (mod->init_layout.size)>>PAGE_SHIFT); |
---|
| 3653 | + trace_android_vh_set_memory_nx((unsigned long)mod->init_layout.base, |
---|
| 3654 | + (mod->init_layout.size)>>PAGE_SHIFT); |
---|
3419 | 3655 | module_memfree(mod->init_layout.base); |
---|
| 3656 | + trace_android_vh_set_memory_rw((unsigned long)mod->core_layout.base, |
---|
| 3657 | + (mod->core_layout.size)>>PAGE_SHIFT); |
---|
| 3658 | + trace_android_vh_set_memory_nx((unsigned long)mod->core_layout.base, |
---|
| 3659 | + (mod->core_layout.size)>>PAGE_SHIFT); |
---|
3420 | 3660 | module_memfree(mod->core_layout.base); |
---|
3421 | 3661 | } |
---|
3422 | 3662 | |
---|
.. | .. |
---|
3426 | 3666 | { |
---|
3427 | 3667 | return 0; |
---|
3428 | 3668 | } |
---|
3429 | | - |
---|
3430 | | -static void cfi_init(struct module *mod); |
---|
3431 | 3669 | |
---|
3432 | 3670 | static int post_relocation(struct module *mod, const struct load_info *info) |
---|
3433 | 3671 | { |
---|
.. | .. |
---|
3440 | 3678 | |
---|
3441 | 3679 | /* Setup kallsyms-specific fields. */ |
---|
3442 | 3680 | add_kallsyms(mod, info); |
---|
3443 | | - |
---|
3444 | | - /* Setup CFI for the module. */ |
---|
3445 | | - cfi_init(mod); |
---|
3446 | 3681 | |
---|
3447 | 3682 | /* Arch-specific module finalizing. */ |
---|
3448 | 3683 | return module_finalize(info->hdr, info->sechdrs, mod); |
---|
.. | .. |
---|
3462 | 3697 | sched_annotate_sleep(); |
---|
3463 | 3698 | mutex_lock(&module_mutex); |
---|
3464 | 3699 | mod = find_module_all(name, strlen(name), true); |
---|
3465 | | - ret = !mod || mod->state == MODULE_STATE_LIVE; |
---|
| 3700 | + ret = !mod || mod->state == MODULE_STATE_LIVE |
---|
| 3701 | + || mod->state == MODULE_STATE_GOING; |
---|
3466 | 3702 | mutex_unlock(&module_mutex); |
---|
3467 | 3703 | |
---|
3468 | 3704 | return ret; |
---|
.. | .. |
---|
3481 | 3717 | |
---|
3482 | 3718 | /* For freeing module_init on success, in case kallsyms traversing */ |
---|
3483 | 3719 | struct mod_initfree { |
---|
3484 | | - struct rcu_head rcu; |
---|
| 3720 | + struct llist_node node; |
---|
3485 | 3721 | void *module_init; |
---|
3486 | 3722 | }; |
---|
3487 | 3723 | |
---|
3488 | | -static void do_free_init(struct rcu_head *head) |
---|
| 3724 | +static void do_free_init(struct work_struct *w) |
---|
3489 | 3725 | { |
---|
3490 | | - struct mod_initfree *m = container_of(head, struct mod_initfree, rcu); |
---|
3491 | | - module_memfree(m->module_init); |
---|
3492 | | - kfree(m); |
---|
| 3726 | + struct llist_node *pos, *n, *list; |
---|
| 3727 | + struct mod_initfree *initfree; |
---|
| 3728 | + |
---|
| 3729 | + list = llist_del_all(&init_free_list); |
---|
| 3730 | + |
---|
| 3731 | + synchronize_rcu(); |
---|
| 3732 | + |
---|
| 3733 | + llist_for_each_safe(pos, n, list) { |
---|
| 3734 | + initfree = container_of(pos, struct mod_initfree, node); |
---|
| 3735 | + module_memfree(initfree->module_init); |
---|
| 3736 | + kfree(initfree); |
---|
| 3737 | + } |
---|
3493 | 3738 | } |
---|
3494 | 3739 | |
---|
3495 | 3740 | /* |
---|
.. | .. |
---|
3555 | 3800 | rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms); |
---|
3556 | 3801 | #endif |
---|
3557 | 3802 | module_enable_ro(mod, true); |
---|
| 3803 | + trace_android_vh_set_module_permit_after_init(mod); |
---|
3558 | 3804 | mod_tree_remove_init(mod); |
---|
3559 | | - disable_ro_nx(&mod->init_layout); |
---|
3560 | 3805 | module_arch_freeing_init(mod); |
---|
| 3806 | + trace_android_vh_set_memory_rw((unsigned long)mod->init_layout.base, |
---|
| 3807 | + (mod->init_layout.size)>>PAGE_SHIFT); |
---|
| 3808 | + trace_android_vh_set_memory_nx((unsigned long)mod->init_layout.base, |
---|
| 3809 | + (mod->init_layout.size)>>PAGE_SHIFT); |
---|
3561 | 3810 | mod->init_layout.base = NULL; |
---|
3562 | 3811 | mod->init_layout.size = 0; |
---|
3563 | 3812 | mod->init_layout.ro_size = 0; |
---|
.. | .. |
---|
3566 | 3815 | /* |
---|
3567 | 3816 | * We want to free module_init, but be aware that kallsyms may be |
---|
3568 | 3817 | * walking this with preempt disabled. In all the failure paths, we |
---|
3569 | | - * call synchronize_sched(), but we don't want to slow down the success |
---|
3570 | | - * path, so use actual RCU here. |
---|
| 3818 | + * call synchronize_rcu(), but we don't want to slow down the success |
---|
| 3819 | + * path. module_memfree() cannot be called in an interrupt, so do the |
---|
| 3820 | + * work and call synchronize_rcu() in a work queue. |
---|
| 3821 | + * |
---|
3571 | 3822 | * Note that module_alloc() on most architectures creates W+X page |
---|
3572 | 3823 | * mappings which won't be cleaned up until do_free_init() runs. Any |
---|
3573 | 3824 | * code such as mark_rodata_ro() which depends on those mappings to |
---|
3574 | 3825 | * be cleaned up needs to sync with the queued work - ie |
---|
3575 | | - * rcu_barrier_sched() |
---|
| 3826 | + * rcu_barrier() |
---|
3576 | 3827 | */ |
---|
3577 | | - call_rcu_sched(&freeinit->rcu, do_free_init); |
---|
| 3828 | + if (llist_add(&freeinit->node, &init_free_list)) |
---|
| 3829 | + schedule_work(&init_free_wq); |
---|
| 3830 | + |
---|
3578 | 3831 | mutex_unlock(&module_mutex); |
---|
3579 | 3832 | wake_up_all(&module_wq); |
---|
3580 | 3833 | |
---|
.. | .. |
---|
3585 | 3838 | fail: |
---|
3586 | 3839 | /* Try to protect us from buggy refcounters. */ |
---|
3587 | 3840 | mod->state = MODULE_STATE_GOING; |
---|
3588 | | - synchronize_sched(); |
---|
| 3841 | + synchronize_rcu(); |
---|
3589 | 3842 | module_put(mod); |
---|
3590 | 3843 | blocking_notifier_call_chain(&module_notify_list, |
---|
3591 | 3844 | MODULE_STATE_GOING, mod); |
---|
.. | .. |
---|
3616 | 3869 | |
---|
3617 | 3870 | mod->state = MODULE_STATE_UNFORMED; |
---|
3618 | 3871 | |
---|
3619 | | -again: |
---|
3620 | 3872 | mutex_lock(&module_mutex); |
---|
3621 | 3873 | old = find_module_all(mod->name, strlen(mod->name), true); |
---|
3622 | 3874 | if (old != NULL) { |
---|
3623 | | - if (old->state != MODULE_STATE_LIVE) { |
---|
| 3875 | + if (old->state == MODULE_STATE_COMING |
---|
| 3876 | + || old->state == MODULE_STATE_UNFORMED) { |
---|
3624 | 3877 | /* Wait in case it fails to load. */ |
---|
3625 | 3878 | mutex_unlock(&module_mutex); |
---|
3626 | 3879 | err = wait_event_interruptible(module_wq, |
---|
3627 | 3880 | finished_loading(mod->name)); |
---|
3628 | 3881 | if (err) |
---|
3629 | 3882 | goto out_unlocked; |
---|
3630 | | - goto again; |
---|
| 3883 | + |
---|
| 3884 | + /* The module might have gone in the meantime. */ |
---|
| 3885 | + mutex_lock(&module_mutex); |
---|
| 3886 | + old = find_module_all(mod->name, strlen(mod->name), |
---|
| 3887 | + true); |
---|
3631 | 3888 | } |
---|
3632 | | - err = -EEXIST; |
---|
| 3889 | + |
---|
| 3890 | + /* |
---|
| 3891 | + * We are here only when the same module was being loaded. Do |
---|
| 3892 | + * not try to load it again right now. It prevents long delays |
---|
| 3893 | + * caused by serialized module load failures. It might happen |
---|
| 3894 | + * when more devices of the same type trigger load of |
---|
| 3895 | + * a particular module. |
---|
| 3896 | + */ |
---|
| 3897 | + if (old && old->state == MODULE_STATE_LIVE) |
---|
| 3898 | + err = -EEXIST; |
---|
| 3899 | + else |
---|
| 3900 | + err = -EBUSY; |
---|
3633 | 3901 | goto out; |
---|
3634 | 3902 | } |
---|
3635 | 3903 | mod_update_bounds(mod); |
---|
.. | .. |
---|
3650 | 3918 | mutex_lock(&module_mutex); |
---|
3651 | 3919 | |
---|
3652 | 3920 | /* Find duplicate symbols (must be called under lock). */ |
---|
3653 | | - err = verify_export_symbols(mod); |
---|
| 3921 | + err = verify_exported_symbols(mod); |
---|
3654 | 3922 | if (err < 0) |
---|
3655 | 3923 | goto out; |
---|
3656 | 3924 | |
---|
.. | .. |
---|
3660 | 3928 | module_enable_ro(mod, false); |
---|
3661 | 3929 | module_enable_nx(mod); |
---|
3662 | 3930 | module_enable_x(mod); |
---|
| 3931 | + trace_android_vh_set_module_permit_before_init(mod); |
---|
3663 | 3932 | |
---|
3664 | 3933 | /* Mark state as coming so strong_try_module_get() ignores us, |
---|
3665 | 3934 | * but kallsyms etc. can see us. */ |
---|
.. | .. |
---|
3682 | 3951 | if (err) |
---|
3683 | 3952 | return err; |
---|
3684 | 3953 | |
---|
3685 | | - blocking_notifier_call_chain(&module_notify_list, |
---|
3686 | | - MODULE_STATE_COMING, mod); |
---|
3687 | | - return 0; |
---|
| 3954 | + err = blocking_notifier_call_chain_robust(&module_notify_list, |
---|
| 3955 | + MODULE_STATE_COMING, MODULE_STATE_GOING, mod); |
---|
| 3956 | + err = notifier_to_errno(err); |
---|
| 3957 | + if (err) |
---|
| 3958 | + klp_module_going(mod); |
---|
| 3959 | + |
---|
| 3960 | + return err; |
---|
3688 | 3961 | } |
---|
3689 | 3962 | |
---|
3690 | 3963 | static int unknown_module_param_cb(char *param, char *val, const char *modname, |
---|
.. | .. |
---|
3705 | 3978 | return 0; |
---|
3706 | 3979 | } |
---|
3707 | 3980 | |
---|
| 3981 | +static void cfi_init(struct module *mod); |
---|
| 3982 | + |
---|
3708 | 3983 | /* Allocate and load the module: note that size of section 0 is always |
---|
3709 | 3984 | zero, and we rely on this for optional sections. */ |
---|
3710 | 3985 | static int load_module(struct load_info *info, const char __user *uargs, |
---|
.. | .. |
---|
3714 | 3989 | long err = 0; |
---|
3715 | 3990 | char *after_dashes; |
---|
3716 | 3991 | |
---|
3717 | | - err = elf_header_check(info); |
---|
| 3992 | + /* |
---|
| 3993 | + * Do the signature check (if any) first. All that |
---|
| 3994 | + * the signature check needs is info->len, it does |
---|
| 3995 | + * not need any of the section info. That can be |
---|
| 3996 | + * set up later. This will minimize the chances |
---|
| 3997 | + * of a corrupt module causing problems before |
---|
| 3998 | + * we even get to the signature check. |
---|
| 3999 | + * |
---|
| 4000 | + * The check will also adjust info->len by stripping |
---|
| 4001 | + * off the sig length at the end of the module, making |
---|
| 4002 | + * checks against info->len more correct. |
---|
| 4003 | + */ |
---|
| 4004 | + err = module_sig_check(info, flags); |
---|
3718 | 4005 | if (err) |
---|
3719 | 4006 | goto free_copy; |
---|
3720 | 4007 | |
---|
| 4008 | + /* |
---|
| 4009 | + * Do basic sanity checks against the ELF header and |
---|
| 4010 | + * sections. |
---|
| 4011 | + */ |
---|
| 4012 | + err = elf_validity_check(info); |
---|
| 4013 | + if (err) { |
---|
| 4014 | + pr_err("Module has invalid ELF structures\n"); |
---|
| 4015 | + goto free_copy; |
---|
| 4016 | + } |
---|
| 4017 | + |
---|
| 4018 | + /* |
---|
| 4019 | + * Everything checks out, so set up the section info |
---|
| 4020 | + * in the info structure. |
---|
| 4021 | + */ |
---|
3721 | 4022 | err = setup_load_info(info, flags); |
---|
3722 | 4023 | if (err) |
---|
3723 | 4024 | goto free_copy; |
---|
3724 | 4025 | |
---|
| 4026 | + /* |
---|
| 4027 | + * Now that we know we have the correct module name, check |
---|
| 4028 | + * if it's blacklisted. |
---|
| 4029 | + */ |
---|
3725 | 4030 | if (blacklisted(info->name)) { |
---|
3726 | 4031 | err = -EPERM; |
---|
| 4032 | + pr_err("Module %s is blacklisted\n", info->name); |
---|
3727 | 4033 | goto free_copy; |
---|
3728 | 4034 | } |
---|
3729 | | - |
---|
3730 | | - err = module_sig_check(info, flags); |
---|
3731 | | - if (err) |
---|
3732 | | - goto free_copy; |
---|
3733 | 4035 | |
---|
3734 | 4036 | err = rewrite_section_headers(info, flags); |
---|
3735 | 4037 | if (err) |
---|
.. | .. |
---|
3805 | 4107 | |
---|
3806 | 4108 | flush_module_icache(mod); |
---|
3807 | 4109 | |
---|
| 4110 | + /* Setup CFI for the module. */ |
---|
| 4111 | + cfi_init(mod); |
---|
| 4112 | + |
---|
3808 | 4113 | /* Now copy in args */ |
---|
3809 | 4114 | mod->args = strndup_user(uargs, ~0UL >> 1); |
---|
3810 | 4115 | if (IS_ERR(mod->args)) { |
---|
.. | .. |
---|
3872 | 4177 | module_bug_cleanup(mod); |
---|
3873 | 4178 | mutex_unlock(&module_mutex); |
---|
3874 | 4179 | |
---|
3875 | | - /* we can't deallocate the module until we clear memory protection */ |
---|
3876 | | - module_disable_ro(mod); |
---|
3877 | | - module_disable_nx(mod); |
---|
3878 | | - |
---|
3879 | 4180 | ddebug_cleanup: |
---|
3880 | 4181 | ftrace_release_mod(mod); |
---|
3881 | 4182 | dynamic_debug_remove(mod, info->debug); |
---|
3882 | | - synchronize_sched(); |
---|
| 4183 | + synchronize_rcu(); |
---|
3883 | 4184 | kfree(mod->args); |
---|
3884 | 4185 | free_arch_cleanup: |
---|
| 4186 | + cfi_cleanup(mod); |
---|
3885 | 4187 | module_arch_cleanup(mod); |
---|
3886 | 4188 | free_modinfo: |
---|
3887 | 4189 | free_modinfo(mod); |
---|
.. | .. |
---|
3894 | 4196 | mod_tree_remove(mod); |
---|
3895 | 4197 | wake_up_all(&module_wq); |
---|
3896 | 4198 | /* Wait for RCU-sched synchronizing before releasing mod->list. */ |
---|
3897 | | - synchronize_sched(); |
---|
| 4199 | + synchronize_rcu(); |
---|
3898 | 4200 | mutex_unlock(&module_mutex); |
---|
3899 | 4201 | free_module: |
---|
3900 | 4202 | /* Free lock-classes; relies on the preceding sync_rcu() */ |
---|
.. | .. |
---|
3929 | 4231 | SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) |
---|
3930 | 4232 | { |
---|
3931 | 4233 | struct load_info info = { }; |
---|
3932 | | - loff_t size; |
---|
3933 | | - void *hdr; |
---|
| 4234 | + void *hdr = NULL; |
---|
3934 | 4235 | int err; |
---|
3935 | 4236 | |
---|
3936 | 4237 | err = may_init_module(); |
---|
.. | .. |
---|
3943 | 4244 | |MODULE_INIT_IGNORE_VERMAGIC)) |
---|
3944 | 4245 | return -EINVAL; |
---|
3945 | 4246 | |
---|
3946 | | - err = kernel_read_file_from_fd(fd, &hdr, &size, INT_MAX, |
---|
| 4247 | + err = kernel_read_file_from_fd(fd, 0, &hdr, INT_MAX, NULL, |
---|
3947 | 4248 | READING_MODULE); |
---|
3948 | | - if (err) |
---|
| 4249 | + if (err < 0) |
---|
3949 | 4250 | return err; |
---|
3950 | 4251 | info.hdr = hdr; |
---|
3951 | | - info.len = size; |
---|
| 4252 | + info.len = err; |
---|
3952 | 4253 | |
---|
3953 | 4254 | return load_module(&info, uargs, flags); |
---|
3954 | 4255 | } |
---|
.. | .. |
---|
3971 | 4272 | && (str[2] == '\0' || str[2] == '.'); |
---|
3972 | 4273 | } |
---|
3973 | 4274 | |
---|
3974 | | -static const char *symname(struct mod_kallsyms *kallsyms, unsigned int symnum) |
---|
| 4275 | +static inline int is_cfi_typeid_symbol(const char *str) |
---|
| 4276 | +{ |
---|
| 4277 | + return !strncmp(str, "__typeid__", 10); |
---|
| 4278 | +} |
---|
| 4279 | + |
---|
| 4280 | +static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum) |
---|
3975 | 4281 | { |
---|
3976 | 4282 | return kallsyms->strtab + kallsyms->symtab[symnum].st_name; |
---|
3977 | 4283 | } |
---|
3978 | 4284 | |
---|
3979 | | -static const char *get_ksymbol(struct module *mod, |
---|
3980 | | - unsigned long addr, |
---|
3981 | | - unsigned long *size, |
---|
3982 | | - unsigned long *offset) |
---|
| 4285 | +/* |
---|
| 4286 | + * Given a module and address, find the corresponding symbol and return its name |
---|
| 4287 | + * while providing its size and offset if needed. |
---|
| 4288 | + */ |
---|
| 4289 | +static const char *find_kallsyms_symbol(struct module *mod, |
---|
| 4290 | + unsigned long addr, |
---|
| 4291 | + unsigned long *size, |
---|
| 4292 | + unsigned long *offset) |
---|
3983 | 4293 | { |
---|
3984 | 4294 | unsigned int i, best = 0; |
---|
3985 | | - unsigned long nextval; |
---|
| 4295 | + unsigned long nextval, bestval; |
---|
3986 | 4296 | struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms); |
---|
3987 | 4297 | |
---|
3988 | 4298 | /* At worse, next value is at end of module */ |
---|
.. | .. |
---|
3991 | 4301 | else |
---|
3992 | 4302 | nextval = (unsigned long)mod->core_layout.base+mod->core_layout.text_size; |
---|
3993 | 4303 | |
---|
| 4304 | + bestval = kallsyms_symbol_value(&kallsyms->symtab[best]); |
---|
| 4305 | + |
---|
3994 | 4306 | /* Scan for closest preceding symbol, and next symbol. (ELF |
---|
3995 | 4307 | starts real symbols at 1). */ |
---|
3996 | 4308 | for (i = 1; i < kallsyms->num_symtab; i++) { |
---|
3997 | | - if (kallsyms->symtab[i].st_shndx == SHN_UNDEF) |
---|
| 4309 | + const Elf_Sym *sym = &kallsyms->symtab[i]; |
---|
| 4310 | + unsigned long thisval = kallsyms_symbol_value(sym); |
---|
| 4311 | + |
---|
| 4312 | + if (sym->st_shndx == SHN_UNDEF) |
---|
3998 | 4313 | continue; |
---|
3999 | 4314 | |
---|
4000 | 4315 | /* We ignore unnamed symbols: they're uninformative |
---|
4001 | 4316 | * and inserted at a whim. */ |
---|
4002 | | - if (*symname(kallsyms, i) == '\0' |
---|
4003 | | - || is_arm_mapping_symbol(symname(kallsyms, i))) |
---|
| 4317 | + if (*kallsyms_symbol_name(kallsyms, i) == '\0' |
---|
| 4318 | + || is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i)) |
---|
| 4319 | + || is_cfi_typeid_symbol(kallsyms_symbol_name(kallsyms, i))) |
---|
4004 | 4320 | continue; |
---|
4005 | 4321 | |
---|
4006 | | - if (kallsyms->symtab[i].st_value <= addr |
---|
4007 | | - && kallsyms->symtab[i].st_value > kallsyms->symtab[best].st_value) |
---|
| 4322 | + if (thisval <= addr && thisval > bestval) { |
---|
4008 | 4323 | best = i; |
---|
4009 | | - if (kallsyms->symtab[i].st_value > addr |
---|
4010 | | - && kallsyms->symtab[i].st_value < nextval) |
---|
4011 | | - nextval = kallsyms->symtab[i].st_value; |
---|
| 4324 | + bestval = thisval; |
---|
| 4325 | + } |
---|
| 4326 | + if (thisval > addr && thisval < nextval) |
---|
| 4327 | + nextval = thisval; |
---|
4012 | 4328 | } |
---|
4013 | 4329 | |
---|
4014 | 4330 | if (!best) |
---|
4015 | 4331 | return NULL; |
---|
4016 | 4332 | |
---|
4017 | 4333 | if (size) |
---|
4018 | | - *size = nextval - kallsyms->symtab[best].st_value; |
---|
| 4334 | + *size = nextval - bestval; |
---|
4019 | 4335 | if (offset) |
---|
4020 | | - *offset = addr - kallsyms->symtab[best].st_value; |
---|
4021 | | - return symname(kallsyms, best); |
---|
| 4336 | + *offset = addr - bestval; |
---|
| 4337 | + |
---|
| 4338 | + return kallsyms_symbol_name(kallsyms, best); |
---|
4022 | 4339 | } |
---|
4023 | 4340 | |
---|
4024 | 4341 | void * __weak dereference_module_function_descriptor(struct module *mod, |
---|
.. | .. |
---|
4043 | 4360 | if (mod) { |
---|
4044 | 4361 | if (modname) |
---|
4045 | 4362 | *modname = mod->name; |
---|
4046 | | - ret = get_ksymbol(mod, addr, size, offset); |
---|
| 4363 | + |
---|
| 4364 | + ret = find_kallsyms_symbol(mod, addr, size, offset); |
---|
4047 | 4365 | } |
---|
4048 | 4366 | /* Make a copy in here where it's safe */ |
---|
4049 | 4367 | if (ret) { |
---|
.. | .. |
---|
4066 | 4384 | if (within_module(addr, mod)) { |
---|
4067 | 4385 | const char *sym; |
---|
4068 | 4386 | |
---|
4069 | | - sym = get_ksymbol(mod, addr, NULL, NULL); |
---|
| 4387 | + sym = find_kallsyms_symbol(mod, addr, NULL, NULL); |
---|
4070 | 4388 | if (!sym) |
---|
4071 | 4389 | goto out; |
---|
| 4390 | + |
---|
4072 | 4391 | strlcpy(symname, sym, KSYM_NAME_LEN); |
---|
4073 | 4392 | preempt_enable(); |
---|
4074 | 4393 | return 0; |
---|
.. | .. |
---|
4091 | 4410 | if (within_module(addr, mod)) { |
---|
4092 | 4411 | const char *sym; |
---|
4093 | 4412 | |
---|
4094 | | - sym = get_ksymbol(mod, addr, size, offset); |
---|
| 4413 | + sym = find_kallsyms_symbol(mod, addr, size, offset); |
---|
4095 | 4414 | if (!sym) |
---|
4096 | 4415 | goto out; |
---|
4097 | 4416 | if (modname) |
---|
.. | .. |
---|
4120 | 4439 | continue; |
---|
4121 | 4440 | kallsyms = rcu_dereference_sched(mod->kallsyms); |
---|
4122 | 4441 | if (symnum < kallsyms->num_symtab) { |
---|
4123 | | - *value = kallsyms->symtab[symnum].st_value; |
---|
4124 | | - *type = kallsyms->symtab[symnum].st_info; |
---|
4125 | | - strlcpy(name, symname(kallsyms, symnum), KSYM_NAME_LEN); |
---|
| 4442 | + const Elf_Sym *sym = &kallsyms->symtab[symnum]; |
---|
| 4443 | + |
---|
| 4444 | + *value = kallsyms_symbol_value(sym); |
---|
| 4445 | + *type = kallsyms->typetab[symnum]; |
---|
| 4446 | + strlcpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN); |
---|
4126 | 4447 | strlcpy(module_name, mod->name, MODULE_NAME_LEN); |
---|
4127 | 4448 | *exported = is_exported(name, *value, mod); |
---|
4128 | 4449 | preempt_enable(); |
---|
.. | .. |
---|
4134 | 4455 | return -ERANGE; |
---|
4135 | 4456 | } |
---|
4136 | 4457 | |
---|
4137 | | -static unsigned long mod_find_symname(struct module *mod, const char *name) |
---|
| 4458 | +/* Given a module and name of symbol, find and return the symbol's value */ |
---|
| 4459 | +static unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name) |
---|
4138 | 4460 | { |
---|
4139 | 4461 | unsigned int i; |
---|
4140 | 4462 | struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms); |
---|
4141 | 4463 | |
---|
4142 | | - for (i = 0; i < kallsyms->num_symtab; i++) |
---|
4143 | | - if (strcmp(name, symname(kallsyms, i)) == 0 && |
---|
4144 | | - kallsyms->symtab[i].st_shndx != SHN_UNDEF) |
---|
4145 | | - return kallsyms->symtab[i].st_value; |
---|
| 4464 | + for (i = 0; i < kallsyms->num_symtab; i++) { |
---|
| 4465 | + const Elf_Sym *sym = &kallsyms->symtab[i]; |
---|
| 4466 | + |
---|
| 4467 | + if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) == 0 && |
---|
| 4468 | + sym->st_shndx != SHN_UNDEF) |
---|
| 4469 | + return kallsyms_symbol_value(sym); |
---|
| 4470 | + } |
---|
4146 | 4471 | return 0; |
---|
4147 | 4472 | } |
---|
4148 | 4473 | |
---|
.. | .. |
---|
4157 | 4482 | preempt_disable(); |
---|
4158 | 4483 | if ((colon = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) { |
---|
4159 | 4484 | if ((mod = find_module_all(name, colon - name, false)) != NULL) |
---|
4160 | | - ret = mod_find_symname(mod, colon+1); |
---|
| 4485 | + ret = find_kallsyms_symbol_value(mod, colon+1); |
---|
4161 | 4486 | } else { |
---|
4162 | 4487 | list_for_each_entry_rcu(mod, &modules, list) { |
---|
4163 | 4488 | if (mod->state == MODULE_STATE_UNFORMED) |
---|
4164 | 4489 | continue; |
---|
4165 | | - if ((ret = mod_find_symname(mod, name)) != 0) |
---|
| 4490 | + if ((ret = find_kallsyms_symbol_value(mod, name)) != 0) |
---|
4166 | 4491 | break; |
---|
4167 | 4492 | } |
---|
4168 | 4493 | } |
---|
.. | .. |
---|
4187 | 4512 | if (mod->state == MODULE_STATE_UNFORMED) |
---|
4188 | 4513 | continue; |
---|
4189 | 4514 | for (i = 0; i < kallsyms->num_symtab; i++) { |
---|
| 4515 | + const Elf_Sym *sym = &kallsyms->symtab[i]; |
---|
4190 | 4516 | |
---|
4191 | | - if (kallsyms->symtab[i].st_shndx == SHN_UNDEF) |
---|
| 4517 | + if (sym->st_shndx == SHN_UNDEF) |
---|
4192 | 4518 | continue; |
---|
4193 | 4519 | |
---|
4194 | | - ret = fn(data, symname(kallsyms, i), |
---|
4195 | | - mod, kallsyms->symtab[i].st_value); |
---|
| 4520 | + ret = fn(data, kallsyms_symbol_name(kallsyms, i), |
---|
| 4521 | + mod, kallsyms_symbol_value(sym)); |
---|
4196 | 4522 | if (ret != 0) |
---|
4197 | 4523 | return ret; |
---|
4198 | 4524 | } |
---|
.. | .. |
---|
4204 | 4530 | static void cfi_init(struct module *mod) |
---|
4205 | 4531 | { |
---|
4206 | 4532 | #ifdef CONFIG_CFI_CLANG |
---|
4207 | | - preempt_disable(); |
---|
4208 | | - mod->cfi_check = |
---|
4209 | | - (cfi_check_fn)mod_find_symname(mod, CFI_CHECK_FN_NAME); |
---|
4210 | | - preempt_enable(); |
---|
4211 | | - cfi_module_add(mod, module_addr_min, module_addr_max); |
---|
| 4533 | + initcall_t *init; |
---|
| 4534 | + exitcall_t *exit; |
---|
| 4535 | + |
---|
| 4536 | + rcu_read_lock_sched(); |
---|
| 4537 | + mod->cfi_check = (cfi_check_fn) |
---|
| 4538 | + find_kallsyms_symbol_value(mod, "__cfi_check"); |
---|
| 4539 | + init = (initcall_t *) |
---|
| 4540 | + find_kallsyms_symbol_value(mod, "__cfi_jt_init_module"); |
---|
| 4541 | + exit = (exitcall_t *) |
---|
| 4542 | + find_kallsyms_symbol_value(mod, "__cfi_jt_cleanup_module"); |
---|
| 4543 | + rcu_read_unlock_sched(); |
---|
| 4544 | + |
---|
| 4545 | + /* Fix init/exit functions to point to the CFI jump table */ |
---|
| 4546 | + if (init) mod->init = *init; |
---|
| 4547 | + if (exit) mod->exit = *exit; |
---|
| 4548 | + |
---|
| 4549 | + cfi_module_add(mod, module_addr_min); |
---|
4212 | 4550 | #endif |
---|
4213 | 4551 | } |
---|
4214 | 4552 | |
---|
4215 | 4553 | static void cfi_cleanup(struct module *mod) |
---|
4216 | 4554 | { |
---|
4217 | 4555 | #ifdef CONFIG_CFI_CLANG |
---|
4218 | | - cfi_module_remove(mod, module_addr_min, module_addr_max); |
---|
| 4556 | + cfi_module_remove(mod, module_addr_min); |
---|
4219 | 4557 | #endif |
---|
4220 | 4558 | } |
---|
4221 | 4559 | |
---|
.. | .. |
---|
4326 | 4664 | return err; |
---|
4327 | 4665 | } |
---|
4328 | 4666 | |
---|
4329 | | -static const struct file_operations proc_modules_operations = { |
---|
4330 | | - .open = modules_open, |
---|
4331 | | - .read = seq_read, |
---|
4332 | | - .llseek = seq_lseek, |
---|
4333 | | - .release = seq_release, |
---|
| 4667 | +static const struct proc_ops modules_proc_ops = { |
---|
| 4668 | + .proc_flags = PROC_ENTRY_PERMANENT, |
---|
| 4669 | + .proc_open = modules_open, |
---|
| 4670 | + .proc_read = seq_read, |
---|
| 4671 | + .proc_lseek = seq_lseek, |
---|
| 4672 | + .proc_release = seq_release, |
---|
4334 | 4673 | }; |
---|
4335 | 4674 | |
---|
4336 | 4675 | static int __init proc_modules_init(void) |
---|
4337 | 4676 | { |
---|
4338 | | - proc_create("modules", 0, NULL, &proc_modules_operations); |
---|
| 4677 | + proc_create("modules", 0, NULL, &modules_proc_ops); |
---|
4339 | 4678 | return 0; |
---|
4340 | 4679 | } |
---|
4341 | 4680 | module_init(proc_modules_init); |
---|
.. | .. |
---|
4469 | 4808 | pr_cont("\n"); |
---|
4470 | 4809 | } |
---|
4471 | 4810 | |
---|
| 4811 | +#ifdef CONFIG_ANDROID_DEBUG_SYMBOLS |
---|
| 4812 | +void android_debug_for_each_module(int (*fn)(const char *mod_name, void *mod_addr, void *data), |
---|
| 4813 | + void *data) |
---|
| 4814 | +{ |
---|
| 4815 | + struct module *module; |
---|
| 4816 | + |
---|
| 4817 | + preempt_disable(); |
---|
| 4818 | + list_for_each_entry_rcu(module, &modules, list) { |
---|
| 4819 | + if (fn(module->name, module->core_layout.base, data)) |
---|
| 4820 | + goto out; |
---|
| 4821 | + } |
---|
| 4822 | +out: |
---|
| 4823 | + preempt_enable(); |
---|
| 4824 | +} |
---|
| 4825 | +EXPORT_SYMBOL_GPL(android_debug_for_each_module); |
---|
| 4826 | +#endif |
---|
| 4827 | + |
---|
4472 | 4828 | #ifdef CONFIG_MODVERSIONS |
---|
4473 | 4829 | /* Generate the signature for all relevant module structures here. |
---|
4474 | 4830 | * If these change, we don't want to try to parse the module. */ |
---|