aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Robinson <andr345@gmail.com>2009-05-14 14:07:37 +0200
committerAndreas Robinson <andr345@gmail.com>2009-05-15 15:01:32 +0200
commit7ffd0170469019b8feafd82b02f7902f9602142c (patch)
tree6bea5627239fe8e00f92f8441e2a3a3f77b036f4
parent39e63afd9d179b03b84f27eb9cfe8d6dd7c2ba7f (diff)
downloadmodule-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.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/modprobe.c b/modprobe.c
index c0680a7..1cbbeff 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -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: