summaryrefslogtreecommitdiff
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 3e36848e0702..00d8b07c4fd1 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -771,6 +771,18 @@ static int check_version(Elf_Shdr *sechdrs,
return 1;
}
+static inline int check_modstruct_version(Elf_Shdr *sechdrs,
+ unsigned int versindex,
+ struct module *mod)
+{
+ unsigned int i;
+ struct kernel_symbol_group *ksg;
+
+ if (!__find_symbol("struct_module", &ksg, &i, 1))
+ BUG();
+ return check_version(sechdrs, versindex, "struct_module", mod, ksg, i);
+}
+
/* First part is kernel version, which we ignore. */
static inline int same_magic(const char *amagic, const char *bmagic)
{
@@ -789,6 +801,13 @@ static inline int check_version(Elf_Shdr *sechdrs,
return 1;
}
+static inline int check_modstruct_version(Elf_Shdr *sechdrs,
+ unsigned int versindex,
+ struct module *mod)
+{
+ return 1;
+}
+
static inline int same_magic(const char *amagic, const char *bmagic)
{
return strcmp(amagic, bmagic) == 0;
@@ -1185,6 +1204,12 @@ static struct module *load_module(void *umod,
}
mod = (void *)sechdrs[modindex].sh_addr;
+ /* Check module struct version now, before we try to use module. */
+ if (!check_modstruct_version(sechdrs, versindex, mod)) {
+ err = -ENOEXEC;
+ goto free_hdr;
+ }
+
/* This is allowed: modprobe --force will invalidate it. */
if (!vmagindex) {
tainted |= TAINT_FORCED_MODULE;
@@ -1630,3 +1655,9 @@ static int __init symbols_init(void)
}
__initcall(symbols_init);
+
+#ifdef CONFIG_MODVERSIONS
+/* Generate the signature for struct module here, too, for modversions. */
+void struct_module(struct module *mod) { return; }
+EXPORT_SYMBOL(struct_module);
+#endif