public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Takahiro Akashi <takahiro.akashi@linaro.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 1/1] efi_loader: optional data in load options are binary
Date: Tue, 7 May 2019 10:53:09 +0900	[thread overview]
Message-ID: <20190507015308.GA11160@linaro.org> (raw)
In-Reply-To: <20190430061115.29960-1-xypron.glpk@gmx.de>

On Tue, Apr 30, 2019 at 08:11:15AM +0200, Heinrich Schuchardt wrote:
> 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.

While optional_data holds u8 string in calling efi_serialize_load_option(),
it holds u16 string in leaving from efi_deserialize_load_option().
We should handle it in a consistent way if you want to keep optional_data
as "const u8."

Thanks,
-Takahiro Akashi

> 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>
> ---
> v2:
> 	remove statement without effect in efi_serialize_load_option()
> ---
>  cmd/efidebug.c               | 27 +++++++++++++++++----------
>  include/efi_loader.h         |  2 +-
>  lib/efi_loader/efi_bootmgr.c | 15 ++++++++-------
>  3 files changed, 26 insertions(+), 18 deletions(-)
> 
> diff --git a/cmd/efidebug.c b/cmd/efidebug.c
> index efe4ea873e..c4ac9dd634 100644
> --- a/cmd/efidebug.c
> +++ b/cmd/efidebug.c
> @@ -11,6 +11,7 @@
>  #include <efi_loader.h>
>  #include <environment.h>
>  #include <exports.h>
> +#include <hexdump.h>
>  #include <malloc.h>
>  #include <search.h>
>  #include <linux/ctype.h>
> @@ -545,7 +546,10 @@ static int do_efi_boot_add(cmd_tbl_t *cmdtp, int flag,
>  				+ sizeof(struct efi_device_path); /* for END */
> 
>  	/* optional data */
> -	lo.optional_data = (u8 *)(argc == 6 ? "" : argv[6]);
> +	if (argc < 6)
> +		lo.optional_data = NULL;
> +	else
> +		lo.optional_data = (const u8 *)argv[6];
> 
>  	size = efi_serialize_load_option(&lo, (u8 **)&data);
>  	if (!size) {
> @@ -615,12 +619,13 @@ static int do_efi_boot_rm(cmd_tbl_t *cmdtp, int flag,
>  /**
>   * show_efi_boot_opt_data() - dump UEFI load option
>   *
> - * @id:		Load option number
> - * @data:	Value of UEFI load option variable
> + * @id:		load option number
> + * @data:	value of UEFI load option variable
> + * @size:	size of the boot option
>   *
>   * Decode the value of UEFI load option variable and print information.
>   */
> -static void show_efi_boot_opt_data(int id, void *data)
> +static void show_efi_boot_opt_data(int id, void *data, size_t size)
>  {
>  	struct efi_load_option lo;
>  	char *label, *p;
> @@ -638,7 +643,7 @@ static void show_efi_boot_opt_data(int id, void *data)
>  	utf16_utf8_strncpy(&p, lo.label, label_len16);
> 
>  	printf("Boot%04X:\n", id);
> -	printf("\tattributes: %c%c%c (0x%08x)\n",
> +	printf("  attributes: %c%c%c (0x%08x)\n",
>  	       /* ACTIVE */
>  	       lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-',
>  	       /* FORCE RECONNECT */
> @@ -646,14 +651,16 @@ static void show_efi_boot_opt_data(int id, void *data)
>  	       /* HIDDEN */
>  	       lo.attributes & LOAD_OPTION_HIDDEN ? 'H' : '-',
>  	       lo.attributes);
> -	printf("\tlabel: %s\n", label);
> +	printf("  label: %s\n", label);
> 
>  	dp_str = efi_dp_str(lo.file_path);
> -	printf("\tfile_path: %ls\n", dp_str);
> +	printf("  file_path: %ls\n", dp_str);
>  	efi_free_pool(dp_str);
> 
> -	printf("\tdata: %s\n", lo.optional_data);
> -
> +	printf("  data:\n");
> +	print_hex_dump("    ", DUMP_PREFIX_OFFSET, 16, 1,
> +		       lo.optional_data, size + (u8 *)data -
> +		       (u8 *)lo.optional_data, true);
>  	free(label);
>  }
> 
> @@ -686,7 +693,7 @@ static void show_efi_boot_opt(int id)
>  						data));
>  	}
>  	if (ret == EFI_SUCCESS)
> -		show_efi_boot_opt_data(id, data);
> +		show_efi_boot_opt_data(id, data, size);
>  	else if (ret == EFI_NOT_FOUND)
>  		printf("Boot%04X: not found\n", id);
> 
> diff --git a/include/efi_loader.h b/include/efi_loader.h
> index 39ed8a6fa5..07b913d256 100644
> --- a/include/efi_loader.h
> +++ b/include/efi_loader.h
> @@ -560,7 +560,7 @@ struct efi_load_option {
>  	u16 file_path_length;
>  	u16 *label;
>  	struct efi_device_path *file_path;
> -	u8 *optional_data;
> +	const u8 *optional_data;
>  };
> 
>  void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data);
> diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
> index 4ccba22875..7bf51874c1 100644
> --- a/lib/efi_loader/efi_bootmgr.c
> +++ b/lib/efi_loader/efi_bootmgr.c
> @@ -53,19 +53,20 @@ void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data)
>   */
>  unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data)
>  {
> -	unsigned long label_len, option_len;
> +	unsigned long label_len;
>  	unsigned long size;
>  	u8 *p;
> 
>  	label_len = (u16_strlen(lo->label) + 1) * sizeof(u16);
> -	option_len = strlen((char *)lo->optional_data);
> 
>  	/* total size */
>  	size = sizeof(lo->attributes);
>  	size += sizeof(lo->file_path_length);
>  	size += label_len;
>  	size += lo->file_path_length;
> -	size += option_len + 1;
> +	if (lo->optional_data)
> +		size += (utf8_utf16_strlen((const char *)lo->optional_data)
> +					   + 1) * sizeof(u16);
>  	p = malloc(size);
>  	if (!p)
>  		return 0;
> @@ -84,10 +85,10 @@ unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data)
>  	memcpy(p, lo->file_path, lo->file_path_length);
>  	p += lo->file_path_length;
> 
> -	memcpy(p, lo->optional_data, option_len);
> -	p += option_len;
> -	*(char *)p = '\0';
> -
> +	if (lo->optional_data) {
> +		utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data);
> +		p += sizeof(u16); /* size of trailing \0 */
> +	}
>  	return size;
>  }
> 
> --
> 2.20.1
> 

  reply	other threads:[~2019-05-07  1:53 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-30  6:11 [U-Boot] [PATCH v2 1/1] efi_loader: optional data in load options are binary Heinrich Schuchardt
2019-05-07  1:53 ` Takahiro Akashi [this message]
2019-05-07  5:16   ` Heinrich Schuchardt
2019-05-07  6:04     ` Heinrich Schuchardt
2019-05-07  6:16       ` Takahiro Akashi
2019-05-07  7:12         ` Heinrich Schuchardt
2019-05-07  7:30           ` Takahiro Akashi
2019-05-07  9:47             ` Graf, Alexander
2019-05-07 16:54             ` Heinrich Schuchardt
2019-05-07 23:56               ` Takahiro Akashi
2019-05-08  0:50                 ` Heinrich Schuchardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190507015308.GA11160@linaro.org \
    --to=takahiro.akashi@linaro.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox