diff options
author | Andreas Robinson <andr345@gmail.com> | 2009-05-14 14:07:37 +0200 |
---|---|---|
committer | Andreas Robinson <andr345@gmail.com> | 2009-05-15 15:01:32 +0200 |
commit | 7ffd0170469019b8feafd82b02f7902f9602142c (patch) | |
tree | 6bea5627239fe8e00f92f8441e2a3a3f77b036f4 | |
parent | 39e63afd9d179b03b84f27eb9cfe8d6dd7c2ba7f (diff) | |
download | module-init-tools-7ffd0170469019b8feafd82b02f7902f9602142c.tar.gz |
modprobe: load modules with grab_elf_file_fd()
In the old implementation, the loader didn't care about whether
a file is an ELF-file or not, and let init_module() sort it out.
In the new implementation, the loading fails with errno = ENOEXEC
if the file isn't an ELF-file.
However, the new logic does not pass the testing, specifically
test-modprobe/10alias.sh. To work around this, the commit adds a
hack that replicates the old way, when grab_elf_file_fd() does
return errno = ENOEXEC.
Obviously, this needs to be fixed. To replicate the problem,
simply remove the hack.
Signed-off-by: Andreas Robinson <andr345@gmail.com>
-rw-r--r-- | modprobe.c | 36 |
1 files changed, 24 insertions, 12 deletions
@@ -667,8 +667,7 @@ static int insmod(struct list_head *list, const char *cmdline_opts) { int ret, fd; - unsigned long len; - void *map; + struct elf_file *module; const char *command; struct module *mod = list_entry(list->next, struct module, list); int rc = 0; @@ -712,21 +711,33 @@ static int insmod(struct list_head *list, goto out_optstring; } - map = grab_fd(fd, &len); - if (!map) { + module = grab_elf_file_fd(mod->filename, fd); + if (!module) { + /* This is an ugly hack that maintains the logic where + * init_module() sets errno = ENOEXEC if the file is + * not an ELF object. + */ + if (errno == ENOEXEC) { + struct stat st; + optstring = add_extra_options(mod->modname, + optstring, options); + if (dry_run) + goto out; + fstat(fd, &st); + ret = init_module(NULL, st.st_size, optstring); + goto out_hack; + } + error("Could not read '%s': %s\n", mod->filename, strerror(errno)); goto out_unlock; } - - /* Rename it? */ if (newname) - rename_module(mod, map, len, newname); - + rename_module(mod, module->data, module->len, newname); if (strip_modversion) - strip_section(mod, map, len, "__versions"); + strip_section(mod, module->data, module->len, "__versions"); if (strip_vermagic) - clear_magic(mod, map, len); + clear_magic(mod, module->data, module->len); /* Config file might have given more options */ optstring = add_extra_options(mod->modname, optstring, options); @@ -736,7 +747,8 @@ static int insmod(struct list_head *list, if (dry_run) goto out; - ret = init_module(map, len, optstring); + ret = init_module(module->data, module->len, optstring); +out_hack: if (ret != 0) { if (errno == EEXIST) { if (first_time) @@ -753,7 +765,7 @@ static int insmod(struct list_head *list, rc = 1; } out: - release_file(map, len); + release_elf_file(module); out_unlock: close_file(fd); out_optstring: |