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@xxxxxxxxx>
---
modprobe.c | 36 ++++++++++++++++++++++++------------
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:
--
1.6.0.4
--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Home]
[Linux USB Devel]
[Video for Linux]
[Linux Audio Users]
[Photo]
[Yosemite News]
[Yosemite Photos]
[Video Projectors]
[PDAs]
[Free Online Dating]
[Hacking TiVo]
[Linux Kernel]
[Linux SCSI]
[XFree86]
[Devices]
[Big List of Linux Books]
[16.7MP]