diff options
| author | Rusty Russell <rusty@rustcorp.com.au> | 2003-02-14 10:16:23 -0600 |
|---|---|---|
| committer | Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de> | 2003-02-14 10:16:23 -0600 |
| commit | ccada2dfe81978d16bf226386111ef8a72ecdd7b (patch) | |
| tree | d74403b4384e10572253009e7b27d248e2bc3c99 | |
| parent | 1cc0e0529569bf6a94f6d49770aa6d4b599d2c46 (diff) | |
kbuild: Do modversions checks on module structure
Checks the module structure itself when CONFIG_MODVERSIONS is set.
| -rw-r--r-- | kernel/module.c | 31 | ||||
| -rw-r--r-- | scripts/modpost.c | 13 |
2 files changed, 44 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 diff --git a/scripts/modpost.c b/scripts/modpost.c index 5b21b7a27353..6da8241ce7a6 100644 --- a/scripts/modpost.c +++ b/scripts/modpost.c @@ -308,6 +308,7 @@ read_symbols(char *modname) const char *symname; struct module *mod; struct elf_info info = { }; + struct symbol *s; Elf_Sym *sym; /* When there's no vmlinux, don't print warnings about @@ -326,6 +327,17 @@ read_symbols(char *modname) handle_moddevtable(mod, &info, sym, symname); } parse_elf_finish(&info); + + /* Our trick to get versioning for struct_module - it's + * never passed as an argument to an exported function, so + * the automatic versioning doesn't pick it up, but it's really + * important anyhow */ + if (modversions) { + s = alloc_symbol("struct_module"); + /* add to list */ + s->next = mod->unres; + mod->unres = s; + } } #define SZ 500 @@ -502,6 +514,7 @@ main(int argc, char **argv) { struct module *mod; struct buffer buf = { }; + struct symbol *s; char fname[SZ]; for (; argv[1]; argv++) { |
