cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

version.c (2449B)


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