Hi Philippe, Sorry for the long time to reply On Thu, Nov 15, 2012 at 9:41 PM, Philippe De Swert <philippe.deswert@xxxxxxxxxxxxxxx> wrote: > 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. Indeed, we are only removing the value, not the entire key-value pair, which is wrong. > 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 <philippe.deswert@xxxxxxxxxxxxxxx> > 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 <philippe.deswert@xxxxxxxxxxxxxxx> > --- > 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); Humn... mangling the key is not the right thing to do. We could just remove the entire key-value pair. kernel as well as other tools will happily ignore '\0' between the strings. See the diff below (whitespace damaged). Does it work for you? Regards, Lucas De Marchi ------>8----- diff --git a/libkmod/libkmod-elf.c b/libkmod/libkmod-elf.c index 38e83c1..9d3f05f 100644 --- a/libkmod/libkmod-elf.c +++ b/libkmod/libkmod-elf.c @@ -611,7 +611,7 @@ int kmod_elf_strip_vermagic(struct kmod_elf *elf) i += strlen(s); continue; } - s += len; + off = (const uint8_t *)s - elf->memory; if (elf->changed == NULL) { -- 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