1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/efi.h> 4 #include <linux/pe.h> 5 #include <asm/efi.h> 6 #include <asm/unaligned.h> 7 8 #include "efistub.h" 9 10 static unsigned char zboot_heap[SZ_256K] __aligned(64); 11 static unsigned long free_mem_ptr, free_mem_end_ptr; 12 13 #define STATIC static 14 #if defined(CONFIG_KERNEL_GZIP) 15 #include "../../../../lib/decompress_inflate.c" 16 #elif defined(CONFIG_KERNEL_LZ4) 17 #include "../../../../lib/decompress_unlz4.c" 18 #elif defined(CONFIG_KERNEL_LZMA) 19 #include "../../../../lib/decompress_unlzma.c" 20 #elif defined(CONFIG_KERNEL_LZO) 21 #include "../../../../lib/decompress_unlzo.c" 22 #elif defined(CONFIG_KERNEL_XZ) 23 #undef memcpy 24 #define memcpy memcpy 25 #undef memmove 26 #define memmove memmove 27 #include "../../../../lib/decompress_unxz.c" 28 #elif defined(CONFIG_KERNEL_ZSTD) 29 #include "../../../../lib/decompress_unzstd.c" 30 #endif 31 32 extern char efi_zboot_header[]; 33 extern char _gzdata_start[], _gzdata_end[]; 34 35 static void error(char *x) 36 { 37 efi_err("EFI decompressor: %s\n", x); 38 } 39 40 static efi_status_t __efiapi 41 load_file(efi_load_file_protocol_t *this, efi_device_path_protocol_t *rem, 42 bool boot_policy, unsigned long *bufsize, void *buffer) 43 { 44 unsigned long compressed_size = _gzdata_end - _gzdata_start; 45 struct efi_vendor_dev_path *vendor_dp; 46 bool decompress = false; 47 unsigned long size; 48 int ret; 49 50 if (rem == NULL || bufsize == NULL) 51 return EFI_INVALID_PARAMETER; 52 53 if (boot_policy) 54 return EFI_UNSUPPORTED; 55 56 // Look for our vendor media device node in the remaining file path 57 if (rem->type == EFI_DEV_MEDIA && 58 rem->sub_type == EFI_DEV_MEDIA_VENDOR) { 59 vendor_dp = container_of(rem, struct efi_vendor_dev_path, header); 60 if (efi_guidcmp(vendor_dp->vendorguid, LINUX_EFI_ZBOOT_MEDIA_GUID)) 61 return EFI_NOT_FOUND; 62 63 decompress = true; 64 rem = (void *)(vendor_dp + 1); 65 } 66 67 if (rem->type != EFI_DEV_END_PATH || 68 rem->sub_type != EFI_DEV_END_ENTIRE) 69 return EFI_NOT_FOUND; 70 71 // The uncompressed size of the payload is appended to the raw bit 72 // stream, and may therefore appear misaligned in memory 73 size = decompress ? get_unaligned_le32(_gzdata_end - 4) 74 : compressed_size; 75 if (buffer == NULL || *bufsize < size) { 76 *bufsize = size; 77 return EFI_BUFFER_TOO_SMALL; 78 } 79 80 if (decompress) { 81 ret = __decompress(_gzdata_start, compressed_size, NULL, NULL, 82 buffer, size, NULL, error); 83 if (ret < 0) { 84 error("Decompression failed"); 85 return EFI_DEVICE_ERROR; 86 } 87 } else { 88 memcpy(buffer, _gzdata_start, compressed_size); 89 } 90 91 return EFI_SUCCESS; 92 } 93 94 // Return the length in bytes of the device path up to the first end node. 95 static int device_path_length(const efi_device_path_protocol_t *dp) 96 { 97 int len = 0; 98 99 while (dp->type != EFI_DEV_END_PATH) { 100 len += dp->length; 101 dp = (void *)((u8 *)dp + dp->length); 102 } 103 return len; 104 } 105 106 static void append_rel_offset_node(efi_device_path_protocol_t **dp, 107 unsigned long start, unsigned long end) 108 { 109 struct efi_rel_offset_dev_path *rodp = (void *)*dp; 110 111 rodp->header.type = EFI_DEV_MEDIA; 112 rodp->header.sub_type = EFI_DEV_MEDIA_REL_OFFSET; 113 rodp->header.length = sizeof(struct efi_rel_offset_dev_path); 114 rodp->reserved = 0; 115 rodp->starting_offset = start; 116 rodp->ending_offset = end; 117 118 *dp = (void *)(rodp + 1); 119 } 120 121 static void append_ven_media_node(efi_device_path_protocol_t **dp, 122 efi_guid_t *guid) 123 { 124 struct efi_vendor_dev_path *vmdp = (void *)*dp; 125 126 vmdp->header.type = EFI_DEV_MEDIA; 127 vmdp->header.sub_type = EFI_DEV_MEDIA_VENDOR; 128 vmdp->header.length = sizeof(struct efi_vendor_dev_path); 129 vmdp->vendorguid = *guid; 130 131 *dp = (void *)(vmdp + 1); 132 } 133 134 static void append_end_node(efi_device_path_protocol_t **dp) 135 { 136 (*dp)->type = EFI_DEV_END_PATH; 137 (*dp)->sub_type = EFI_DEV_END_ENTIRE; 138 (*dp)->length = sizeof(struct efi_generic_dev_path); 139 140 ++*dp; 141 } 142 143 asmlinkage efi_status_t __efiapi 144 efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab) 145 { 146 struct efi_mem_mapped_dev_path mmdp = { 147 .header.type = EFI_DEV_HW, 148 .header.sub_type = EFI_DEV_MEM_MAPPED, 149 .header.length = sizeof(struct efi_mem_mapped_dev_path) 150 }; 151 efi_device_path_protocol_t *parent_dp, *dpp, *lf2_dp, *li_dp; 152 efi_load_file2_protocol_t zboot_load_file2; 153 efi_loaded_image_t *parent, *child; 154 unsigned long exit_data_size; 155 efi_handle_t child_handle; 156 efi_handle_t zboot_handle; 157 efi_char16_t *exit_data; 158 efi_status_t status; 159 void *dp_alloc; 160 int dp_len; 161 162 WRITE_ONCE(efi_system_table, systab); 163 164 free_mem_ptr = (unsigned long)&zboot_heap; 165 free_mem_end_ptr = free_mem_ptr + sizeof(zboot_heap); 166 167 exit_data = NULL; 168 exit_data_size = 0; 169 170 status = efi_bs_call(handle_protocol, handle, 171 &LOADED_IMAGE_PROTOCOL_GUID, (void **)&parent); 172 if (status != EFI_SUCCESS) { 173 error("Failed to locate parent's loaded image protocol"); 174 return status; 175 } 176 177 status = efi_bs_call(handle_protocol, handle, 178 &LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID, 179 (void **)&parent_dp); 180 if (status != EFI_SUCCESS || parent_dp == NULL) { 181 // Create a MemoryMapped() device path node to describe 182 // the parent image if no device path was provided. 183 mmdp.memory_type = parent->image_code_type; 184 mmdp.starting_addr = (unsigned long)parent->image_base; 185 mmdp.ending_addr = (unsigned long)parent->image_base + 186 parent->image_size - 1; 187 parent_dp = &mmdp.header; 188 dp_len = sizeof(mmdp); 189 } else { 190 dp_len = device_path_length(parent_dp); 191 } 192 193 // Allocate some pool memory for device path protocol data 194 status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, 195 2 * (dp_len + sizeof(struct efi_rel_offset_dev_path) + 196 sizeof(struct efi_generic_dev_path)) + 197 sizeof(struct efi_vendor_dev_path), 198 (void **)&dp_alloc); 199 if (status != EFI_SUCCESS) { 200 error("Failed to allocate device path pool memory"); 201 return status; 202 } 203 204 // Create a device path describing the compressed payload in this image 205 // <...parent_dp...>/Offset(<start>, <end>) 206 lf2_dp = memcpy(dp_alloc, parent_dp, dp_len); 207 dpp = (void *)((u8 *)lf2_dp + dp_len); 208 append_rel_offset_node(&dpp, 209 (unsigned long)(_gzdata_start - efi_zboot_header), 210 (unsigned long)(_gzdata_end - efi_zboot_header - 1)); 211 append_end_node(&dpp); 212 213 // Create a device path describing the decompressed payload in this image 214 // <...parent_dp...>/Offset(<start>, <end>)/VenMedia(ZBOOT_MEDIA_GUID) 215 dp_len += sizeof(struct efi_rel_offset_dev_path); 216 li_dp = memcpy(dpp, lf2_dp, dp_len); 217 dpp = (void *)((u8 *)li_dp + dp_len); 218 append_ven_media_node(&dpp, &LINUX_EFI_ZBOOT_MEDIA_GUID); 219 append_end_node(&dpp); 220 221 zboot_handle = NULL; 222 zboot_load_file2.load_file = load_file; 223 status = efi_bs_call(install_multiple_protocol_interfaces, 224 &zboot_handle, 225 &EFI_DEVICE_PATH_PROTOCOL_GUID, lf2_dp, 226 &EFI_LOAD_FILE2_PROTOCOL_GUID, &zboot_load_file2, 227 NULL); 228 if (status != EFI_SUCCESS) { 229 error("Failed to install LoadFile2 protocol and device path"); 230 goto free_dpalloc; 231 } 232 233 status = efi_bs_call(load_image, false, handle, li_dp, NULL, 0, 234 &child_handle); 235 if (status != EFI_SUCCESS) { 236 error("Failed to load image"); 237 goto uninstall_lf2; 238 } 239 240 status = efi_bs_call(handle_protocol, child_handle, 241 &LOADED_IMAGE_PROTOCOL_GUID, (void **)&child); 242 if (status != EFI_SUCCESS) { 243 error("Failed to locate child's loaded image protocol"); 244 goto unload_image; 245 } 246 247 // Copy the kernel command line 248 child->load_options = parent->load_options; 249 child->load_options_size = parent->load_options_size; 250 251 status = efi_bs_call(start_image, child_handle, &exit_data_size, 252 &exit_data); 253 if (status != EFI_SUCCESS) { 254 error("StartImage() returned with error:"); 255 if (exit_data_size > 0) 256 efi_err("%ls\n", exit_data); 257 258 // If StartImage() returns EFI_SECURITY_VIOLATION, the image is 259 // not unloaded so we need to do it by hand. 260 if (status == EFI_SECURITY_VIOLATION) 261 unload_image: 262 efi_bs_call(unload_image, child_handle); 263 } 264 265 uninstall_lf2: 266 efi_bs_call(uninstall_multiple_protocol_interfaces, 267 zboot_handle, 268 &EFI_DEVICE_PATH_PROTOCOL_GUID, lf2_dp, 269 &EFI_LOAD_FILE2_PROTOCOL_GUID, &zboot_load_file2, 270 NULL); 271 272 free_dpalloc: 273 efi_bs_call(free_pool, dp_alloc); 274 275 efi_bs_call(exit, handle, status, exit_data_size, exit_data); 276 277 // Free ExitData in case Exit() returned with a failure code, 278 // but return the original status code. 279 error("Exit() returned with failure code"); 280 if (exit_data != NULL) 281 efi_bs_call(free_pool, exit_data); 282 return status; 283 } 284