Commit 39a1ff8ceab4b74164b2e19217206e7226aa9cd8

Authored by Heinrich Schuchardt
1 parent ffe2157447

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

... ... @@ -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
... ... @@ -560,7 +560,7 @@
560 560 u16 file_path_length;
561 561 u16 *label;
562 562 struct efi_device_path *file_path;
563   - u8 *optional_data;
  563 + const u8 *optional_data;
564 564 };
565 565  
566 566 void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data);
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