Ok. Not every object, but every object file which includes module.h.
I've only updated the x86 linker script, since the other archs'
compile will break as soon as they set CONFIG_MODULES=y (there are 40
linker scripts in the tree, and I don't want to patch them all again).
You now get:
ext2: version magic 'non-SMP,preempt,gcc-2.95' != kernel 'SMP,preempt,gcc-2.95'
Thanks!
Rusty.
-- Anyone who quotes me in their sig is an idiot. -- Rusty Russell.Name: Module Sanity Check Author: Rusty Russell Status: Tested on 2.5.56
D: Stores a section in each object, for SMP, PREEMPT and compiler D: version (spinlocks change size on UP with gcc major, at least). D: This was Linus' suggestion. Also printks on modules with common D: section (becoming an FAQ for third-party modules).
diff -urNp --exclude TAGS -X /home/rusty/current-dontdiff --minimal linux-2.5-bk/arch/i386/vmlinux.lds.S working-2.5-bk-sanityII/arch/i386/vmlinux.lds.S --- linux-2.5-bk/arch/i386/vmlinux.lds.S Mon Jan 13 16:56:21 2003 +++ working-2.5-bk-sanityII/arch/i386/vmlinux.lds.S Mon Jan 13 17:36:39 2003 @@ -39,6 +39,9 @@ SECTIONS __kallsyms : { *(__kallsyms) } __stop___kallsyms = .; + __vermagic = . ; /* Version magic to match against modules. */ + .gnu.linkonce.vermagic : { *(.gnu.linkonce.vermagic) } + /* writeable */ .data : { /* Data */ *(.data) diff -urNp --exclude TAGS -X /home/rusty/current-dontdiff --minimal linux-2.5-bk/include/linux/module.h working-2.5-bk-sanityII/include/linux/module.h --- linux-2.5-bk/include/linux/module.h Mon Jan 13 16:56:29 2003 +++ working-2.5-bk-sanityII/include/linux/module.h Mon Jan 13 17:27:41 2003 @@ -134,6 +134,25 @@ struct exception_table #ifdef CONFIG_MODULES +/* Simply sanity version stamp to place in each object. */ +#ifdef CONFIG_SMP +#define MODULE_VERMAGIC_SMP "SMP," +#else +#define MODULE_VERMAGIC_SMP "non-SMP," +#endif +#ifdef CONFIG_PREEMPT +#define MODULE_VERMAGIC_PREEMPT "preempt," +#else +#define MODULE_VERMAGIC_PREEMPT "non-preempt," +#endif +#ifndef MODULE_ARCH_VERMAGIC +#define MODULE_ARCH_VERMAGIC "" +#endif + +char __vermagic[] __attribute__((section(".gnu.linkonce.vermagic"))) = + MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT MODULE_ARCH_VERMAGIC + "gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__); + /* Get/put a kernel symbol (calls must be symmetric) */ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); diff -urNp --exclude TAGS -X /home/rusty/current-dontdiff --minimal linux-2.5-bk/kernel/module.c working-2.5-bk-sanityII/kernel/module.c --- linux-2.5-bk/kernel/module.c Mon Jan 13 16:56:30 2003 +++ working-2.5-bk-sanityII/kernel/module.c Mon Jan 13 17:43:59 2003 @@ -846,6 +846,8 @@ static int simplify_symbols(Elf_Shdr *se /* We compiled with -fno-common. These are not supposed to happen. */ DEBUGP("Common symbol: %s\n", strtab + sym[i].st_name); + printk("%s: probably not compiled with -fno-common\n", + mod->name); return -ENOEXEC; case SHN_ABS: @@ -976,6 +978,9 @@ static void set_license(struct module *m } } +/* Created bu the linker script */ +extern char __vermagic[]; + /* Allocate and load the module: note that size of section 0 is always zero, and we rely on this for optional sections. */ static struct module *load_module(void *umod, @@ -986,7 +991,7 @@ static struct module *load_module(void * Elf_Shdr *sechdrs; char *secstrings, *args; unsigned int i, symindex, exportindex, strindex, setupindex, exindex, - modindex, obsparmindex, licenseindex, gplindex; + modindex, obsparmindex, licenseindex, gplindex, vmagindex; long arglen; struct module *mod; long err = 0; @@ -1025,7 +1030,7 @@ static struct module *load_module(void * exportindex = setupindex = obsparmindex = gplindex = licenseindex = 0; /* And these should exist, but gcc whinges if we don't init them */ - symindex = strindex = exindex = modindex = 0; + symindex = strindex = exindex = modindex = vmagindex = 0; /* Find where important sections are */ for (i = 1; i < hdr->e_shnum; i++) { @@ -1075,6 +1080,11 @@ static struct module *load_module(void * /* EXPORT_SYMBOL_GPL() */ DEBUGP("GPL symbols found in section %u\n", i); gplindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, + ".gnu.linkonce.vermagic") == 0) { + /* Version magic. */ + DEBUGP("Version magic found in section %u\n", i); + vmagindex = i; } #ifdef CONFIG_KALLSYMS /* symbol and string tables for decoding later. */ @@ -1094,6 +1104,16 @@ static struct module *load_module(void * goto free_hdr; } mod = (void *)sechdrs[modindex].sh_addr; + + if (!vmagindex + || strcmp((char *)sechdrs[vmagindex].sh_addr, __vermagic) != 0) { + printk(KERN_WARNING "%s: version magic '%s' != kernel '%s'\n", + mod->name, + vmagindex ? (char*)sechdrs[vmagindex].sh_addr : "NONE", + __vermagic); + err = -ENOEXEC; + goto free_hdr; + } /* Now copy in args */ arglen = strlen_user(uargs); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/