module: Add module name to modinfo
Accessing the mod structure (e.g. for mod->name) prior to having completed check_modstruct_version() can result in writing garbage to the error logs if the layout of the mod structure loaded from disk doesn't match the running kernel's mod structure layout. This kind of mismatch will become much more likely if a kernel is built with different randomization seed for the struct layout randomization plugin. Instead, add and use a new modinfo string for logging the module name. Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Jessica Yu <jeyu@redhat.com>
This commit is contained in:
parent
4901942696
commit
3e2e857f9c
|
@ -302,6 +302,7 @@ int unregister_module_notifier(struct notifier_block *nb)
|
|||
EXPORT_SYMBOL(unregister_module_notifier);
|
||||
|
||||
struct load_info {
|
||||
char *name;
|
||||
Elf_Ehdr *hdr;
|
||||
unsigned long len;
|
||||
Elf_Shdr *sechdrs;
|
||||
|
@ -1318,12 +1319,12 @@ static int check_version(const struct load_info *info,
|
|||
}
|
||||
|
||||
/* Broken toolchain. Warn once, then let it go.. */
|
||||
pr_warn_once("%s: no symbol version for %s\n", mod->name, symname);
|
||||
pr_warn_once("%s: no symbol version for %s\n", info->name, symname);
|
||||
return 1;
|
||||
|
||||
bad_version:
|
||||
pr_warn("%s: disagrees about version of symbol %s\n",
|
||||
mod->name, symname);
|
||||
info->name, symname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2913,9 +2914,15 @@ static int rewrite_section_headers(struct load_info *info, int flags)
|
|||
info->index.vers = 0; /* Pretend no __versions section! */
|
||||
else
|
||||
info->index.vers = find_sec(info, "__versions");
|
||||
info->index.info = find_sec(info, ".modinfo");
|
||||
info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC;
|
||||
info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;
|
||||
|
||||
info->index.info = find_sec(info, ".modinfo");
|
||||
if (!info->index.info)
|
||||
info->name = "(missing .modinfo section)";
|
||||
else
|
||||
info->name = get_modinfo(info, "name");
|
||||
info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2955,14 +2962,22 @@ static struct module *setup_load_info(struct load_info *info, int flags)
|
|||
|
||||
info->index.mod = find_sec(info, ".gnu.linkonce.this_module");
|
||||
if (!info->index.mod) {
|
||||
pr_warn("No module found in object\n");
|
||||
pr_warn("%s: No module found in object\n",
|
||||
info->name ?: "(missing .modinfo name field)");
|
||||
return ERR_PTR(-ENOEXEC);
|
||||
}
|
||||
/* This is temporary: point mod into copy of data. */
|
||||
mod = (void *)info->sechdrs[info->index.mod].sh_addr;
|
||||
|
||||
/*
|
||||
* If we didn't load the .modinfo 'name' field, fall back to
|
||||
* on-disk struct mod 'name' field.
|
||||
*/
|
||||
if (!info->name)
|
||||
info->name = mod->name;
|
||||
|
||||
if (info->index.sym == 0) {
|
||||
pr_warn("%s: module has no symbols (stripped?)\n", mod->name);
|
||||
pr_warn("%s: module has no symbols (stripped?)\n", info->name);
|
||||
return ERR_PTR(-ENOEXEC);
|
||||
}
|
||||
|
||||
|
@ -2990,7 +3005,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
|
|||
return err;
|
||||
} else if (!same_magic(modmagic, vermagic, info->index.vers)) {
|
||||
pr_err("%s: version magic '%s' should be '%s'\n",
|
||||
mod->name, modmagic, vermagic);
|
||||
info->name, modmagic, vermagic);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
|
@ -3270,7 +3285,7 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
|
|||
if (IS_ERR(mod))
|
||||
return mod;
|
||||
|
||||
if (blacklisted(mod->name))
|
||||
if (blacklisted(info->name))
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
err = check_modinfo(mod, info, flags);
|
||||
|
|
|
@ -2126,6 +2126,7 @@ static void add_header(struct buffer *b, struct module *mod)
|
|||
buf_printf(b, "#include <linux/compiler.h>\n");
|
||||
buf_printf(b, "\n");
|
||||
buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
|
||||
buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
|
||||
buf_printf(b, "\n");
|
||||
buf_printf(b, "__visible struct module __this_module\n");
|
||||
buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
|
||||
|
|
Loading…
Reference in New Issue