Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Module version support
0004  *
0005  * Copyright (C) 2008 Rusty Russell
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/string.h>
0010 #include <linux/printk.h>
0011 #include "internal.h"
0012 
0013 int check_version(const struct load_info *info,
0014           const char *symname,
0015              struct module *mod,
0016              const s32 *crc)
0017 {
0018     Elf_Shdr *sechdrs = info->sechdrs;
0019     unsigned int versindex = info->index.vers;
0020     unsigned int i, num_versions;
0021     struct modversion_info *versions;
0022 
0023     /* Exporting module didn't supply crcs?  OK, we're already tainted. */
0024     if (!crc)
0025         return 1;
0026 
0027     /* No versions at all?  modprobe --force does this. */
0028     if (versindex == 0)
0029         return try_to_force_load(mod, symname) == 0;
0030 
0031     versions = (void *)sechdrs[versindex].sh_addr;
0032     num_versions = sechdrs[versindex].sh_size
0033         / sizeof(struct modversion_info);
0034 
0035     for (i = 0; i < num_versions; i++) {
0036         u32 crcval;
0037 
0038         if (strcmp(versions[i].name, symname) != 0)
0039             continue;
0040 
0041         crcval = *crc;
0042         if (versions[i].crc == crcval)
0043             return 1;
0044         pr_debug("Found checksum %X vs module %lX\n",
0045              crcval, versions[i].crc);
0046         goto bad_version;
0047     }
0048 
0049     /* Broken toolchain. Warn once, then let it go.. */
0050     pr_warn_once("%s: no symbol version for %s\n", info->name, symname);
0051     return 1;
0052 
0053 bad_version:
0054     pr_warn("%s: disagrees about version of symbol %s\n", info->name, symname);
0055     return 0;
0056 }
0057 
0058 int check_modstruct_version(const struct load_info *info,
0059                 struct module *mod)
0060 {
0061     struct find_symbol_arg fsa = {
0062         .name   = "module_layout",
0063         .gplok  = true,
0064     };
0065 
0066     /*
0067      * Since this should be found in kernel (which can't be removed), no
0068      * locking is necessary -- use preempt_disable() to placate lockdep.
0069      */
0070     preempt_disable();
0071     if (!find_symbol(&fsa)) {
0072         preempt_enable();
0073         BUG();
0074     }
0075     preempt_enable();
0076     return check_version(info, "module_layout", mod, fsa.crc);
0077 }
0078 
0079 /* First part is kernel version, which we ignore if module has crcs. */
0080 int same_magic(const char *amagic, const char *bmagic,
0081            bool has_crcs)
0082 {
0083     if (has_crcs) {
0084         amagic += strcspn(amagic, " ");
0085         bmagic += strcspn(bmagic, " ");
0086     }
0087     return strcmp(amagic, bmagic) == 0;
0088 }
0089 
0090 /*
0091  * Generate the signature for all relevant module structures here.
0092  * If these change, we don't want to try to parse the module.
0093  */
0094 void module_layout(struct module *mod,
0095            struct modversion_info *ver,
0096            struct kernel_param *kp,
0097            struct kernel_symbol *ks,
0098            struct tracepoint * const *tp)
0099 {
0100 }
0101 EXPORT_SYMBOL(module_layout);