1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Module version support 4 * 5 * Copyright (C) 2008 Rusty Russell 6 */ 7 8 #include <linux/module.h> 9 #include <linux/string.h> 10 #include <linux/printk.h> 11 #include "internal.h" 12 13 static u32 resolve_rel_crc(const s32 *crc) 14 { 15 return *(u32 *)((void *)crc + *crc); 16 } 17 18 int check_version(const struct load_info *info, 19 const char *symname, 20 struct module *mod, 21 const s32 *crc) 22 { 23 Elf_Shdr *sechdrs = info->sechdrs; 24 unsigned int versindex = info->index.vers; 25 unsigned int i, num_versions; 26 struct modversion_info *versions; 27 28 /* Exporting module didn't supply crcs? OK, we're already tainted. */ 29 if (!crc) 30 return 1; 31 32 /* No versions at all? modprobe --force does this. */ 33 if (versindex == 0) 34 return try_to_force_load(mod, symname) == 0; 35 36 versions = (void *)sechdrs[versindex].sh_addr; 37 num_versions = sechdrs[versindex].sh_size 38 / sizeof(struct modversion_info); 39 40 for (i = 0; i < num_versions; i++) { 41 u32 crcval; 42 43 if (strcmp(versions[i].name, symname) != 0) 44 continue; 45 46 if (IS_ENABLED(CONFIG_MODULE_REL_CRCS)) 47 crcval = resolve_rel_crc(crc); 48 else 49 crcval = *crc; 50 if (versions[i].crc == crcval) 51 return 1; 52 pr_debug("Found checksum %X vs module %lX\n", 53 crcval, versions[i].crc); 54 goto bad_version; 55 } 56 57 /* Broken toolchain. Warn once, then let it go.. */ 58 pr_warn_once("%s: no symbol version for %s\n", info->name, symname); 59 return 1; 60 61 bad_version: 62 pr_warn("%s: disagrees about version of symbol %s\n", info->name, symname); 63 return 0; 64 } 65 66 int check_modstruct_version(const struct load_info *info, 67 struct module *mod) 68 { 69 struct find_symbol_arg fsa = { 70 .name = "module_layout", 71 .gplok = true, 72 }; 73 74 /* 75 * Since this should be found in kernel (which can't be removed), no 76 * locking is necessary -- use preempt_disable() to placate lockdep. 77 */ 78 preempt_disable(); 79 if (!find_symbol(&fsa)) { 80 preempt_enable(); 81 BUG(); 82 } 83 preempt_enable(); 84 return check_version(info, "module_layout", mod, fsa.crc); 85 } 86 87 /* First part is kernel version, which we ignore if module has crcs. */ 88 int same_magic(const char *amagic, const char *bmagic, 89 bool has_crcs) 90 { 91 if (has_crcs) { 92 amagic += strcspn(amagic, " "); 93 bmagic += strcspn(bmagic, " "); 94 } 95 return strcmp(amagic, bmagic) == 0; 96 } 97 98 /* 99 * Generate the signature for all relevant module structures here. 100 * If these change, we don't want to try to parse the module. 101 */ 102 void module_layout(struct module *mod, 103 struct modversion_info *ver, 104 struct kernel_param *kp, 105 struct kernel_symbol *ks, 106 struct tracepoint * const *tp) 107 { 108 } 109 EXPORT_SYMBOL(module_layout); 110