1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Helper functions used by the EFI stub on multiple 4 * architectures. This should be #included by the EFI stub 5 * implementation files. 6 * 7 * Copyright 2011 Intel Corporation; author Matt Fleming 8 */ 9 10 #include <linux/stdarg.h> 11 12 #include <linux/efi.h> 13 #include <linux/kernel.h> 14 #include <linux/overflow.h> 15 #include <linux/ucs2_string.h> 16 #include <asm/efi.h> 17 #include <asm/setup.h> 18 19 #include "efistub.h" 20 21 bool efi_nochunk; 22 bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE); 23 bool efi_novamap; 24 25 static bool efi_noinitrd; 26 static bool efi_nosoftreserve; 27 static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA); 28 29 int efi_mem_encrypt; 30 31 bool __pure __efi_soft_reserve_enabled(void) 32 { 33 return !efi_nosoftreserve; 34 } 35 36 /** 37 * efi_parse_options() - Parse EFI command line options 38 * @cmdline: kernel command line 39 * 40 * Parse the ASCII string @cmdline for EFI options, denoted by the efi= 41 * option, e.g. efi=nochunk. 42 * 43 * It should be noted that efi= is parsed in two very different 44 * environments, first in the early boot environment of the EFI boot 45 * stub, and subsequently during the kernel boot. 46 * 47 * Return: status code 48 */ 49 efi_status_t efi_parse_options(char const *cmdline) 50 { 51 char *buf __free(efi_pool) = NULL; 52 efi_status_t status; 53 size_t len; 54 char *str; 55 56 if (!cmdline) 57 return EFI_SUCCESS; 58 59 len = strnlen(cmdline, COMMAND_LINE_SIZE - 1) + 1; 60 status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, len, (void **)&buf); 61 if (status != EFI_SUCCESS) 62 return status; 63 64 memcpy(buf, cmdline, len - 1); 65 buf[len - 1] = '\0'; 66 str = skip_spaces(buf); 67 68 while (*str) { 69 char *param, *val; 70 71 str = next_arg(str, ¶m, &val); 72 if (!val && !strcmp(param, "--")) 73 break; 74 75 if (!strcmp(param, "nokaslr")) { 76 efi_nokaslr = true; 77 } else if (!strcmp(param, "quiet")) { 78 efi_loglevel = CONSOLE_LOGLEVEL_QUIET; 79 } else if (!strcmp(param, "noinitrd")) { 80 efi_noinitrd = true; 81 } else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) { 82 efi_no5lvl = true; 83 } else if (IS_ENABLED(CONFIG_LOONGARCH) && 84 IS_ENABLED(CONFIG_HIBERNATION) && 85 !strcmp(param, "resume") && val) { 86 efi_nokaslr = true; /* LoongArch can't KASLR for hibernation */ 87 } else if (IS_ENABLED(CONFIG_ARCH_HAS_MEM_ENCRYPT) && 88 !strcmp(param, "mem_encrypt") && val) { 89 if (parse_option_str(val, "on")) 90 efi_mem_encrypt = 1; 91 else if (parse_option_str(val, "off")) 92 efi_mem_encrypt = -1; 93 } else if (!strcmp(param, "efi") && val) { 94 efi_nochunk = parse_option_str(val, "nochunk"); 95 efi_novamap |= parse_option_str(val, "novamap"); 96 97 efi_nosoftreserve = IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) && 98 parse_option_str(val, "nosoftreserve"); 99 100 if (parse_option_str(val, "disable_early_pci_dma")) 101 efi_disable_pci_dma = true; 102 if (parse_option_str(val, "no_disable_early_pci_dma")) 103 efi_disable_pci_dma = false; 104 if (parse_option_str(val, "debug")) 105 efi_loglevel = CONSOLE_LOGLEVEL_DEBUG; 106 } else if (!strcmp(param, "video") && 107 val && strstarts(val, "efifb:")) { 108 efi_parse_option_graphics(val + strlen("efifb:")); 109 } 110 } 111 return EFI_SUCCESS; 112 } 113 114 /* 115 * The EFI_LOAD_OPTION descriptor has the following layout: 116 * u32 Attributes; 117 * u16 FilePathListLength; 118 * u16 Description[]; 119 * efi_device_path_protocol_t FilePathList[]; 120 * u8 OptionalData[]; 121 * 122 * This function validates and unpacks the variable-size data fields. 123 */ 124 static 125 bool efi_load_option_unpack(efi_load_option_unpacked_t *dest, 126 const efi_load_option_t *src, size_t size) 127 { 128 const void *pos; 129 u16 c; 130 efi_device_path_protocol_t header; 131 const efi_char16_t *description; 132 const efi_device_path_protocol_t *file_path_list; 133 134 if (size < offsetof(efi_load_option_t, variable_data)) 135 return false; 136 pos = src->variable_data; 137 size -= offsetof(efi_load_option_t, variable_data); 138 139 if ((src->attributes & ~EFI_LOAD_OPTION_MASK) != 0) 140 return false; 141 142 /* Scan description. */ 143 description = pos; 144 do { 145 if (size < sizeof(c)) 146 return false; 147 c = *(const u16 *)pos; 148 pos += sizeof(c); 149 size -= sizeof(c); 150 } while (c != L'\0'); 151 152 /* Scan file_path_list. */ 153 file_path_list = pos; 154 do { 155 if (size < sizeof(header)) 156 return false; 157 header = *(const efi_device_path_protocol_t *)pos; 158 if (header.length < sizeof(header)) 159 return false; 160 if (size < header.length) 161 return false; 162 pos += header.length; 163 size -= header.length; 164 } while ((header.type != EFI_DEV_END_PATH && header.type != EFI_DEV_END_PATH2) || 165 (header.sub_type != EFI_DEV_END_ENTIRE)); 166 if (pos != (const void *)file_path_list + src->file_path_list_length) 167 return false; 168 169 dest->attributes = src->attributes; 170 dest->file_path_list_length = src->file_path_list_length; 171 dest->description = description; 172 dest->file_path_list = file_path_list; 173 dest->optional_data_size = size; 174 dest->optional_data = size ? pos : NULL; 175 176 return true; 177 } 178 179 /* 180 * At least some versions of Dell firmware pass the entire contents of the 181 * Boot#### variable, i.e. the EFI_LOAD_OPTION descriptor, rather than just the 182 * OptionalData field. 183 * 184 * Detect this case and extract OptionalData. 185 */ 186 void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_size) 187 { 188 const efi_load_option_t *load_option = *load_options; 189 efi_load_option_unpacked_t load_option_unpacked; 190 191 if (!IS_ENABLED(CONFIG_X86)) 192 return; 193 if (!load_option) 194 return; 195 if (*load_options_size < sizeof(*load_option)) 196 return; 197 if ((load_option->attributes & ~EFI_LOAD_OPTION_BOOT_MASK) != 0) 198 return; 199 200 if (!efi_load_option_unpack(&load_option_unpacked, load_option, *load_options_size)) 201 return; 202 203 efi_warn_once(FW_BUG "LoadOptions is an EFI_LOAD_OPTION descriptor\n"); 204 efi_warn_once(FW_BUG "Using OptionalData as a workaround\n"); 205 206 *load_options = load_option_unpacked.optional_data; 207 *load_options_size = load_option_unpacked.optional_data_size; 208 } 209 210 enum efistub_event_type { 211 EFISTUB_EVT_INITRD, 212 EFISTUB_EVT_LOAD_OPTIONS, 213 EFISTUB_EVT_COUNT, 214 }; 215 216 #define STR_WITH_SIZE(s) sizeof(s), s 217 218 static const struct { 219 u32 pcr_index; 220 u32 event_id; 221 u32 event_data_len; 222 u8 event_data[52]; 223 } events[] = { 224 [EFISTUB_EVT_INITRD] = { 225 9, 226 INITRD_EVENT_TAG_ID, 227 STR_WITH_SIZE("Linux initrd") 228 }, 229 [EFISTUB_EVT_LOAD_OPTIONS] = { 230 9, 231 LOAD_OPTIONS_EVENT_TAG_ID, 232 STR_WITH_SIZE("LOADED_IMAGE::LoadOptions") 233 }, 234 }; 235 236 static_assert(sizeof(efi_tcg2_event_t) == sizeof(efi_cc_event_t)); 237 238 union efistub_event { 239 efi_tcg2_event_t tcg2_data; 240 efi_cc_event_t cc_data; 241 }; 242 243 struct efistub_measured_event { 244 union efistub_event event_data; 245 TCG_PCClientTaggedEvent tagged_event __packed; 246 }; 247 248 static efi_status_t efi_measure_tagged_event(unsigned long load_addr, 249 unsigned long load_size, 250 enum efistub_event_type event) 251 { 252 static efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; 253 union { 254 efi_status_t 255 (__efiapi *hash_log_extend_event)(void *, u64, efi_physical_addr_t, 256 u64, const union efistub_event *); 257 struct { u32 hash_log_extend_event; } mixed_mode; 258 } method; 259 struct efistub_measured_event *evt __free(efi_pool) = NULL; 260 int size = struct_size(evt, tagged_event.tagged_event_data, 261 events[event].event_data_len); 262 efi_tcg2_protocol_t *tcg2 = NULL; 263 union efistub_event ev; 264 efi_status_t status; 265 void *protocol; 266 267 efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2); 268 if (tcg2) { 269 ev.tcg2_data = (struct efi_tcg2_event){ 270 .event_size = size, 271 .event_header.header_size = sizeof(ev.tcg2_data.event_header), 272 .event_header.header_version = EFI_TCG2_EVENT_HEADER_VERSION, 273 .event_header.pcr_index = events[event].pcr_index, 274 .event_header.event_type = EV_EVENT_TAG, 275 }; 276 protocol = tcg2; 277 method.hash_log_extend_event = 278 (void *)efi_table_attr(tcg2, hash_log_extend_event); 279 } else { 280 static efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID; 281 efi_cc_protocol_t *cc = NULL; 282 283 efi_bs_call(locate_protocol, &cc_guid, NULL, (void **)&cc); 284 if (!cc) 285 return EFI_UNSUPPORTED; 286 287 ev.cc_data = (struct efi_cc_event){ 288 .event_size = size, 289 .event_header.header_size = sizeof(ev.cc_data.event_header), 290 .event_header.header_version = EFI_CC_EVENT_HEADER_VERSION, 291 .event_header.event_type = EV_EVENT_TAG, 292 }; 293 294 status = efi_call_proto(cc, map_pcr_to_mr_index, 295 events[event].pcr_index, 296 &ev.cc_data.event_header.mr_index); 297 if (status != EFI_SUCCESS) 298 goto fail; 299 300 protocol = cc; 301 method.hash_log_extend_event = 302 (void *)efi_table_attr(cc, hash_log_extend_event); 303 } 304 305 status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size, (void **)&evt); 306 if (status != EFI_SUCCESS) 307 goto fail; 308 309 *evt = (struct efistub_measured_event) { 310 .event_data = ev, 311 .tagged_event.tagged_event_id = events[event].event_id, 312 .tagged_event.tagged_event_data_size = events[event].event_data_len, 313 }; 314 315 memcpy(evt->tagged_event.tagged_event_data, events[event].event_data, 316 events[event].event_data_len); 317 318 status = efi_fn_call(&method, hash_log_extend_event, protocol, 0, 319 load_addr, load_size, &evt->event_data); 320 321 if (status == EFI_SUCCESS) 322 return EFI_SUCCESS; 323 324 fail: 325 efi_warn("Failed to measure data for event %d: 0x%lx\n", event, status); 326 return status; 327 } 328 329 /* 330 * Convert the unicode UEFI command line to ASCII to pass to kernel. 331 * Size of memory allocated return in *cmd_line_len. 332 * Returns NULL on error. 333 */ 334 char *efi_convert_cmdline(efi_loaded_image_t *image) 335 { 336 const efi_char16_t *options = efi_table_attr(image, load_options); 337 u32 options_size = efi_table_attr(image, load_options_size); 338 unsigned long options_chars = 0; 339 unsigned long cmdline_bytes; 340 efi_status_t status; 341 char *cmdline_addr; 342 343 if (options_size > 0) 344 efi_measure_tagged_event((unsigned long)options, options_size, 345 EFISTUB_EVT_LOAD_OPTIONS); 346 347 efi_apply_loadoptions_quirk((const void **)&options, &options_size); 348 if (options) 349 options_chars = ucs2_strnlen(options, 350 options_size / sizeof(efi_char16_t)); 351 352 /* Each UCS-2 char takes up at most 3 UTF-8 bytes */ 353 cmdline_bytes = min(3 * options_chars, COMMAND_LINE_SIZE - 1) + 3; 354 355 status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, cmdline_bytes, 356 (void **)&cmdline_addr); 357 if (status != EFI_SUCCESS) 358 return NULL; 359 360 if (ucs2_as_utf8_l(cmdline_addr, options, options_chars, 361 cmdline_bytes) >= COMMAND_LINE_SIZE) { 362 /* 363 * The output fills up the entire buffer, and may have been 364 * truncated. Work backwards through the buffer to find a safe 365 * truncation point (i.e., a blank character not inside a 366 * quoted string). 367 */ 368 int safe_pos[2] = {}; 369 int in_quote = 0; 370 371 for (int i = COMMAND_LINE_SIZE - 1; i >= 0; i--) { 372 char c = cmdline_addr[i]; 373 374 if (!c) 375 return cmdline_addr; 376 else if (c == '"') 377 in_quote ^= 1; 378 else if (!safe_pos[in_quote] && isspace(c)) 379 safe_pos[in_quote] = i; 380 } 381 382 efi_err("Command line is too long: truncated to %d bytes\n", 383 safe_pos[in_quote]); 384 cmdline_addr[safe_pos[in_quote]] = '\0'; 385 } 386 387 return cmdline_addr; 388 } 389 390 /** 391 * efi_exit_boot_services() - Exit boot services 392 * @handle: handle of the exiting image 393 * @priv: argument to be passed to @priv_func 394 * @priv_func: function to process the memory map before exiting boot services 395 * 396 * Handle calling ExitBootServices according to the requirements set out by the 397 * spec. Obtains the current memory map, and returns that info after calling 398 * ExitBootServices. The client must specify a function to perform any 399 * processing of the memory map data prior to ExitBootServices. A client 400 * specific structure may be passed to the function via priv. The client 401 * function may be called multiple times. 402 * 403 * Return: status code 404 */ 405 efi_status_t efi_exit_boot_services(void *handle, void *priv, 406 efi_exit_boot_map_processing priv_func) 407 { 408 struct efi_boot_memmap *map; 409 efi_status_t status; 410 411 if (efi_disable_pci_dma) 412 efi_pci_disable_bridge_busmaster(); 413 414 status = efi_get_memory_map(&map, true); 415 if (status != EFI_SUCCESS) 416 return status; 417 418 status = priv_func(map, priv); 419 if (status != EFI_SUCCESS) { 420 efi_bs_call(free_pool, map); 421 return status; 422 } 423 424 status = efi_bs_call(exit_boot_services, handle, map->map_key); 425 426 if (status == EFI_INVALID_PARAMETER) { 427 /* 428 * The memory map changed between efi_get_memory_map() and 429 * exit_boot_services(). Per the UEFI Spec v2.6, Section 6.4: 430 * EFI_BOOT_SERVICES.ExitBootServices we need to get the 431 * updated map, and try again. The spec implies one retry 432 * should be sufficent, which is confirmed against the EDK2 433 * implementation. Per the spec, we can only invoke 434 * get_memory_map() and exit_boot_services() - we cannot alloc 435 * so efi_get_memory_map() cannot be used, and we must reuse 436 * the buffer. For all practical purposes, the headroom in the 437 * buffer should account for any changes in the map so the call 438 * to get_memory_map() is expected to succeed here. 439 */ 440 map->map_size = map->buff_size; 441 status = efi_bs_call(get_memory_map, 442 &map->map_size, 443 &map->map, 444 &map->map_key, 445 &map->desc_size, 446 &map->desc_ver); 447 448 /* exit_boot_services() was called, thus cannot free */ 449 if (status != EFI_SUCCESS) 450 return status; 451 452 status = priv_func(map, priv); 453 /* exit_boot_services() was called, thus cannot free */ 454 if (status != EFI_SUCCESS) 455 return status; 456 457 status = efi_bs_call(exit_boot_services, handle, map->map_key); 458 } 459 460 return status; 461 } 462 463 /** 464 * get_efi_config_table() - retrieve UEFI configuration table 465 * @guid: GUID of the configuration table to be retrieved 466 * Return: pointer to the configuration table or NULL 467 */ 468 void *get_efi_config_table(efi_guid_t guid) 469 { 470 unsigned long tables = efi_table_attr(efi_system_table, tables); 471 int nr_tables = efi_table_attr(efi_system_table, nr_tables); 472 int i; 473 474 for (i = 0; i < nr_tables; i++) { 475 efi_config_table_t *t = (void *)tables; 476 477 if (efi_guidcmp(t->guid, guid) == 0) 478 return efi_table_attr(t, table); 479 480 tables += efi_is_native() ? sizeof(efi_config_table_t) 481 : sizeof(efi_config_table_32_t); 482 } 483 return NULL; 484 } 485 486 /* 487 * The LINUX_EFI_INITRD_MEDIA_GUID vendor media device path below provides a way 488 * for the firmware or bootloader to expose the initrd data directly to the stub 489 * via the trivial LoadFile2 protocol, which is defined in the UEFI spec, and is 490 * very easy to implement. It is a simple Linux initrd specific conduit between 491 * kernel and firmware, allowing us to put the EFI stub (being part of the 492 * kernel) in charge of where and when to load the initrd, while leaving it up 493 * to the firmware to decide whether it needs to expose its filesystem hierarchy 494 * via EFI protocols. 495 */ 496 static const struct { 497 struct efi_vendor_dev_path vendor; 498 struct efi_generic_dev_path end; 499 } __packed initrd_dev_path = { 500 { 501 { 502 EFI_DEV_MEDIA, 503 EFI_DEV_MEDIA_VENDOR, 504 sizeof(struct efi_vendor_dev_path), 505 }, 506 LINUX_EFI_INITRD_MEDIA_GUID 507 }, { 508 EFI_DEV_END_PATH, 509 EFI_DEV_END_ENTIRE, 510 sizeof(struct efi_generic_dev_path) 511 } 512 }; 513 514 /** 515 * efi_load_initrd_dev_path() - load the initrd from the Linux initrd device path 516 * @initrd: pointer of struct to store the address where the initrd was loaded 517 * and the size of the loaded initrd 518 * @max: upper limit for the initrd memory allocation 519 * 520 * Return: 521 * * %EFI_SUCCESS if the initrd was loaded successfully, in which 522 * case @load_addr and @load_size are assigned accordingly 523 * * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd device path 524 * * %EFI_OUT_OF_RESOURCES if memory allocation failed 525 * * %EFI_LOAD_ERROR in all other cases 526 */ 527 static 528 efi_status_t efi_load_initrd_dev_path(struct linux_efi_initrd *initrd, 529 unsigned long max) 530 { 531 static efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID; 532 efi_device_path_protocol_t *dp; 533 efi_load_file2_protocol_t *lf2; 534 efi_handle_t handle; 535 efi_status_t status; 536 537 dp = (efi_device_path_protocol_t *)&initrd_dev_path; 538 status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp, &handle); 539 if (status != EFI_SUCCESS) 540 return status; 541 542 status = efi_bs_call(handle_protocol, handle, &lf2_proto_guid, 543 (void **)&lf2); 544 if (status != EFI_SUCCESS) 545 return status; 546 547 initrd->size = 0; 548 status = efi_call_proto(lf2, load_file, dp, false, &initrd->size, NULL); 549 if (status != EFI_BUFFER_TOO_SMALL) 550 return EFI_LOAD_ERROR; 551 552 status = efi_allocate_pages(initrd->size, &initrd->base, max); 553 if (status != EFI_SUCCESS) 554 return status; 555 556 status = efi_call_proto(lf2, load_file, dp, false, &initrd->size, 557 (void *)initrd->base); 558 if (status != EFI_SUCCESS) { 559 efi_free(initrd->size, initrd->base); 560 return EFI_LOAD_ERROR; 561 } 562 return EFI_SUCCESS; 563 } 564 565 static 566 efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image, 567 struct linux_efi_initrd *initrd, 568 unsigned long soft_limit, 569 unsigned long hard_limit) 570 { 571 if (image == NULL) 572 return EFI_UNSUPPORTED; 573 574 return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2, 575 soft_limit, hard_limit, 576 &initrd->base, &initrd->size); 577 } 578 579 /** 580 * efi_load_initrd() - Load initial RAM disk 581 * @image: EFI loaded image protocol 582 * @soft_limit: preferred address for loading the initrd 583 * @hard_limit: upper limit address for loading the initrd 584 * @out: pointer to store the address of the initrd table 585 * 586 * Return: status code 587 */ 588 efi_status_t efi_load_initrd(efi_loaded_image_t *image, 589 unsigned long soft_limit, 590 unsigned long hard_limit, 591 const struct linux_efi_initrd **out) 592 { 593 static efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID; 594 efi_status_t status = EFI_SUCCESS; 595 struct linux_efi_initrd initrd, *tbl; 596 597 if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD) || efi_noinitrd) 598 return EFI_SUCCESS; 599 600 status = efi_load_initrd_dev_path(&initrd, hard_limit); 601 if (status == EFI_SUCCESS) { 602 efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n"); 603 } else if (status == EFI_NOT_FOUND) { 604 status = efi_load_initrd_cmdline(image, &initrd, soft_limit, 605 hard_limit); 606 /* command line loader disabled or no initrd= passed? */ 607 if (status == EFI_UNSUPPORTED || status == EFI_NOT_READY) 608 return EFI_SUCCESS; 609 if (status == EFI_SUCCESS) 610 efi_info("Loaded initrd from command line option\n"); 611 } 612 if (status != EFI_SUCCESS) 613 goto failed; 614 615 if (initrd.size > 0 && 616 efi_measure_tagged_event(initrd.base, initrd.size, 617 EFISTUB_EVT_INITRD) == EFI_SUCCESS) 618 efi_info("Measured initrd data into PCR 9\n"); 619 620 status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(initrd), 621 (void **)&tbl); 622 if (status != EFI_SUCCESS) 623 goto free_initrd; 624 625 *tbl = initrd; 626 status = efi_bs_call(install_configuration_table, &tbl_guid, tbl); 627 if (status != EFI_SUCCESS) 628 goto free_tbl; 629 630 if (out) 631 *out = tbl; 632 return EFI_SUCCESS; 633 634 free_tbl: 635 efi_bs_call(free_pool, tbl); 636 free_initrd: 637 efi_free(initrd.size, initrd.base); 638 failed: 639 efi_err("Failed to load initrd: 0x%lx\n", status); 640 return status; 641 } 642 643 /** 644 * efi_wait_for_key() - Wait for key stroke 645 * @usec: number of microseconds to wait for key stroke 646 * @key: key entered 647 * 648 * Wait for up to @usec microseconds for a key stroke. 649 * 650 * Return: status code, EFI_SUCCESS if key received 651 */ 652 efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key) 653 { 654 efi_event_t events[2], timer; 655 unsigned long index; 656 efi_simple_text_input_protocol_t *con_in; 657 efi_status_t status; 658 659 con_in = efi_table_attr(efi_system_table, con_in); 660 if (!con_in) 661 return EFI_UNSUPPORTED; 662 efi_set_event_at(events, 0, efi_table_attr(con_in, wait_for_key)); 663 664 status = efi_bs_call(create_event, EFI_EVT_TIMER, 0, NULL, NULL, &timer); 665 if (status != EFI_SUCCESS) 666 return status; 667 668 status = efi_bs_call(set_timer, timer, EfiTimerRelative, 669 EFI_100NSEC_PER_USEC * usec); 670 if (status != EFI_SUCCESS) 671 return status; 672 efi_set_event_at(events, 1, timer); 673 674 status = efi_bs_call(wait_for_event, 2, events, &index); 675 if (status == EFI_SUCCESS) { 676 if (index == 0) 677 status = efi_call_proto(con_in, read_keystroke, key); 678 else 679 status = EFI_TIMEOUT; 680 } 681 682 efi_bs_call(close_event, timer); 683 684 return status; 685 } 686 687 /** 688 * efi_remap_image - Remap a loaded image with the appropriate permissions 689 * for code and data 690 * 691 * @image_base: the base of the image in memory 692 * @alloc_size: the size of the area in memory occupied by the image 693 * @code_size: the size of the leading part of the image containing code 694 * and read-only data 695 * 696 * efi_remap_image() uses the EFI memory attribute protocol to remap the code 697 * region of the loaded image read-only/executable, and the remainder 698 * read-write/non-executable. The code region is assumed to start at the base 699 * of the image, and will therefore cover the PE/COFF header as well. 700 */ 701 void efi_remap_image(unsigned long image_base, unsigned alloc_size, 702 unsigned long code_size) 703 { 704 static efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; 705 efi_memory_attribute_protocol_t *memattr; 706 efi_status_t status; 707 u64 attr; 708 709 /* 710 * If the firmware implements the EFI_MEMORY_ATTRIBUTE_PROTOCOL, let's 711 * invoke it to remap the text/rodata region of the decompressed image 712 * as read-only and the data/bss region as non-executable. 713 */ 714 status = efi_bs_call(locate_protocol, &guid, NULL, (void **)&memattr); 715 if (status != EFI_SUCCESS) 716 return; 717 718 // Get the current attributes for the entire region 719 status = memattr->get_memory_attributes(memattr, image_base, 720 alloc_size, &attr); 721 if (status != EFI_SUCCESS) { 722 efi_warn("Failed to retrieve memory attributes for image region: 0x%lx\n", 723 status); 724 return; 725 } 726 727 // Mark the code region as read-only 728 status = memattr->set_memory_attributes(memattr, image_base, code_size, 729 EFI_MEMORY_RO); 730 if (status != EFI_SUCCESS) { 731 efi_warn("Failed to remap code region read-only\n"); 732 return; 733 } 734 735 // If the entire region was already mapped as non-exec, clear the 736 // attribute from the code region. Otherwise, set it on the data 737 // region. 738 if (attr & EFI_MEMORY_XP) { 739 status = memattr->clear_memory_attributes(memattr, image_base, 740 code_size, 741 EFI_MEMORY_XP); 742 if (status != EFI_SUCCESS) 743 efi_warn("Failed to remap code region executable\n"); 744 } else { 745 status = memattr->set_memory_attributes(memattr, 746 image_base + code_size, 747 alloc_size - code_size, 748 EFI_MEMORY_XP); 749 if (status != EFI_SUCCESS) 750 efi_warn("Failed to remap data region non-executable\n"); 751 } 752 } 753