From 12401a5c63f980b0f21e5633a9369832e2f80623 Mon Sep 17 00:00:00 2001 From: imp Date: Fri, 26 Oct 2018 22:13:40 +0000 Subject: [PATCH] Implenent --fromfile to read variable values when printing variables So ./efivar --fromfile Boot0001.bin --print --load-option will take the value from Boot0001.bin file and then decode it as if it were a load-option. This is useful for debugging handling of such variables that may be hanging the boot for some people. Sponsored by: Netflix, Inc --- usr.sbin/efivar/efivar.8 | 13 +++++++++++-- usr.sbin/efivar/efivar.c | 38 +++++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/usr.sbin/efivar/efivar.8 b/usr.sbin/efivar/efivar.8 index 07c7366e7de..7113ba931e4 100644 --- a/usr.sbin/efivar/efivar.8 +++ b/usr.sbin/efivar/efivar.8 @@ -86,8 +86,17 @@ This flag implies .Fl -write unless the .Fl -append -flag is given. -This behavior is not well understood and is currently unimplemented. +or +.Fl -print +flags are given. +This behavior is not well understood and is currently unimplemented +for writes. +When +.Fl -print +is specified, the contents of the file are used as the value to +print using any other specified flags. +This is used primarily for testing purposes for more complicated +variable decoding. .It Fl a Fl -append Append the specified value to the UEFI variable rather than replacing it. diff --git a/usr.sbin/efivar/efivar.c b/usr.sbin/efivar/efivar.c index dc4a7b899b1..f278ecd78b6 100644 --- a/usr.sbin/efivar/efivar.c +++ b/usr.sbin/efivar/efivar.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -70,6 +71,7 @@ static struct option longopts[] = { static int aflag, Aflag, bflag, dflag, Dflag, gflag, Hflag, Nflag, lflag, Lflag, Rflag, wflag, pflag, uflag, load_opt_flag; static char *varname; +static char *fromfile; static u_long attrib = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; static void @@ -183,15 +185,31 @@ print_var(efi_guid_t *guid, char *name) uint32_t att; uint8_t *data; size_t datalen; - char *gname; + char *gname = NULL; int rv; - pretty_guid(guid, &gname); - if (pflag) { - rv = efi_get_variable(*guid, name, &data, &datalen, &att); + if (guid) + pretty_guid(guid, &gname); + if (pflag || fromfile) { + if (fromfile) { + int fd; + + fd = open(fromfile, O_RDONLY); + if (fd < 0) + err(1, "open %s", fromfile); + data = malloc(64 * 1024); + if (data == NULL) + err(1, "malloc"); + datalen = read(fd, data, 64 * 1024); + if (datalen <= 0) + err(1, "read"); + close(fd); + } else { + rv = efi_get_variable(*guid, name, &data, &datalen, &att); + if (rv < 0) + err(1, "fetching %s-%s", gname, name); + } - if (rv < 0) - err(1, "%s-%s", gname, name); if (!Nflag) printf("%s-%s\n", gname, name); @@ -310,6 +328,9 @@ parse_args(int argc, char **argv) wflag++; break; case 'f': + free(fromfile); + fromfile = strdup(optarg); + break; case 0: errx(1, "unknown or unimplemented option\n"); break; @@ -343,7 +364,10 @@ parse_args(int argc, char **argv) write_variable(varname, NULL); else if (Lflag) print_known_guid(); - else if (varname) { + else if (fromfile) { + Nflag = 1; + print_var(NULL, NULL); + } else if (varname) { pflag++; print_variable(varname); } else if (argc > 0) { -- 2.45.0