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 tag 's390-6.11-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes from Vasily Gorbik:

- Fix KASLR base offset to account for symbol offsets in the vmlinux
ELF file, preventing tool breakages like the drgn debugger

- Fix potential memory corruption of physmem_info during kernel
physical address randomization

- Fix potential memory corruption due to overlap between the relocated
lowcore and identity mapping by correctly reserving lowcore memory

- Fix performance regression and avoid randomizing identity mapping
base by default

- Fix unnecessary delay of AP bus binding complete uevent to prevent
startup lag in KVM guests using AP

* tag 's390-6.11-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/boot: Fix KASLR base offset off by __START_KERNEL bytes
s390/boot: Avoid possible physmem_info segment corruption
s390/ap: Refine AP bus bindings complete processing
s390/mm: Pin identity mapping base to zero
s390/mm: Prevent lowcore vs identity mapping overlap

+91 -34
+13
arch/s390/Kconfig
··· 604 604 as a security feature that deters exploit attempts relying on 605 605 knowledge of the location of kernel internals. 606 606 607 + config RANDOMIZE_IDENTITY_BASE 608 + bool "Randomize the address of the identity mapping base" 609 + depends on RANDOMIZE_BASE 610 + default DEBUG_VM 611 + help 612 + The identity mapping base address is pinned to zero by default. 613 + Allow randomization of that base to expose otherwise missed 614 + notion of physical and virtual addresses of data structures. 615 + That does not have any impact on the base address at which the 616 + kernel image is loaded. 617 + 618 + If unsure, say N 619 + 607 620 config KERNEL_IMAGE_BASE 608 621 hex "Kernel image base address" 609 622 range 0x100000 0x1FFFFFE0000000 if !KASAN
+32 -26
arch/s390/boot/startup.c
··· 162 162 loc = (long)*reloc + phys_offset; 163 163 if (loc < min_addr || loc > max_addr) 164 164 error("64-bit relocation outside of kernel!\n"); 165 - *(u64 *)loc += offset - __START_KERNEL; 165 + *(u64 *)loc += offset; 166 166 } 167 167 } 168 168 ··· 177 177 */ 178 178 for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++) { 179 179 if (*entry) 180 - *entry += offset - __START_KERNEL; 180 + *entry += offset; 181 181 } 182 182 } 183 183 ··· 252 252 vmemmap_size = SECTION_ALIGN_UP(pages) * sizeof(struct page); 253 253 254 254 /* choose kernel address space layout: 4 or 3 levels. */ 255 - BUILD_BUG_ON(!IS_ALIGNED(__START_KERNEL, THREAD_SIZE)); 255 + BUILD_BUG_ON(!IS_ALIGNED(TEXT_OFFSET, THREAD_SIZE)); 256 256 BUILD_BUG_ON(!IS_ALIGNED(__NO_KASLR_START_KERNEL, THREAD_SIZE)); 257 257 BUILD_BUG_ON(__NO_KASLR_END_KERNEL > _REGION1_SIZE); 258 258 vsize = get_vmem_size(ident_map_size, vmemmap_size, vmalloc_size, _REGION3_SIZE); ··· 341 341 BUILD_BUG_ON(MAX_DCSS_ADDR > (1UL << MAX_PHYSMEM_BITS)); 342 342 max_mappable = max(ident_map_size, MAX_DCSS_ADDR); 343 343 max_mappable = min(max_mappable, vmemmap_start); 344 - __identity_base = round_down(vmemmap_start - max_mappable, rte_size); 344 + if (IS_ENABLED(CONFIG_RANDOMIZE_IDENTITY_BASE)) 345 + __identity_base = round_down(vmemmap_start - max_mappable, rte_size); 345 346 346 347 return asce_limit; 347 348 } ··· 389 388 #endif 390 389 } 391 390 392 - static void fixup_vmlinux_info(void) 393 - { 394 - vmlinux.entry -= __START_KERNEL; 395 - kaslr_adjust_vmlinux_info(-__START_KERNEL); 396 - } 397 - 398 391 void startup_kernel(void) 399 392 { 400 - unsigned long kernel_size = vmlinux.image_size + vmlinux.bss_size; 401 - unsigned long nokaslr_offset_phys, kaslr_large_page_offset; 402 - unsigned long amode31_lma = 0; 393 + unsigned long vmlinux_size = vmlinux.image_size + vmlinux.bss_size; 394 + unsigned long nokaslr_text_lma, text_lma = 0, amode31_lma = 0; 395 + unsigned long kernel_size = TEXT_OFFSET + vmlinux_size; 396 + unsigned long kaslr_large_page_offset; 403 397 unsigned long max_physmem_end; 404 398 unsigned long asce_limit; 405 399 unsigned long safe_addr; 406 400 psw_t psw; 407 401 408 - fixup_vmlinux_info(); 409 402 setup_lpp(); 410 403 411 404 /* 412 405 * Non-randomized kernel physical start address must be _SEGMENT_SIZE 413 406 * aligned (see blow). 414 407 */ 415 - nokaslr_offset_phys = ALIGN(mem_safe_offset(), _SEGMENT_SIZE); 416 - safe_addr = PAGE_ALIGN(nokaslr_offset_phys + kernel_size); 408 + nokaslr_text_lma = ALIGN(mem_safe_offset(), _SEGMENT_SIZE); 409 + safe_addr = PAGE_ALIGN(nokaslr_text_lma + vmlinux_size); 417 410 418 411 /* 419 412 * Reserve decompressor memory together with decompression heap, ··· 451 456 */ 452 457 kaslr_large_page_offset = __kaslr_offset & ~_SEGMENT_MASK; 453 458 if (kaslr_enabled()) { 454 - unsigned long end = ident_map_size - kaslr_large_page_offset; 459 + unsigned long size = vmlinux_size + kaslr_large_page_offset; 455 460 456 - __kaslr_offset_phys = randomize_within_range(kernel_size, _SEGMENT_SIZE, 0, end); 461 + text_lma = randomize_within_range(size, _SEGMENT_SIZE, TEXT_OFFSET, ident_map_size); 457 462 } 458 - if (!__kaslr_offset_phys) 459 - __kaslr_offset_phys = nokaslr_offset_phys; 460 - __kaslr_offset_phys |= kaslr_large_page_offset; 463 + if (!text_lma) 464 + text_lma = nokaslr_text_lma; 465 + text_lma |= kaslr_large_page_offset; 466 + 467 + /* 468 + * [__kaslr_offset_phys..__kaslr_offset_phys + TEXT_OFFSET] region is 469 + * never accessed via the kernel image mapping as per the linker script: 470 + * 471 + * . = TEXT_OFFSET; 472 + * 473 + * Therefore, this region could be used for something else and does 474 + * not need to be reserved. See how it is skipped in setup_vmem(). 475 + */ 476 + __kaslr_offset_phys = text_lma - TEXT_OFFSET; 461 477 kaslr_adjust_vmlinux_info(__kaslr_offset_phys); 462 - physmem_reserve(RR_VMLINUX, __kaslr_offset_phys, kernel_size); 463 - deploy_kernel((void *)__kaslr_offset_phys); 478 + physmem_reserve(RR_VMLINUX, text_lma, vmlinux_size); 479 + deploy_kernel((void *)text_lma); 464 480 465 481 /* vmlinux decompression is done, shrink reserved low memory */ 466 482 physmem_reserve(RR_DECOMPRESSOR, 0, (unsigned long)_decompressor_end); ··· 494 488 amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, amode31_min, SZ_2G); 495 489 } 496 490 if (!amode31_lma) 497 - amode31_lma = __kaslr_offset_phys - vmlinux.amode31_size; 491 + amode31_lma = text_lma - vmlinux.amode31_size; 498 492 physmem_reserve(RR_AMODE31, amode31_lma, vmlinux.amode31_size); 499 493 500 494 /* ··· 510 504 * - copy_bootdata() must follow setup_vmem() to propagate changes 511 505 * to bootdata made by setup_vmem() 512 506 */ 513 - clear_bss_section(__kaslr_offset_phys); 514 - kaslr_adjust_relocs(__kaslr_offset_phys, __kaslr_offset_phys + vmlinux.image_size, 507 + clear_bss_section(text_lma); 508 + kaslr_adjust_relocs(text_lma, text_lma + vmlinux.image_size, 515 509 __kaslr_offset, __kaslr_offset_phys); 516 510 kaslr_adjust_got(__kaslr_offset); 517 511 setup_vmem(__kaslr_offset, __kaslr_offset + kernel_size, asce_limit);
+12 -2
arch/s390/boot/vmem.c
··· 90 90 } 91 91 memgap_start = end; 92 92 } 93 - kasan_populate(kernel_start, kernel_end, POPULATE_KASAN_MAP_SHADOW); 93 + kasan_populate(kernel_start + TEXT_OFFSET, kernel_end, POPULATE_KASAN_MAP_SHADOW); 94 94 kasan_populate(0, (unsigned long)__identity_va(0), POPULATE_KASAN_ZERO_SHADOW); 95 95 kasan_populate(AMODE31_START, AMODE31_END, POPULATE_KASAN_ZERO_SHADOW); 96 96 if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) { ··· 475 475 (unsigned long)__identity_va(end), 476 476 POPULATE_IDENTITY); 477 477 } 478 - pgtable_populate(kernel_start, kernel_end, POPULATE_KERNEL); 478 + 479 + /* 480 + * [kernel_start..kernel_start + TEXT_OFFSET] region is never 481 + * accessed as per the linker script: 482 + * 483 + * . = TEXT_OFFSET; 484 + * 485 + * Therefore, skip mapping TEXT_OFFSET bytes to prevent access to 486 + * [__kaslr_offset_phys..__kaslr_offset_phys + TEXT_OFFSET] region. 487 + */ 488 + pgtable_populate(kernel_start + TEXT_OFFSET, kernel_end, POPULATE_KERNEL); 479 489 pgtable_populate(AMODE31_START, AMODE31_END, POPULATE_DIRECT); 480 490 pgtable_populate(__abs_lowcore, __abs_lowcore + sizeof(struct lowcore), 481 491 POPULATE_ABS_LOWCORE);
+6 -1
arch/s390/boot/vmlinux.lds.S
··· 109 109 #ifdef CONFIG_KERNEL_UNCOMPRESSED 110 110 . = ALIGN(PAGE_SIZE); 111 111 . += AMODE31_SIZE; /* .amode31 section */ 112 - . = ALIGN(1 << 20); /* _SEGMENT_SIZE */ 112 + 113 + /* 114 + * Make sure the location counter is not less than TEXT_OFFSET. 115 + * _SEGMENT_SIZE is not available, use ALIGN(1 << 20) instead. 116 + */ 117 + . = MAX(TEXT_OFFSET, ALIGN(1 << 20)); 113 118 #else 114 119 . = ALIGN(8); 115 120 #endif
+2 -1
arch/s390/include/asm/page.h
··· 279 279 #define AMODE31_SIZE (3 * PAGE_SIZE) 280 280 281 281 #define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) 282 - #define __START_KERNEL 0x100000 283 282 #define __NO_KASLR_START_KERNEL CONFIG_KERNEL_IMAGE_BASE 284 283 #define __NO_KASLR_END_KERNEL (__NO_KASLR_START_KERNEL + KERNEL_IMAGE_SIZE) 284 + 285 + #define TEXT_OFFSET 0x100000 285 286 286 287 #endif /* _S390_PAGE_H */
+18 -1
arch/s390/kernel/setup.c
··· 734 734 } 735 735 736 736 /* 737 - * Reserve memory used for lowcore/command line/kernel image. 737 + * Reserve memory used for lowcore. 738 + */ 739 + static void __init reserve_lowcore(void) 740 + { 741 + void *lowcore_start = get_lowcore(); 742 + void *lowcore_end = lowcore_start + sizeof(struct lowcore); 743 + void *start, *end; 744 + 745 + if ((void *)__identity_base < lowcore_end) { 746 + start = max(lowcore_start, (void *)__identity_base); 747 + end = min(lowcore_end, (void *)(__identity_base + ident_map_size)); 748 + memblock_reserve(__pa(start), __pa(end)); 749 + } 750 + } 751 + 752 + /* 753 + * Reserve memory used for absolute lowcore/command line/kernel image. 738 754 */ 739 755 static void __init reserve_kernel(void) 740 756 { ··· 934 918 935 919 /* Do some memory reservations *before* memory is added to memblock */ 936 920 reserve_pgtables(); 921 + reserve_lowcore(); 937 922 reserve_kernel(); 938 923 reserve_initrd(); 939 924 reserve_certificate_list();
+1 -1
arch/s390/kernel/vmlinux.lds.S
··· 39 39 40 40 SECTIONS 41 41 { 42 - . = __START_KERNEL; 42 + . = TEXT_OFFSET; 43 43 .text : { 44 44 _stext = .; /* Start of text section */ 45 45 _text = .; /* Text and read-only data */
+1 -1
arch/s390/tools/relocs.c
··· 280 280 case R_390_GOTOFF64: 281 281 break; 282 282 case R_390_64: 283 - add_reloc(&relocs64, offset - ehdr.e_entry); 283 + add_reloc(&relocs64, offset); 284 284 break; 285 285 default: 286 286 die("Unsupported relocation type: %d\n", r_type);
+6 -1
drivers/s390/crypto/ap_bus.c
··· 971 971 char *name) 972 972 { 973 973 struct device_driver *drv = &ap_drv->driver; 974 + int rc; 974 975 975 976 drv->bus = &ap_bus_type; 976 977 drv->owner = owner; 977 978 drv->name = name; 978 - return driver_register(drv); 979 + rc = driver_register(drv); 980 + 981 + ap_check_bindings_complete(); 982 + 983 + return rc; 979 984 } 980 985 EXPORT_SYMBOL(ap_driver_register); 981 986