aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 12afc5a3ddd3..f82386bd9ee9 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -880,11 +880,23 @@ static int try_to_force_load(struct module *mod, const char *reason)
880} 880}
881 881
882#ifdef CONFIG_MODVERSIONS 882#ifdef CONFIG_MODVERSIONS
883/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */
884static unsigned long maybe_relocated(unsigned long crc,
885 const struct module *crc_owner)
886{
887#ifdef ARCH_RELOCATES_KCRCTAB
888 if (crc_owner == NULL)
889 return crc - (unsigned long)reloc_start;
890#endif
891 return crc;
892}
893
883static int check_version(Elf_Shdr *sechdrs, 894static int check_version(Elf_Shdr *sechdrs,
884 unsigned int versindex, 895 unsigned int versindex,
885 const char *symname, 896 const char *symname,
886 struct module *mod, 897 struct module *mod,
887 const unsigned long *crc) 898 const unsigned long *crc,
899 const struct module *crc_owner)
888{ 900{
889 unsigned int i, num_versions; 901 unsigned int i, num_versions;
890 struct modversion_info *versions; 902 struct modversion_info *versions;
@@ -905,10 +917,10 @@ static int check_version(Elf_Shdr *sechdrs,
905 if (strcmp(versions[i].name, symname) != 0) 917 if (strcmp(versions[i].name, symname) != 0)
906 continue; 918 continue;
907 919
908 if (versions[i].crc == *crc) 920 if (versions[i].crc == maybe_relocated(*crc, crc_owner))
909 return 1; 921 return 1;
910 DEBUGP("Found checksum %lX vs module %lX\n", 922 DEBUGP("Found checksum %lX vs module %lX\n",
911 *crc, versions[i].crc); 923 maybe_relocated(*crc, crc_owner), versions[i].crc);
912 goto bad_version; 924 goto bad_version;
913 } 925 }
914 926
@@ -931,7 +943,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
931 if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, 943 if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL,
932 &crc, true, false)) 944 &crc, true, false))
933 BUG(); 945 BUG();
934 return check_version(sechdrs, versindex, "module_layout", mod, crc); 946 return check_version(sechdrs, versindex, "module_layout", mod, crc,
947 NULL);
935} 948}
936 949
937/* First part is kernel version, which we ignore if module has crcs. */ 950/* First part is kernel version, which we ignore if module has crcs. */
@@ -949,7 +962,8 @@ static inline int check_version(Elf_Shdr *sechdrs,
949 unsigned int versindex, 962 unsigned int versindex,
950 const char *symname, 963 const char *symname,
951 struct module *mod, 964 struct module *mod,
952 const unsigned long *crc) 965 const unsigned long *crc,
966 const struct module *crc_owner)
953{ 967{
954 return 1; 968 return 1;
955} 969}
@@ -984,8 +998,8 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
984 /* use_module can fail due to OOM, 998 /* use_module can fail due to OOM,
985 or module initialization or unloading */ 999 or module initialization or unloading */
986 if (sym) { 1000 if (sym) {
987 if (!check_version(sechdrs, versindex, name, mod, crc) || 1001 if (!check_version(sechdrs, versindex, name, mod, crc, owner)
988 !use_module(mod, owner)) 1002 || !use_module(mod, owner))
989 sym = NULL; 1003 sym = NULL;
990 } 1004 }
991 return sym; 1005 return sym;
@@ -996,6 +1010,12 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
996 * J. Corbet <corbet@lwn.net> 1010 * J. Corbet <corbet@lwn.net>
997 */ 1011 */
998#if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS) 1012#if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS)
1013
1014static inline bool sect_empty(const Elf_Shdr *sect)
1015{
1016 return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0;
1017}
1018
999struct module_sect_attr 1019struct module_sect_attr
1000{ 1020{
1001 struct module_attribute mattr; 1021 struct module_attribute mattr;
@@ -1037,8 +1057,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
1037 1057
1038 /* Count loaded sections and allocate structures */ 1058 /* Count loaded sections and allocate structures */
1039 for (i = 0; i < nsect; i++) 1059 for (i = 0; i < nsect; i++)
1040 if (sechdrs[i].sh_flags & SHF_ALLOC 1060 if (!sect_empty(&sechdrs[i]))
1041 && sechdrs[i].sh_size)
1042 nloaded++; 1061 nloaded++;
1043 size[0] = ALIGN(sizeof(*sect_attrs) 1062 size[0] = ALIGN(sizeof(*sect_attrs)
1044 + nloaded * sizeof(sect_attrs->attrs[0]), 1063 + nloaded * sizeof(sect_attrs->attrs[0]),
@@ -1056,9 +1075,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
1056 sattr = &sect_attrs->attrs[0]; 1075 sattr = &sect_attrs->attrs[0];
1057 gattr = &sect_attrs->grp.attrs[0]; 1076 gattr = &sect_attrs->grp.attrs[0];
1058 for (i = 0; i < nsect; i++) { 1077 for (i = 0; i < nsect; i++) {
1059 if (! (sechdrs[i].sh_flags & SHF_ALLOC)) 1078 if (sect_empty(&sechdrs[i]))
1060 continue;
1061 if (!sechdrs[i].sh_size)
1062 continue; 1079 continue;
1063 sattr->address = sechdrs[i].sh_addr; 1080 sattr->address = sechdrs[i].sh_addr;
1064 sattr->name = kstrdup(secstrings + sechdrs[i].sh_name, 1081 sattr->name = kstrdup(secstrings + sechdrs[i].sh_name,
@@ -1142,7 +1159,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
1142 /* Count notes sections and allocate structures. */ 1159 /* Count notes sections and allocate structures. */
1143 notes = 0; 1160 notes = 0;
1144 for (i = 0; i < nsect; i++) 1161 for (i = 0; i < nsect; i++)
1145 if ((sechdrs[i].sh_flags & SHF_ALLOC) && 1162 if (!sect_empty(&sechdrs[i]) &&
1146 (sechdrs[i].sh_type == SHT_NOTE)) 1163 (sechdrs[i].sh_type == SHT_NOTE))
1147 ++notes; 1164 ++notes;
1148 1165
@@ -1158,7 +1175,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
1158 notes_attrs->notes = notes; 1175 notes_attrs->notes = notes;
1159 nattr = &notes_attrs->attrs[0]; 1176 nattr = &notes_attrs->attrs[0];
1160 for (loaded = i = 0; i < nsect; ++i) { 1177 for (loaded = i = 0; i < nsect; ++i) {
1161 if (!(sechdrs[i].sh_flags & SHF_ALLOC)) 1178 if (sect_empty(&sechdrs[i]))
1162 continue; 1179 continue;
1163 if (sechdrs[i].sh_type == SHT_NOTE) { 1180 if (sechdrs[i].sh_type == SHT_NOTE) {
1164 nattr->attr.name = mod->sect_attrs->attrs[loaded].name; 1181 nattr->attr.name = mod->sect_attrs->attrs[loaded].name;
@@ -1896,9 +1913,7 @@ static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
1896 unsigned int i; 1913 unsigned int i;
1897 1914
1898 /* only scan the sections containing data */ 1915 /* only scan the sections containing data */
1899 kmemleak_scan_area(mod->module_core, (unsigned long)mod - 1916 kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL);
1900 (unsigned long)mod->module_core,
1901 sizeof(struct module), GFP_KERNEL);
1902 1917
1903 for (i = 1; i < hdr->e_shnum; i++) { 1918 for (i = 1; i < hdr->e_shnum; i++) {
1904 if (!(sechdrs[i].sh_flags & SHF_ALLOC)) 1919 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
@@ -1907,8 +1922,7 @@ static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
1907 && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0) 1922 && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0)
1908 continue; 1923 continue;
1909 1924
1910 kmemleak_scan_area(mod->module_core, sechdrs[i].sh_addr - 1925 kmemleak_scan_area((void *)sechdrs[i].sh_addr,
1911 (unsigned long)mod->module_core,
1912 sechdrs[i].sh_size, GFP_KERNEL); 1926 sechdrs[i].sh_size, GFP_KERNEL);
1913 } 1927 }
1914} 1928}
@@ -2236,6 +2250,12 @@ static noinline struct module *load_module(void __user *umod,
2236 "_ftrace_events", 2250 "_ftrace_events",
2237 sizeof(*mod->trace_events), 2251 sizeof(*mod->trace_events),
2238 &mod->num_trace_events); 2252 &mod->num_trace_events);
2253 /*
2254 * This section contains pointers to allocated objects in the trace
2255 * code and not scanning it leads to false positives.
2256 */
2257 kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) *
2258 mod->num_trace_events, GFP_KERNEL);
2239#endif 2259#endif
2240#ifdef CONFIG_FTRACE_MCOUNT_RECORD 2260#ifdef CONFIG_FTRACE_MCOUNT_RECORD
2241 /* sechdrs[0].sh_size is always zero */ 2261 /* sechdrs[0].sh_size is always zero */