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