Hi,

Having to do something "evil"  like loading a module with a different version 
magic than the kernel fails
with modprobe -f or --force-vermagic

I tracked the problem down to kmod only clearing the vermagic string. This 
results in the kernel comparing
an empty string to the kernel's own vermagic string. Which fails.

As you can see from kernel/module.c a module will only load if no vermagic is 
found. And in get_modinfo
the string vermagic is found and the contents of the part behind the '=' used 
to check if there is a vermagic 
or not.

static int check_modinfo(struct module *mod, struct load_info *info)
{
        const char *modmagic = get_modinfo(info, "vermagic");
        int err;

        /* This is allowed: modprobe --force will invalidate it. */
        if (!modmagic) {
                err = try_to_force_load(mod, "bad vermagic");
                if (err)
                        return err;
.....

static char *get_modinfo(struct load_info *info, const char *tag)
{
        char *p;
        unsigned int taglen = strlen(tag);
        Elf_Shdr *infosec = &info->sechdrs[info->index.info];
        unsigned long size = infosec->sh_size;

        for (p = (char *)infosec->sh_addr; p; p = next_string(p, &size)) {
                if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
                        return p + taglen + 1;
        }
        return NULL;
}

Kmod with -f or --force-vermagic only clears the string. Thus it is still found 
by the kernel and the comparison is tried.
The problem was solved with the following lazy patch, which not only makes a 
zero'd string but also mangles the vermagic keyword, 
confirming the theory. However I think there must be a better solution, just 
cannot think of it now as it is time for me to go to sleep.

>From 77b46192198d1f2516f9b7c0dac4ffbbe6841922 Mon Sep 17 00:00:00 2001
From: Philippe De Swert <[email protected]>
Date: Fri, 16 Nov 2012 01:33:52 +0200
Subject: [PATCH] Mangle vermagic string so kernel cannot find it, so modprobe
 -f / --force-vermagic works

Signed-off-by: Philippe De Swert <[email protected]>
---
 libkmod/libkmod-elf.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libkmod/libkmod-elf.c b/libkmod/libkmod-elf.c
index 38e83c1..1c4e2f0 100644
--- a/libkmod/libkmod-elf.c
+++ b/libkmod/libkmod-elf.c
@@ -626,7 +626,7 @@ int kmod_elf_strip_vermagic(struct kmod_elf *elf)
                len = strlen(s);
                ELFDBG(elf, "clear .modinfo vermagic \"%s\" (%zd bytes)\n",
                       s, len);
-               memset(elf->changed + off, '\0', len);
+               memset(elf->changed + off -2 , '\0', len + 2);
                return 0;
        }

-- 
1.7.10.4

Regards,

Philippe--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to