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,
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
......@@ -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++) {
......
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