Commit 39a1ff8ceab4b74164b2e19217206e7226aa9cd8
1 parent
ffe2157447
Exists in
smarc_8mq_lf_v2020.04
and in
9 other branches
efi_loader: optional data in load options are binary
The field boot OptionalData in structure _EFI_LOAD_OPTIONS is for binary data. When we use `efidebug boot add` we should convert the 5th argument from UTF-8 to UTF-16 before putting it into the BootXXXX variable. When printing boot variables with `efidebug boot dump` we should support the OptionalData being arbitrary binary data. So let's dump the data as hexadecimal values. Here is an example session protocol: => efidebug boot add 00a1 label1 scsi 0:1 doit1 'my option' => efidebug boot add 00a2 label2 scsi 0:1 doit2 => efidebug boot dump Boot00A0: attributes: A-- (0x00000001) label: label1 file_path: .../HD(1,MBR,0xeac4e18b,0x800,0x3fffe)/doit1 data: 00000000: 6d 00 79 00 20 00 6f 00 70 00 74 00 69 00 6f 00 m.y. .o.p.t.i.o. 00000010: 6e 00 00 00 n... Boot00A1: attributes: A-- (0x00000001) label: label2 file_path: .../HD(1,MBR,0xeac4e18b,0x800,0x3fffe)/doit2 data: Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Showing 3 changed files with 26 additions and 18 deletions Side-by-side Diff
cmd/efidebug.c
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | #include <efi_loader.h> |
12 | 12 | #include <environment.h> |
13 | 13 | #include <exports.h> |
14 | +#include <hexdump.h> | |
14 | 15 | #include <malloc.h> |
15 | 16 | #include <search.h> |
16 | 17 | #include <linux/ctype.h> |
... | ... | @@ -545,7 +546,10 @@ |
545 | 546 | + sizeof(struct efi_device_path); /* for END */ |
546 | 547 | |
547 | 548 | /* optional data */ |
548 | - lo.optional_data = (u8 *)(argc == 6 ? "" : argv[6]); | |
549 | + if (argc < 6) | |
550 | + lo.optional_data = NULL; | |
551 | + else | |
552 | + lo.optional_data = (const u8 *)argv[6]; | |
549 | 553 | |
550 | 554 | size = efi_serialize_load_option(&lo, (u8 **)&data); |
551 | 555 | if (!size) { |
552 | 556 | |
... | ... | @@ -615,12 +619,13 @@ |
615 | 619 | /** |
616 | 620 | * show_efi_boot_opt_data() - dump UEFI load option |
617 | 621 | * |
618 | - * @id: Load option number | |
619 | - * @data: Value of UEFI load option variable | |
622 | + * @id: load option number | |
623 | + * @data: value of UEFI load option variable | |
624 | + * @size: size of the boot option | |
620 | 625 | * |
621 | 626 | * Decode the value of UEFI load option variable and print information. |
622 | 627 | */ |
623 | -static void show_efi_boot_opt_data(int id, void *data) | |
628 | +static void show_efi_boot_opt_data(int id, void *data, size_t size) | |
624 | 629 | { |
625 | 630 | struct efi_load_option lo; |
626 | 631 | char *label, *p; |
... | ... | @@ -638,7 +643,7 @@ |
638 | 643 | utf16_utf8_strncpy(&p, lo.label, label_len16); |
639 | 644 | |
640 | 645 | printf("Boot%04X:\n", id); |
641 | - printf("\tattributes: %c%c%c (0x%08x)\n", | |
646 | + printf(" attributes: %c%c%c (0x%08x)\n", | |
642 | 647 | /* ACTIVE */ |
643 | 648 | lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-', |
644 | 649 | /* FORCE RECONNECT */ |
645 | 650 | |
646 | 651 | |
... | ... | @@ -646,14 +651,16 @@ |
646 | 651 | /* HIDDEN */ |
647 | 652 | lo.attributes & LOAD_OPTION_HIDDEN ? 'H' : '-', |
648 | 653 | lo.attributes); |
649 | - printf("\tlabel: %s\n", label); | |
654 | + printf(" label: %s\n", label); | |
650 | 655 | |
651 | 656 | dp_str = efi_dp_str(lo.file_path); |
652 | - printf("\tfile_path: %ls\n", dp_str); | |
657 | + printf(" file_path: %ls\n", dp_str); | |
653 | 658 | efi_free_pool(dp_str); |
654 | 659 | |
655 | - printf("\tdata: %s\n", lo.optional_data); | |
656 | - | |
660 | + printf(" data:\n"); | |
661 | + print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, | |
662 | + lo.optional_data, size + (u8 *)data - | |
663 | + (u8 *)lo.optional_data, true); | |
657 | 664 | free(label); |
658 | 665 | } |
659 | 666 | |
... | ... | @@ -686,7 +693,7 @@ |
686 | 693 | data)); |
687 | 694 | } |
688 | 695 | if (ret == EFI_SUCCESS) |
689 | - show_efi_boot_opt_data(id, data); | |
696 | + show_efi_boot_opt_data(id, data, size); | |
690 | 697 | else if (ret == EFI_NOT_FOUND) |
691 | 698 | printf("Boot%04X: not found\n", id); |
692 | 699 |
include/efi_loader.h
lib/efi_loader/efi_bootmgr.c
... | ... | @@ -53,19 +53,20 @@ |
53 | 53 | */ |
54 | 54 | unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) |
55 | 55 | { |
56 | - unsigned long label_len, option_len; | |
56 | + unsigned long label_len; | |
57 | 57 | unsigned long size; |
58 | 58 | u8 *p; |
59 | 59 | |
60 | 60 | label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); |
61 | - option_len = strlen((char *)lo->optional_data); | |
62 | 61 | |
63 | 62 | /* total size */ |
64 | 63 | size = sizeof(lo->attributes); |
65 | 64 | size += sizeof(lo->file_path_length); |
66 | 65 | size += label_len; |
67 | 66 | size += lo->file_path_length; |
68 | - size += option_len + 1; | |
67 | + if (lo->optional_data) | |
68 | + size += (utf8_utf16_strlen((const char *)lo->optional_data) | |
69 | + + 1) * sizeof(u16); | |
69 | 70 | p = malloc(size); |
70 | 71 | if (!p) |
71 | 72 | return 0; |
... | ... | @@ -84,10 +85,10 @@ |
84 | 85 | memcpy(p, lo->file_path, lo->file_path_length); |
85 | 86 | p += lo->file_path_length; |
86 | 87 | |
87 | - memcpy(p, lo->optional_data, option_len); | |
88 | - p += option_len; | |
89 | - *(char *)p = '\0'; | |
90 | - | |
88 | + if (lo->optional_data) { | |
89 | + utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); | |
90 | + p += sizeof(u16); /* size of trailing \0 */ | |
91 | + } | |
91 | 92 | return size; |
92 | 93 | } |
93 | 94 |