mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
ef98f9cfe2
As promised, for v5.19 I queued up quite a bit of work for modules, but still with a pretty conservative eye. These changes have been soaking on modules-next (and so linux-next) for quite some time, the code shift was merged onto modules-next on March 22, and the last patch was queued on May 5th. The following are the highlights of what bells and whistles we will get for v5.19: 1) It was time to tidy up kernel/module.c and one way of starting with that effort was to split it up into files. At my request Aaron Tomlin spearheaded that effort with the goal to not introduce any functional at all during that endeavour. The penalty for the split is +1322 bytes total, +112 bytes in data, +1210 bytes in text while bss is unchanged. One of the benefits of this other than helping make the code easier to read and review is summoning more help on review for changes with livepatching so kernel/module/livepatch.c is now pegged as maintained by the live patching folks. The before and after with just the move on a defconfig on x86-64: $ size kernel/module.o text data bss dec hex filename 38434 4540 104 43078 a846 kernel/module.o $ size -t kernel/module/*.o text data bss dec hex filename 4785 120 0 4905 1329 kernel/module/kallsyms.o 28577 4416 104 33097 8149 kernel/module/main.o 1158 8 0 1166 48e kernel/module/procfs.o 902 108 0 1010 3f2 kernel/module/strict_rwx.o 3390 0 0 3390 d3e kernel/module/sysfs.o 832 0 0 832 340 kernel/module/tree_lookup.o 39644 4652 104 44400 ad70 (TOTALS) 2) Aaron added module unload taint tracking (MODULE_UNLOAD_TAINT_TRACKING), so to enable tracking unloaded modules which did taint the kernel. 3) Christophe Leroy added CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC which lets architectures to request having modules data in vmalloc area instead of module area. There are three reasons why an architecture might want this: a) On some architectures (like book3s/32) it is not possible to protect against execution on a page basis. The exec stuff can be mapped by different arch segment sizes (on book3s/32 that is 256M segments). By default the module area is in an Exec segment while vmalloc area is in a NoExec segment. Using vmalloc lets you muck with module data as NoExec on those architectures whereas before you could not. b) By pushing more module data to vmalloc you also increase the probability of module text to remain within a closer distance from kernel core text and this reduces trampolines, this has been reported on arm first and powerpc folks are following that lead. c) Free'ing module_alloc() (Exec by default) area leaves this exposed as Exec by default, some architectures have some security enhancements to set this as NoExec on free, and splitting module data with text let's future generic special allocators be added to the kernel without having developers try to grok the tribal knowledge per arch. Work like Rick Edgecombe's permission vmalloc interface [0] becomes easier to address over time. [0] https://lore.kernel.org/lkml/20201120202426.18009-1-rick.p.edgecombe@intel.com/#r 4) Masahiro Yamada's symbol search enhancements -----BEGIN PGP SIGNATURE----- iQJGBAABCgAwFiEENnNq2KuOejlQLZofziMdCjCSiKcFAmKOnHkSHG1jZ3JvZkBr ZXJuZWwub3JnAAoJEM4jHQowkoinFw4P/1ADdvfj+b6wbAxou6tPa2ZKnx/ImEnE 0T1P/n2guWg+2Q8oYjqifTpadGzr8td4c/PaGb5UpfdEOdBIyIGklrVZpQ+xkqfT X4KIvqsf4ajL24OKxOSNtvL8RXEIDUhJ4Veq6BImBk8CPrPjsUBlNyAIlvV0aom2 BsFROQ2pMTSCiFY47gkMKLBlBny1l7zktoF0lhWTzHimw8VSDbTJFlu+fZvspd0o lCqiHTkpiBSJDSEEjqk0lT6wIb27fvdzjmjy+Ur71bBKiPIEPiL5XNUufkGe6oB3 mnTOPow+wPTQc0dtkTpCHQYXE/a70Sbkwp1JfkbSYeHzJLlFru/tkmKiwN0RUo9l 0mY7VPEKuQWmxsOkLqvwcPBGx5JOSWOJKrbgpFmH+RLgeEgEa8t7uQDURK2KeIj8 P7ZzN5M2klKIHHA4vjfekYOJAb1Tii9Ibp7iGeiYxf93mPJBqwvRwbtBXBZpB4ce FoDrxwEq812KPW7P2O1kgOvq7Fn1KWh0wVeKc8iBGxFxJhzOQY86H1ZRWDLAxRss Rr1PMLt2TbTLUBt7MzR4vrg0NoQvpLYyf2jGFjWyZDRHU8nLeHkOlQot3xRDAtq9 Bpx5mSlM9BGfPibd1Kw4BaxBha5vVCQ+AcleT+NWnCjw4I0wLoFi9RLUSyItn9No tlHLgdrM2a54 =cxtr -----END PGP SIGNATURE----- Merge tag 'modules-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux Pull modules updates from Luis Chamberlain: - It was time to tidy up kernel/module.c and one way of starting with that effort was to split it up into files. At my request Aaron Tomlin spearheaded that effort with the goal to not introduce any functional at all during that endeavour. The penalty for the split is +1322 bytes total, +112 bytes in data, +1210 bytes in text while bss is unchanged. One of the benefits of this other than helping make the code easier to read and review is summoning more help on review for changes with livepatching so kernel/module/livepatch.c is now pegged as maintained by the live patching folks. The before and after with just the move on a defconfig on x86-64: $ size kernel/module.o text data bss dec hex filename 38434 4540 104 43078 a846 kernel/module.o $ size -t kernel/module/*.o text data bss dec hex filename 4785 120 0 4905 1329 kernel/module/kallsyms.o 28577 4416 104 33097 8149 kernel/module/main.o 1158 8 0 1166 48e kernel/module/procfs.o 902 108 0 1010 3f2 kernel/module/strict_rwx.o 3390 0 0 3390 d3e kernel/module/sysfs.o 832 0 0 832 340 kernel/module/tree_lookup.o 39644 4652 104 44400 ad70 (TOTALS) - Aaron added module unload taint tracking (MODULE_UNLOAD_TAINT_TRACKING), to enable tracking unloaded modules which did taint the kernel. - Christophe Leroy added CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC which lets architectures to request having modules data in vmalloc area instead of module area. There are three reasons why an architecture might want this: a) On some architectures (like book3s/32) it is not possible to protect against execution on a page basis. The exec stuff can be mapped by different arch segment sizes (on book3s/32 that is 256M segments). By default the module area is in an Exec segment while vmalloc area is in a NoExec segment. Using vmalloc lets you muck with module data as NoExec on those architectures whereas before you could not. b) By pushing more module data to vmalloc you also increase the probability of module text to remain within a closer distance from kernel core text and this reduces trampolines, this has been reported on arm first and powerpc folks are following that lead. c) Free'ing module_alloc() (Exec by default) area leaves this exposed as Exec by default, some architectures have some security enhancements to set this as NoExec on free, and splitting module data with text let's future generic special allocators be added to the kernel without having developers try to grok the tribal knowledge per arch. Work like Rick Edgecombe's permission vmalloc interface [0] becomes easier to address over time. [0] https://lore.kernel.org/lkml/20201120202426.18009-1-rick.p.edgecombe@intel.com/#r - Masahiro Yamada's symbol search enhancements * tag 'modules-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux: (33 commits) module: merge check_exported_symbol() into find_exported_symbol_in_section() module: do not binary-search in __ksymtab_gpl if fsa->gplok is false module: do not pass opaque pointer for symbol search module: show disallowed symbol name for inherit_taint() module: fix [e_shstrndx].sh_size=0 OOB access module: Introduce module unload taint tracking module: Move module_assert_mutex_or_preempt() to internal.h module: Make module_flags_taint() accept a module's taints bitmap and usable outside core code module.h: simplify MODULE_IMPORT_NS powerpc: Select ARCH_WANTS_MODULES_DATA_IN_VMALLOC on book3s/32 and 8xx module: Remove module_addr_min and module_addr_max module: Add CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC module: Introduce data_layout module: Prepare for handling several RB trees module: Always have struct mod_tree_root module: Rename debug_align() as strict_align() module: Rework layout alignment to avoid BUG_ON()s module: Move module_enable_x() and frob_text() in strict_rwx.c module: Make module_enable_x() independent of CONFIG_ARCH_HAS_STRICT_MODULE_RWX module: Move version support into a separate file ...
102 lines
2.4 KiB
C
102 lines
2.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Module version support
|
|
*
|
|
* Copyright (C) 2008 Rusty Russell
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/string.h>
|
|
#include <linux/printk.h>
|
|
#include "internal.h"
|
|
|
|
int check_version(const struct load_info *info,
|
|
const char *symname,
|
|
struct module *mod,
|
|
const s32 *crc)
|
|
{
|
|
Elf_Shdr *sechdrs = info->sechdrs;
|
|
unsigned int versindex = info->index.vers;
|
|
unsigned int i, num_versions;
|
|
struct modversion_info *versions;
|
|
|
|
/* Exporting module didn't supply crcs? OK, we're already tainted. */
|
|
if (!crc)
|
|
return 1;
|
|
|
|
/* No versions at all? modprobe --force does this. */
|
|
if (versindex == 0)
|
|
return try_to_force_load(mod, symname) == 0;
|
|
|
|
versions = (void *)sechdrs[versindex].sh_addr;
|
|
num_versions = sechdrs[versindex].sh_size
|
|
/ sizeof(struct modversion_info);
|
|
|
|
for (i = 0; i < num_versions; i++) {
|
|
u32 crcval;
|
|
|
|
if (strcmp(versions[i].name, symname) != 0)
|
|
continue;
|
|
|
|
crcval = *crc;
|
|
if (versions[i].crc == crcval)
|
|
return 1;
|
|
pr_debug("Found checksum %X vs module %lX\n",
|
|
crcval, versions[i].crc);
|
|
goto bad_version;
|
|
}
|
|
|
|
/* Broken toolchain. Warn once, then let it go.. */
|
|
pr_warn_once("%s: no symbol version for %s\n", info->name, symname);
|
|
return 1;
|
|
|
|
bad_version:
|
|
pr_warn("%s: disagrees about version of symbol %s\n", info->name, symname);
|
|
return 0;
|
|
}
|
|
|
|
int check_modstruct_version(const struct load_info *info,
|
|
struct module *mod)
|
|
{
|
|
struct find_symbol_arg fsa = {
|
|
.name = "module_layout",
|
|
.gplok = true,
|
|
};
|
|
|
|
/*
|
|
* Since this should be found in kernel (which can't be removed), no
|
|
* locking is necessary -- use preempt_disable() to placate lockdep.
|
|
*/
|
|
preempt_disable();
|
|
if (!find_symbol(&fsa)) {
|
|
preempt_enable();
|
|
BUG();
|
|
}
|
|
preempt_enable();
|
|
return check_version(info, "module_layout", mod, fsa.crc);
|
|
}
|
|
|
|
/* First part is kernel version, which we ignore if module has crcs. */
|
|
int same_magic(const char *amagic, const char *bmagic,
|
|
bool has_crcs)
|
|
{
|
|
if (has_crcs) {
|
|
amagic += strcspn(amagic, " ");
|
|
bmagic += strcspn(bmagic, " ");
|
|
}
|
|
return strcmp(amagic, bmagic) == 0;
|
|
}
|
|
|
|
/*
|
|
* Generate the signature for all relevant module structures here.
|
|
* If these change, we don't want to try to parse the module.
|
|
*/
|
|
void module_layout(struct module *mod,
|
|
struct modversion_info *ver,
|
|
struct kernel_param *kp,
|
|
struct kernel_symbol *ks,
|
|
struct tracepoint * const *tp)
|
|
{
|
|
}
|
|
EXPORT_SYMBOL(module_layout);
|