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 'efi_urgent_for_v5.14_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull EFI fixes from Borislav Petkov:
"A batch of fixes for the arm64 stub image loader:

- fix a logic bug that can make the random page allocator fail
spuriously

- force reallocation of the Image when it overlaps with firmware
reserved memory regions

- fix an oversight that defeated on optimization introduced earlier
where images loaded at a suitable offset are never moved if booting
without randomization

- complain about images that were not loaded at the right offset by
the firmware image loader"

* tag 'efi_urgent_for_v5.14_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
efi/libstub: arm64: Double check image alignment at entry
efi/libstub: arm64: Warn when efi_random_alloc() fails
efi/libstub: arm64: Relax 2M alignment again for relocatable kernels
efi/libstub: arm64: Force Image reallocation if BSS was not reserved
arm64: efi: kaslr: Fix occasional random alloc (and boot) failure

+63 -10
+61 -10
drivers/firmware/efi/libstub/arm64-stub.c
··· 35 35 } 36 36 37 37 /* 38 - * Although relocatable kernels can fix up the misalignment with respect to 39 - * MIN_KIMG_ALIGN, the resulting virtual text addresses are subtly out of 40 - * sync with those recorded in the vmlinux when kaslr is disabled but the 41 - * image required relocation anyway. Therefore retain 2M alignment unless 42 - * KASLR is in use. 38 + * Distro versions of GRUB may ignore the BSS allocation entirely (i.e., fail 39 + * to provide space, and fail to zero it). Check for this condition by double 40 + * checking that the first and the last byte of the image are covered by the 41 + * same EFI memory map entry. 43 42 */ 44 - static u64 min_kimg_align(void) 43 + static bool check_image_region(u64 base, u64 size) 45 44 { 46 - return efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN; 45 + unsigned long map_size, desc_size, buff_size; 46 + efi_memory_desc_t *memory_map; 47 + struct efi_boot_memmap map; 48 + efi_status_t status; 49 + bool ret = false; 50 + int map_offset; 51 + 52 + map.map = &memory_map; 53 + map.map_size = &map_size; 54 + map.desc_size = &desc_size; 55 + map.desc_ver = NULL; 56 + map.key_ptr = NULL; 57 + map.buff_size = &buff_size; 58 + 59 + status = efi_get_memory_map(&map); 60 + if (status != EFI_SUCCESS) 61 + return false; 62 + 63 + for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { 64 + efi_memory_desc_t *md = (void *)memory_map + map_offset; 65 + u64 end = md->phys_addr + md->num_pages * EFI_PAGE_SIZE; 66 + 67 + /* 68 + * Find the region that covers base, and return whether 69 + * it covers base+size bytes. 70 + */ 71 + if (base >= md->phys_addr && base < end) { 72 + ret = (base + size) <= end; 73 + break; 74 + } 75 + } 76 + 77 + efi_bs_call(free_pool, memory_map); 78 + 79 + return ret; 47 80 } 48 81 49 82 efi_status_t handle_kernel_image(unsigned long *image_addr, ··· 88 55 efi_status_t status; 89 56 unsigned long kernel_size, kernel_memsize = 0; 90 57 u32 phys_seed = 0; 58 + 59 + /* 60 + * Although relocatable kernels can fix up the misalignment with 61 + * respect to MIN_KIMG_ALIGN, the resulting virtual text addresses are 62 + * subtly out of sync with those recorded in the vmlinux when kaslr is 63 + * disabled but the image required relocation anyway. Therefore retain 64 + * 2M alignment if KASLR was explicitly disabled, even if it was not 65 + * going to be activated to begin with. 66 + */ 67 + u64 min_kimg_align = efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN; 91 68 92 69 if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { 93 70 if (!efi_nokaslr) { ··· 119 76 if (image->image_base != _text) 120 77 efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n"); 121 78 79 + if (!IS_ALIGNED((u64)_text, EFI_KIMG_ALIGN)) 80 + efi_err("FIRMWARE BUG: kernel image not aligned on %ldk boundary\n", 81 + EFI_KIMG_ALIGN >> 10); 82 + 122 83 kernel_size = _edata - _text; 123 84 kernel_memsize = kernel_size + (_end - _edata); 124 85 *reserve_size = kernel_memsize; ··· 132 85 * If KASLR is enabled, and we have some randomness available, 133 86 * locate the kernel at a randomized offset in physical memory. 134 87 */ 135 - status = efi_random_alloc(*reserve_size, min_kimg_align(), 88 + status = efi_random_alloc(*reserve_size, min_kimg_align, 136 89 reserve_addr, phys_seed); 90 + if (status != EFI_SUCCESS) 91 + efi_warn("efi_random_alloc() failed: 0x%lx\n", status); 137 92 } else { 138 93 status = EFI_OUT_OF_RESOURCES; 139 94 } 140 95 141 96 if (status != EFI_SUCCESS) { 142 - if (IS_ALIGNED((u64)_text, min_kimg_align())) { 97 + if (!check_image_region((u64)_text, kernel_memsize)) { 98 + efi_err("FIRMWARE BUG: Image BSS overlaps adjacent EFI memory region\n"); 99 + } else if (IS_ALIGNED((u64)_text, min_kimg_align)) { 143 100 /* 144 101 * Just execute from wherever we were loaded by the 145 102 * UEFI PE/COFF loader if the alignment is suitable. ··· 154 103 } 155 104 156 105 status = efi_allocate_pages_aligned(*reserve_size, reserve_addr, 157 - ULONG_MAX, min_kimg_align()); 106 + ULONG_MAX, min_kimg_align); 158 107 159 108 if (status != EFI_SUCCESS) { 160 109 efi_err("Failed to relocate kernel\n");
+2
drivers/firmware/efi/libstub/randomalloc.c
··· 30 30 31 31 region_end = min(md->phys_addr + md->num_pages * EFI_PAGE_SIZE - 1, 32 32 (u64)ULONG_MAX); 33 + if (region_end < size) 34 + return 0; 33 35 34 36 first_slot = round_up(md->phys_addr, align); 35 37 last_slot = round_down(region_end - size + 1, align);