module: don't ignore vermagic string if module doesn't have modversions

Linus found a logic bug: we ignore the version number in a module's
vermagic string if we have CONFIG_MODVERSIONS set, but modversions
also lets through a module with no __versions section for modprobe
--force (with tainting, but still).

We should only ignore the start of the vermagic string if the module
actually *has* crcs to check.  Rather than (say) having an
entertaining hissy fit and creating a config option to work around the
buggy code.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Rusty Russell 2008-05-09 16:25:28 +10:00 committed by Linus Torvalds
parent a5dd697074
commit 91e37a793b
2 changed files with 13 additions and 9 deletions

View file

@ -845,9 +845,9 @@ config MODULE_FORCE_LOAD
depends on MODULES depends on MODULES
default n default n
help help
This option allows loading of modules even if that would set the Allow loading of modules without version information (ie. modprobe
'F' (forced) taint, due to lack of version info. Which is --force). Forced module loading sets the 'F' (forced) taint flag and
usually a really bad idea. is usually a really bad idea.
config MODULE_UNLOAD config MODULE_UNLOAD
bool "Module unloading" bool "Module unloading"

View file

@ -957,11 +957,14 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
return check_version(sechdrs, versindex, "struct_module", mod, crc); return check_version(sechdrs, versindex, "struct_module", mod, crc);
} }
/* First part is kernel version, which we ignore. */ /* First part is kernel version, which we ignore if module has crcs. */
static inline int same_magic(const char *amagic, const char *bmagic) static inline int same_magic(const char *amagic, const char *bmagic,
bool has_crcs)
{ {
amagic += strcspn(amagic, " "); if (has_crcs) {
bmagic += strcspn(bmagic, " "); amagic += strcspn(amagic, " ");
bmagic += strcspn(bmagic, " ");
}
return strcmp(amagic, bmagic) == 0; return strcmp(amagic, bmagic) == 0;
} }
#else #else
@ -981,7 +984,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
return 1; return 1;
} }
static inline int same_magic(const char *amagic, const char *bmagic) static inline int same_magic(const char *amagic, const char *bmagic,
bool has_crcs)
{ {
return strcmp(amagic, bmagic) == 0; return strcmp(amagic, bmagic) == 0;
} }
@ -1874,7 +1878,7 @@ static struct module *load_module(void __user *umod,
err = try_to_force_load(mod, "magic"); err = try_to_force_load(mod, "magic");
if (err) if (err)
goto free_hdr; goto free_hdr;
} else if (!same_magic(modmagic, vermagic)) { } else if (!same_magic(modmagic, vermagic, versindex)) {
printk(KERN_ERR "%s: version magic '%s' should be '%s'\n", printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
mod->name, modmagic, vermagic); mod->name, modmagic, vermagic);
err = -ENOEXEC; err = -ENOEXEC;