File Index
Files and directories
Sign in
FILE

version.c

File preview with syntax highlighting.

linux-6.19.14/kernel/module/version.c C
  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 u32 *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	struct modversion_info_ext version_ext;
 23
 24	/* Exporting module didn't supply crcs?  OK, we're already tainted. */
 25	if (!crc)
 26		return 1;
 27
 28	/* If we have extended version info, rely on it */
 29	if (info->index.vers_ext_crc) {
 30		for_each_modversion_info_ext(version_ext, info) {
 31			if (strcmp(version_ext.name, symname) != 0)
 32				continue;
 33			if (*version_ext.crc == *crc)
 34				return 1;
 35			pr_debug("Found checksum %X vs module %X\n",
 36				 *crc, *version_ext.crc);
 37			goto bad_version;
 38		}
 39		pr_warn_once("%s: no extended symbol version for %s\n",
 40			     info->name, symname);
 41		return 1;
 42	}
 43
 44	/* No versions at all?  modprobe --force does this. */
 45	if (versindex == 0)
 46		return try_to_force_load(mod, symname) == 0;
 47
 48	versions = (void *)sechdrs[versindex].sh_addr;
 49	num_versions = sechdrs[versindex].sh_size
 50		/ sizeof(struct modversion_info);
 51
 52	for (i = 0; i < num_versions; i++) {
 53		u32 crcval;
 54
 55		if (strcmp(versions[i].name, symname) != 0)
 56			continue;
 57
 58		crcval = *crc;
 59		if (versions[i].crc == crcval)
 60			return 1;
 61		pr_debug("Found checksum %X vs module %lX\n",
 62			 crcval, versions[i].crc);
 63		goto bad_version;
 64	}
 65
 66	/* Broken toolchain. Warn once, then let it go.. */
 67	pr_warn_once("%s: no symbol version for %s\n", info->name, symname);
 68	return 1;
 69
 70bad_version:
 71	pr_warn("%s: disagrees about version of symbol %s\n", info->name, symname);
 72	return 0;
 73}
 74
 75int check_modstruct_version(const struct load_info *info,
 76			    struct module *mod)
 77{
 78	struct find_symbol_arg fsa = {
 79		.name	= "module_layout",
 80		.gplok	= true,
 81	};
 82	bool have_symbol;
 83
 84	/*
 85	 * Since this should be found in kernel (which can't be removed), no
 86	 * locking is necessary. Regardless use a RCU read section to keep
 87	 * lockdep happy.
 88	 */
 89	scoped_guard(rcu)
 90		have_symbol = find_symbol(&fsa);
 91	BUG_ON(!have_symbol);
 92
 93	return check_version(info, "module_layout", mod, fsa.crc);
 94}
 95
 96/* First part is kernel version, which we ignore if module has crcs. */
 97int same_magic(const char *amagic, const char *bmagic,
 98	       bool has_crcs)
 99{
100	if (has_crcs) {
101		amagic += strcspn(amagic, " ");
102		bmagic += strcspn(bmagic, " ");
103	}
104	return strcmp(amagic, bmagic) == 0;
105}
106
107void modversion_ext_start(const struct load_info *info,
108			  struct modversion_info_ext *start)
109{
110	unsigned int crc_idx = info->index.vers_ext_crc;
111	unsigned int name_idx = info->index.vers_ext_name;
112	Elf_Shdr *sechdrs = info->sechdrs;
113
114	/*
115	 * Both of these fields are needed for this to be useful
116	 * Any future fields should be initialized to NULL if absent.
117	 */
118	if (crc_idx == 0 || name_idx == 0) {
119		start->remaining = 0;
120		return;
121	}
122
123	start->crc = (const u32 *)sechdrs[crc_idx].sh_addr;
124	start->name = (const char *)sechdrs[name_idx].sh_addr;
125	start->remaining = sechdrs[crc_idx].sh_size / sizeof(*start->crc);
126}
127
128void modversion_ext_advance(struct modversion_info_ext *vers)
129{
130	vers->remaining--;
131	vers->crc++;
132	vers->name += strlen(vers->name) + 1;
133}
134
135/*
136 * Generate the signature for all relevant module structures here.
137 * If these change, we don't want to try to parse the module.
138 */
139void module_layout(struct module *mod,
140		   struct modversion_info *ver,
141		   struct kernel_param *kp,
142		   struct kernel_symbol *ks,
143		   struct tracepoint * const *tp)
144{
145}
146EXPORT_SYMBOL(module_layout);
~/ Read-only file preview.