Re: modprobe -f / --force-vermagic not working correctly

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Nov 19, 2012 at 12:08 PM, Lucas De Marchi
<lucas.demarchi@xxxxxxxxxxxxxx> wrote:
> 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) {


I pushed two separate patches to fix the issue with "modprobe -f".

One is this patch above. The other to fix the removal of modversions.


Please take a look in git head:
http://git.kernel.org/?p=utils/kernel/kmod/kmod.git;a=commit;h=a4578669ca25ef6ede96bf4262821bcb07c8065c

I'll roll out a new release soon, probably by the end of this week.


Regards,
Lucas De Marchi
--
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


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux