aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c65
1 files changed, 44 insertions, 21 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 8674a390a2e8..f5e9491ef7ac 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -890,6 +890,19 @@ static struct module_attribute *modinfo_attrs[] = {
890 890
891static const char vermagic[] = VERMAGIC_STRING; 891static const char vermagic[] = VERMAGIC_STRING;
892 892
893static int try_to_force_load(struct module *mod, const char *symname)
894{
895#ifdef CONFIG_MODULE_FORCE_LOAD
896 if (!(tainted & TAINT_FORCED_MODULE))
897 printk("%s: no version for \"%s\" found: kernel tainted.\n",
898 mod->name, symname);
899 add_taint_module(mod, TAINT_FORCED_MODULE);
900 return 0;
901#else
902 return -ENOEXEC;
903#endif
904}
905
893#ifdef CONFIG_MODVERSIONS 906#ifdef CONFIG_MODVERSIONS
894static int check_version(Elf_Shdr *sechdrs, 907static int check_version(Elf_Shdr *sechdrs,
895 unsigned int versindex, 908 unsigned int versindex,
@@ -904,6 +917,10 @@ static int check_version(Elf_Shdr *sechdrs,
904 if (!crc) 917 if (!crc)
905 return 1; 918 return 1;
906 919
920 /* No versions at all? modprobe --force does this. */
921 if (versindex == 0)
922 return try_to_force_load(mod, symname) == 0;
923
907 versions = (void *) sechdrs[versindex].sh_addr; 924 versions = (void *) sechdrs[versindex].sh_addr;
908 num_versions = sechdrs[versindex].sh_size 925 num_versions = sechdrs[versindex].sh_size
909 / sizeof(struct modversion_info); 926 / sizeof(struct modversion_info);
@@ -914,18 +931,19 @@ static int check_version(Elf_Shdr *sechdrs,
914 931
915 if (versions[i].crc == *crc) 932 if (versions[i].crc == *crc)
916 return 1; 933 return 1;
917 printk("%s: disagrees about version of symbol %s\n",
918 mod->name, symname);
919 DEBUGP("Found checksum %lX vs module %lX\n", 934 DEBUGP("Found checksum %lX vs module %lX\n",
920 *crc, versions[i].crc); 935 *crc, versions[i].crc);
921 return 0; 936 goto bad_version;
922 } 937 }
923 /* Not in module's version table. OK, but that taints the kernel. */ 938
924 if (!(tainted & TAINT_FORCED_MODULE)) 939 printk(KERN_WARNING "%s: no symbol version for %s\n",
925 printk("%s: no version for \"%s\" found: kernel tainted.\n", 940 mod->name, symname);
926 mod->name, symname); 941 return 0;
927 add_taint_module(mod, TAINT_FORCED_MODULE); 942
928 return 1; 943bad_version:
944 printk("%s: disagrees about version of symbol %s\n",
945 mod->name, symname);
946 return 0;
929} 947}
930 948
931static inline int check_modstruct_version(Elf_Shdr *sechdrs, 949static inline int check_modstruct_version(Elf_Shdr *sechdrs,
@@ -939,11 +957,14 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
939 return check_version(sechdrs, versindex, "struct_module", mod, crc); 957 return check_version(sechdrs, versindex, "struct_module", mod, crc);
940} 958}
941 959
942/* First part is kernel version, which we ignore. */ 960/* First part is kernel version, which we ignore if module has crcs. */
943static inline int same_magic(const char *amagic, const char *bmagic) 961static inline int same_magic(const char *amagic, const char *bmagic,
962 bool has_crcs)
944{ 963{
945 amagic += strcspn(amagic, " "); 964 if (has_crcs) {
946 bmagic += strcspn(bmagic, " "); 965 amagic += strcspn(amagic, " ");
966 bmagic += strcspn(bmagic, " ");
967 }
947 return strcmp(amagic, bmagic) == 0; 968 return strcmp(amagic, bmagic) == 0;
948} 969}
949#else 970#else
@@ -963,7 +984,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
963 return 1; 984 return 1;
964} 985}
965 986
966static inline int same_magic(const char *amagic, const char *bmagic) 987static inline int same_magic(const char *amagic, const char *bmagic,
988 bool has_crcs)
967{ 989{
968 return strcmp(amagic, bmagic) == 0; 990 return strcmp(amagic, bmagic) == 0;
969} 991}
@@ -1853,10 +1875,10 @@ static struct module *load_module(void __user *umod,
1853 modmagic = get_modinfo(sechdrs, infoindex, "vermagic"); 1875 modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
1854 /* This is allowed: modprobe --force will invalidate it. */ 1876 /* This is allowed: modprobe --force will invalidate it. */
1855 if (!modmagic) { 1877 if (!modmagic) {
1856 add_taint_module(mod, TAINT_FORCED_MODULE); 1878 err = try_to_force_load(mod, "magic");
1857 printk(KERN_WARNING "%s: no version magic, tainting kernel.\n", 1879 if (err)
1858 mod->name); 1880 goto free_hdr;
1859 } else if (!same_magic(modmagic, vermagic)) { 1881 } else if (!same_magic(modmagic, vermagic, versindex)) {
1860 printk(KERN_ERR "%s: version magic '%s' should be '%s'\n", 1882 printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
1861 mod->name, modmagic, vermagic); 1883 mod->name, modmagic, vermagic);
1862 err = -ENOEXEC; 1884 err = -ENOEXEC;
@@ -2006,9 +2028,10 @@ static struct module *load_module(void __user *umod,
2006 (mod->num_gpl_future_syms && !gplfuturecrcindex) || 2028 (mod->num_gpl_future_syms && !gplfuturecrcindex) ||
2007 (mod->num_unused_syms && !unusedcrcindex) || 2029 (mod->num_unused_syms && !unusedcrcindex) ||
2008 (mod->num_unused_gpl_syms && !unusedgplcrcindex)) { 2030 (mod->num_unused_gpl_syms && !unusedgplcrcindex)) {
2009 printk(KERN_WARNING "%s: No versions for exported symbols." 2031 printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name);
2010 " Tainting kernel.\n", mod->name); 2032 err = try_to_force_load(mod, "nocrc");
2011 add_taint_module(mod, TAINT_FORCED_MODULE); 2033 if (err)
2034 goto cleanup;
2012 } 2035 }
2013#endif 2036#endif
2014 markersindex = find_sec(hdr, sechdrs, secstrings, "__markers"); 2037 markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");