Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'modversions' (modversions fixes for powerpc from Ard)

Merge kcrctab entry fixes from Ard Biesheuvel:
"This is a followup to [0] 'modversions: redefine kcrctab entries as
relative CRC pointers', but since relative CRC pointers do not work in
modules, and are actually only needed by powerpc with
CONFIG_RELOCATABLE=y, I have made it a Kconfig selectable feature
instead.

First it introduces the MODULE_REL_CRCS Kconfig symbol, and adds the
kbuild handling of it, i.e., modpost, genksyms and kallsyms.

Then it switches all architectures to 32-bit CRC entries in kcrctab,
where all architectures except powerpc with CONFIG_RELOCATABLE=y use
absolute ELF symbol references as before"

[0] http://marc.info/?l=linux-arch&m=148493613415294&w=2

* emailed patches from Ard Biesheuvel:
module: unify absolute krctab definitions for 32-bit and 64-bit
modversions: treat symbol CRCs as 32 bit quantities
kbuild: modversions: add infrastructure for emitting relative CRCs

+93 -62
+1
arch/powerpc/Kconfig
··· 484 484 bool "Build a relocatable kernel" 485 485 depends on (PPC64 && !COMPILE_TEST) || (FLATMEM && (44x || FSL_BOOKE)) 486 486 select NONSTATIC_KERNEL 487 + select MODULE_REL_CRCS if MODVERSIONS 487 488 help 488 489 This builds a kernel image that is capable of running at the 489 490 location the kernel is loaded at. For ppc32, there is no any
-4
arch/powerpc/include/asm/module.h
··· 90 90 } 91 91 #endif 92 92 93 - #if defined(CONFIG_MODVERSIONS) && defined(CONFIG_PPC64) 94 - #define ARCH_RELOCATES_KCRCTAB 95 - #define reloc_start PHYSICAL_START 96 - #endif 97 93 #endif /* __KERNEL__ */ 98 94 #endif /* _ASM_POWERPC_MODULE_H */
-8
arch/powerpc/kernel/module_64.c
··· 286 286 for (end = (void *)vers + size; vers < end; vers++) 287 287 if (vers->name[0] == '.') { 288 288 memmove(vers->name, vers->name+1, strlen(vers->name)); 289 - #ifdef ARCH_RELOCATES_KCRCTAB 290 - /* The TOC symbol has no CRC computed. To avoid CRC 291 - * check failing, we must force it to the expected 292 - * value (see CRC check in module.c). 293 - */ 294 - if (!strcmp(vers->name, "TOC.")) 295 - vers->crc = -(unsigned long)reloc_start; 296 - #endif 297 289 } 298 290 } 299 291
+6 -5
include/asm-generic/export.h
··· 9 9 #ifndef KSYM_ALIGN 10 10 #define KSYM_ALIGN 8 11 11 #endif 12 - #ifndef KCRC_ALIGN 13 - #define KCRC_ALIGN 8 14 - #endif 15 12 #else 16 13 #define __put .long 17 14 #ifndef KSYM_ALIGN 18 15 #define KSYM_ALIGN 4 19 16 #endif 17 + #endif 20 18 #ifndef KCRC_ALIGN 21 19 #define KCRC_ALIGN 4 22 - #endif 23 20 #endif 24 21 25 22 #ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX ··· 49 52 .section ___kcrctab\sec+\name,"a" 50 53 .balign KCRC_ALIGN 51 54 KSYM(__kcrctab_\name): 52 - __put KSYM(__crc_\name) 55 + #if defined(CONFIG_MODULE_REL_CRCS) 56 + .long KSYM(__crc_\name) - . 57 + #else 58 + .long KSYM(__crc_\name) 59 + #endif 53 60 .weak KSYM(__crc_\name) 54 61 .previous 55 62 #endif
+12 -5
include/linux/export.h
··· 43 43 #ifdef CONFIG_MODVERSIONS 44 44 /* Mark the CRC weak since genksyms apparently decides not to 45 45 * generate a checksums for some symbols */ 46 + #if defined(CONFIG_MODULE_REL_CRCS) 46 47 #define __CRC_SYMBOL(sym, sec) \ 47 - extern __visible void *__crc_##sym __attribute__((weak)); \ 48 - static const unsigned long __kcrctab_##sym \ 49 - __used \ 50 - __attribute__((section("___kcrctab" sec "+" #sym), used)) \ 51 - = (unsigned long) &__crc_##sym; 48 + asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ 49 + " .weak " VMLINUX_SYMBOL_STR(__crc_##sym) " \n" \ 50 + " .long " VMLINUX_SYMBOL_STR(__crc_##sym) " - . \n" \ 51 + " .previous \n"); 52 + #else 53 + #define __CRC_SYMBOL(sym, sec) \ 54 + asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ 55 + " .weak " VMLINUX_SYMBOL_STR(__crc_##sym) " \n" \ 56 + " .long " VMLINUX_SYMBOL_STR(__crc_##sym) " \n" \ 57 + " .previous \n"); 58 + #endif 52 59 #else 53 60 #define __CRC_SYMBOL(sym, sec) 54 61 #endif
+7 -7
include/linux/module.h
··· 346 346 347 347 /* Exported symbols */ 348 348 const struct kernel_symbol *syms; 349 - const unsigned long *crcs; 349 + const s32 *crcs; 350 350 unsigned int num_syms; 351 351 352 352 /* Kernel parameters. */ ··· 359 359 /* GPL-only exported symbols. */ 360 360 unsigned int num_gpl_syms; 361 361 const struct kernel_symbol *gpl_syms; 362 - const unsigned long *gpl_crcs; 362 + const s32 *gpl_crcs; 363 363 364 364 #ifdef CONFIG_UNUSED_SYMBOLS 365 365 /* unused exported symbols. */ 366 366 const struct kernel_symbol *unused_syms; 367 - const unsigned long *unused_crcs; 367 + const s32 *unused_crcs; 368 368 unsigned int num_unused_syms; 369 369 370 370 /* GPL-only, unused exported symbols. */ 371 371 unsigned int num_unused_gpl_syms; 372 372 const struct kernel_symbol *unused_gpl_syms; 373 - const unsigned long *unused_gpl_crcs; 373 + const s32 *unused_gpl_crcs; 374 374 #endif 375 375 376 376 #ifdef CONFIG_MODULE_SIG ··· 382 382 383 383 /* symbols that will be GPL-only in the near future. */ 384 384 const struct kernel_symbol *gpl_future_syms; 385 - const unsigned long *gpl_future_crcs; 385 + const s32 *gpl_future_crcs; 386 386 unsigned int num_gpl_future_syms; 387 387 388 388 /* Exception table */ ··· 523 523 524 524 struct symsearch { 525 525 const struct kernel_symbol *start, *stop; 526 - const unsigned long *crcs; 526 + const s32 *crcs; 527 527 enum { 528 528 NOT_GPL_ONLY, 529 529 GPL_ONLY, ··· 539 539 */ 540 540 const struct kernel_symbol *find_symbol(const char *name, 541 541 struct module **owner, 542 - const unsigned long **crc, 542 + const s32 **crc, 543 543 bool gplok, 544 544 bool warn); 545 545
+4
init/Kconfig
··· 1987 1987 make them incompatible with the kernel you are running. If 1988 1988 unsure, say N. 1989 1989 1990 + config MODULE_REL_CRCS 1991 + bool 1992 + depends on MODVERSIONS 1993 + 1990 1994 config MODULE_SRCVERSION_ALL 1991 1995 bool "Source checksum for all modules" 1992 1996 help
+25 -28
kernel/module.c
··· 389 389 extern const struct kernel_symbol __stop___ksymtab_gpl[]; 390 390 extern const struct kernel_symbol __start___ksymtab_gpl_future[]; 391 391 extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; 392 - extern const unsigned long __start___kcrctab[]; 393 - extern const unsigned long __start___kcrctab_gpl[]; 394 - extern const unsigned long __start___kcrctab_gpl_future[]; 392 + extern const s32 __start___kcrctab[]; 393 + extern const s32 __start___kcrctab_gpl[]; 394 + extern const s32 __start___kcrctab_gpl_future[]; 395 395 #ifdef CONFIG_UNUSED_SYMBOLS 396 396 extern const struct kernel_symbol __start___ksymtab_unused[]; 397 397 extern const struct kernel_symbol __stop___ksymtab_unused[]; 398 398 extern const struct kernel_symbol __start___ksymtab_unused_gpl[]; 399 399 extern const struct kernel_symbol __stop___ksymtab_unused_gpl[]; 400 - extern const unsigned long __start___kcrctab_unused[]; 401 - extern const unsigned long __start___kcrctab_unused_gpl[]; 400 + extern const s32 __start___kcrctab_unused[]; 401 + extern const s32 __start___kcrctab_unused_gpl[]; 402 402 #endif 403 403 404 404 #ifndef CONFIG_MODVERSIONS ··· 497 497 498 498 /* Output */ 499 499 struct module *owner; 500 - const unsigned long *crc; 500 + const s32 *crc; 501 501 const struct kernel_symbol *sym; 502 502 }; 503 503 ··· 563 563 * (optional) module which owns it. Needs preempt disabled or module_mutex. */ 564 564 const struct kernel_symbol *find_symbol(const char *name, 565 565 struct module **owner, 566 - const unsigned long **crc, 566 + const s32 **crc, 567 567 bool gplok, 568 568 bool warn) 569 569 { ··· 1249 1249 } 1250 1250 1251 1251 #ifdef CONFIG_MODVERSIONS 1252 - /* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */ 1253 - static unsigned long maybe_relocated(unsigned long crc, 1254 - const struct module *crc_owner) 1252 + 1253 + static u32 resolve_rel_crc(const s32 *crc) 1255 1254 { 1256 - #ifdef ARCH_RELOCATES_KCRCTAB 1257 - if (crc_owner == NULL) 1258 - return crc - (unsigned long)reloc_start; 1259 - #endif 1260 - return crc; 1255 + return *(u32 *)((void *)crc + *crc); 1261 1256 } 1262 1257 1263 1258 static int check_version(Elf_Shdr *sechdrs, 1264 1259 unsigned int versindex, 1265 1260 const char *symname, 1266 1261 struct module *mod, 1267 - const unsigned long *crc, 1268 - const struct module *crc_owner) 1262 + const s32 *crc) 1269 1263 { 1270 1264 unsigned int i, num_versions; 1271 1265 struct modversion_info *versions; ··· 1277 1283 / sizeof(struct modversion_info); 1278 1284 1279 1285 for (i = 0; i < num_versions; i++) { 1286 + u32 crcval; 1287 + 1280 1288 if (strcmp(versions[i].name, symname) != 0) 1281 1289 continue; 1282 1290 1283 - if (versions[i].crc == maybe_relocated(*crc, crc_owner)) 1291 + if (IS_ENABLED(CONFIG_MODULE_REL_CRCS)) 1292 + crcval = resolve_rel_crc(crc); 1293 + else 1294 + crcval = *crc; 1295 + if (versions[i].crc == crcval) 1284 1296 return 1; 1285 - pr_debug("Found checksum %lX vs module %lX\n", 1286 - maybe_relocated(*crc, crc_owner), versions[i].crc); 1297 + pr_debug("Found checksum %X vs module %lX\n", 1298 + crcval, versions[i].crc); 1287 1299 goto bad_version; 1288 1300 } 1289 1301 ··· 1307 1307 unsigned int versindex, 1308 1308 struct module *mod) 1309 1309 { 1310 - const unsigned long *crc; 1310 + const s32 *crc; 1311 1311 1312 1312 /* 1313 1313 * Since this should be found in kernel (which can't be removed), no ··· 1321 1321 } 1322 1322 preempt_enable(); 1323 1323 return check_version(sechdrs, versindex, 1324 - VMLINUX_SYMBOL_STR(module_layout), mod, crc, 1325 - NULL); 1324 + VMLINUX_SYMBOL_STR(module_layout), mod, crc); 1326 1325 } 1327 1326 1328 1327 /* First part is kernel version, which we ignore if module has crcs. */ ··· 1339 1340 unsigned int versindex, 1340 1341 const char *symname, 1341 1342 struct module *mod, 1342 - const unsigned long *crc, 1343 - const struct module *crc_owner) 1343 + const s32 *crc) 1344 1344 { 1345 1345 return 1; 1346 1346 } ··· 1366 1368 { 1367 1369 struct module *owner; 1368 1370 const struct kernel_symbol *sym; 1369 - const unsigned long *crc; 1371 + const s32 *crc; 1370 1372 int err; 1371 1373 1372 1374 /* ··· 1381 1383 if (!sym) 1382 1384 goto unlock; 1383 1385 1384 - if (!check_version(info->sechdrs, info->index.vers, name, mod, crc, 1385 - owner)) { 1386 + if (!check_version(info->sechdrs, info->index.vers, name, mod, crc)) { 1386 1387 sym = ERR_PTR(-EINVAL); 1387 1388 goto getname; 1388 1389 }
+2
scripts/Makefile.build
··· 164 164 $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ 165 165 $(GENKSYMS) $(if $(1), -T $(2)) \ 166 166 $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \ 167 + $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \ 167 168 $(if $(KBUILD_PRESERVE),-p) \ 168 169 -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) 169 170 ··· 338 337 $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \ 339 338 $(GENKSYMS) $(if $(1), -T $(2)) \ 340 339 $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \ 340 + $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \ 341 341 $(if $(KBUILD_PRESERVE),-p) \ 342 342 -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) 343 343
+14 -5
scripts/genksyms/genksyms.c
··· 44 44 int in_source_file; 45 45 46 46 static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, 47 - flag_preserve, flag_warnings; 47 + flag_preserve, flag_warnings, flag_rel_crcs; 48 48 static const char *mod_prefix = ""; 49 49 50 50 static int errors; ··· 693 693 fputs(">\n", debugfile); 694 694 695 695 /* Used as a linker script. */ 696 - printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); 696 + printf(!flag_rel_crcs ? "%s__crc_%s = 0x%08lx;\n" : 697 + "SECTIONS { .rodata : ALIGN(4) { " 698 + "%s__crc_%s = .; LONG(0x%08lx); } }\n", 699 + mod_prefix, name, crc); 697 700 } 698 701 } 699 702 ··· 733 730 734 731 static void genksyms_usage(void) 735 732 { 736 - fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" 733 + fputs("Usage:\n" "genksyms [-adDTwqhVR] > /path/to/.tmp_obj.ver\n" "\n" 737 734 #ifdef __GNU_LIBRARY__ 738 735 " -s, --symbol-prefix Select symbol prefix\n" 739 736 " -d, --debug Increment the debug level (repeatable)\n" ··· 745 742 " -q, --quiet Disable warnings (default)\n" 746 743 " -h, --help Print this message\n" 747 744 " -V, --version Print the release version\n" 745 + " -R, --relative-crc Emit section relative symbol CRCs\n" 748 746 #else /* __GNU_LIBRARY__ */ 749 747 " -s Select symbol prefix\n" 750 748 " -d Increment the debug level (repeatable)\n" ··· 757 753 " -q Disable warnings (default)\n" 758 754 " -h Print this message\n" 759 755 " -V Print the release version\n" 756 + " -R Emit section relative symbol CRCs\n" 760 757 #endif /* __GNU_LIBRARY__ */ 761 758 , stderr); 762 759 } ··· 779 774 {"preserve", 0, 0, 'p'}, 780 775 {"version", 0, 0, 'V'}, 781 776 {"help", 0, 0, 'h'}, 777 + {"relative-crc", 0, 0, 'R'}, 782 778 {0, 0, 0, 0} 783 779 }; 784 780 785 - while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph", 781 + while ((o = getopt_long(argc, argv, "s:dwqVDr:T:phR", 786 782 &long_opts[0], NULL)) != EOF) 787 783 #else /* __GNU_LIBRARY__ */ 788 - while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF) 784 + while ((o = getopt(argc, argv, "s:dwqVDr:T:phR")) != EOF) 789 785 #endif /* __GNU_LIBRARY__ */ 790 786 switch (o) { 791 787 case 's': ··· 829 823 case 'h': 830 824 genksyms_usage(); 831 825 return 0; 826 + case 'R': 827 + flag_rel_crcs = 1; 828 + break; 832 829 default: 833 830 genksyms_usage(); 834 831 return 1;
+12
scripts/kallsyms.c
··· 219 219 "_SDA2_BASE_", /* ppc */ 220 220 NULL }; 221 221 222 + static char *special_prefixes[] = { 223 + "__crc_", /* modversions */ 224 + NULL }; 225 + 222 226 static char *special_suffixes[] = { 223 227 "_veneer", /* arm */ 224 228 "_from_arm", /* arm */ ··· 262 258 for (i = 0; special_symbols[i]; i++) 263 259 if (strcmp(sym_name, special_symbols[i]) == 0) 264 260 return 0; 261 + 262 + for (i = 0; special_prefixes[i]; i++) { 263 + int l = strlen(special_prefixes[i]); 264 + 265 + if (l <= strlen(sym_name) && 266 + strncmp(sym_name, special_prefixes[i], l) == 0) 267 + return 0; 268 + } 265 269 266 270 for (i = 0; special_suffixes[i]; i++) { 267 271 int l = strlen(sym_name) - strlen(special_suffixes[i]);
+10
scripts/mod/modpost.c
··· 621 621 if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { 622 622 is_crc = true; 623 623 crc = (unsigned int) sym->st_value; 624 + if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS) { 625 + unsigned int *crcp; 626 + 627 + /* symbol points to the CRC in the ELF object */ 628 + crcp = (void *)info->hdr + sym->st_value + 629 + info->sechdrs[sym->st_shndx].sh_offset - 630 + (info->hdr->e_type != ET_REL ? 631 + info->sechdrs[sym->st_shndx].sh_addr : 0); 632 + crc = *crcp; 633 + } 624 634 sym_update_crc(symname + strlen(CRC_PFX), mod, crc, 625 635 export); 626 636 }