Commit ccada2df authored by Rusty Russell's avatar Rusty Russell Committed by Kai Germaschewski

kbuild: Do modversions checks on module structure

Checks the module structure itself when CONFIG_MODVERSIONS is set.
parent 1cc0e052
...@@ -771,6 +771,18 @@ static int check_version(Elf_Shdr *sechdrs, ...@@ -771,6 +771,18 @@ static int check_version(Elf_Shdr *sechdrs,
return 1; 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. */ /* First part is kernel version, which we ignore. */
static inline int same_magic(const char *amagic, const char *bmagic) static inline int same_magic(const char *amagic, const char *bmagic)
{ {
...@@ -789,6 +801,13 @@ static inline int check_version(Elf_Shdr *sechdrs, ...@@ -789,6 +801,13 @@ static inline int check_version(Elf_Shdr *sechdrs,
return 1; 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) static inline int same_magic(const char *amagic, const char *bmagic)
{ {
return strcmp(amagic, bmagic) == 0; return strcmp(amagic, bmagic) == 0;
...@@ -1185,6 +1204,12 @@ static struct module *load_module(void *umod, ...@@ -1185,6 +1204,12 @@ static struct module *load_module(void *umod,
} }
mod = (void *)sechdrs[modindex].sh_addr; 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. */ /* This is allowed: modprobe --force will invalidate it. */
if (!vmagindex) { if (!vmagindex) {
tainted |= TAINT_FORCED_MODULE; tainted |= TAINT_FORCED_MODULE;
...@@ -1630,3 +1655,9 @@ static int __init symbols_init(void) ...@@ -1630,3 +1655,9 @@ static int __init symbols_init(void)
} }
__initcall(symbols_init); __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
...@@ -308,6 +308,7 @@ read_symbols(char *modname) ...@@ -308,6 +308,7 @@ read_symbols(char *modname)
const char *symname; const char *symname;
struct module *mod; struct module *mod;
struct elf_info info = { }; struct elf_info info = { };
struct symbol *s;
Elf_Sym *sym; Elf_Sym *sym;
/* When there's no vmlinux, don't print warnings about /* When there's no vmlinux, don't print warnings about
...@@ -326,6 +327,17 @@ read_symbols(char *modname) ...@@ -326,6 +327,17 @@ read_symbols(char *modname)
handle_moddevtable(mod, &info, sym, symname); handle_moddevtable(mod, &info, sym, symname);
} }
parse_elf_finish(&info); 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 #define SZ 500
...@@ -502,6 +514,7 @@ main(int argc, char **argv) ...@@ -502,6 +514,7 @@ main(int argc, char **argv)
{ {
struct module *mod; struct module *mod;
struct buffer buf = { }; struct buffer buf = { };
struct symbol *s;
char fname[SZ]; char fname[SZ];
for (; argv[1]; argv++) { for (; argv[1]; argv++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment