From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a48mM-0003Rn-4Y for mharc-grub-devel@gnu.org; Wed, 02 Dec 2015 09:53:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37222) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a48mF-0003P9-CS for grub-devel@gnu.org; Wed, 02 Dec 2015 09:53:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a48mA-000092-Ng for grub-devel@gnu.org; Wed, 02 Dec 2015 09:53:03 -0500 Received: from mail-yk0-x22f.google.com ([2607:f8b0:4002:c07::22f]:35015) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a48mA-00008l-IZ for grub-devel@gnu.org; Wed, 02 Dec 2015 09:52:58 -0500 Received: by ykba77 with SMTP id a77so48803126ykb.2 for ; Wed, 02 Dec 2015 06:52:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloudflare.com; s=google; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; bh=J9Utu2EqPAW6aq87vueFO58Z7wsnvu3A/YXidWX26Cw=; b=S9EBm1xo63c7GuiXEpE3rfbQ8dj9JB65Zkuue9cLyN6ZxvCwbtofwnpqLMVJE2HsWy epG0dUSZMgBBqm2LdoOltH7ghH0lvLe3QoKlIa3v4VQGYvBvtMJqkqNfXyZPXbZcOSz3 MV6ASpVtJbajOLBMVHyCT7Ar/pEtMreXK+gNk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:content-type:content-transfer-encoding; bh=J9Utu2EqPAW6aq87vueFO58Z7wsnvu3A/YXidWX26Cw=; b=EXjimJoptoCKqCJqHSL/qUDAsKS+O6L+Z/W74gGUtdkesYKEqc7U7dJ6hCrjra/1+E TxdcvxypXoru/CeeIDqOECQdch+ljT7AdaM7SbEXxnVG+5+hxoKlExfhRsuZijFWNT+4 8PEXUDCN9bWUGbl7QFZUFTKOSYeH8ewidEGwn8AL5gwpZ/+FPypo6Ot5vdL79/WaIy3J HD9iDbEbD2sdGPUyb5rtjgiufUzhloYdvbqB4rvuJtF1B02NnDHMjm0boLxo4UNgc9Hy uB1cknoIxQx3oyUoxkCQTefF86y1/z+r1/pPNI5p99rs7/s/tVDnlaOM5xDckYclOtx2 H6xQ== X-Gm-Message-State: ALoCoQk4T3Pgmw+uPbhSsJwaRmQDEFzimfKZ/mvtjmhWNIPfxq9hZDLG/3AOlIl0RklvgniLntSR MIME-Version: 1.0 X-Received: by 10.129.92.132 with SMTP id q126mr1339119ywb.46.1449067978069; Wed, 02 Dec 2015 06:52:58 -0800 (PST) Received: by 10.129.27.14 with HTTP; Wed, 2 Dec 2015 06:52:57 -0800 (PST) In-Reply-To: References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> <56586384.1030504@gmail.com> <565ABE97.5060109@gmail.com> Date: Wed, 2 Dec 2015 14:52:57 +0000 Message-ID: Subject: Re: Grub get and set efi variables From: Ignat Korchagin To: The development of GNU GRUB Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:4002:c07::22f X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Dec 2015 14:53:08 -0000 OK. Updated patch below: diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 0cc40bb..aa7b927 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -735,6 +735,12 @@ module =3D { }; module =3D { + name =3D efivar; + efi =3D commands/efi/efivar.c; + enable =3D efi; +}; + +module =3D { name =3D blocklist; common =3D commands/blocklist.c; }; diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efiva= r.c new file mode 100644 index 0000000..8acd0c2 --- /dev/null +++ b/grub-core/commands/efi/efivar.c @@ -0,0 +1,238 @@ +/* efivar.c - Read EFI global variables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2015 Free Software Foundation, Inc. + * Copyright (C) 2015 CloudFlare, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static const struct grub_arg_option options[] =3D { + {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR in specific format (hex, uint8, ascii, dump). Default: hex."), N_("FORMAT"), ARG_TYPE_STRING}, + {"set", 's', GRUB_ARG_OPTION_OPTIONAL, N_("Save parsed result to environment variable (does not work with dump)."), N_("ENV_VAR"), ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} +}; + +enum efi_var_type + { + EFI_VAR_ASCII =3D 0, + EFI_VAR_UINT8, + EFI_VAR_HEX, + EFI_VAR_DUMP, + EFI_VAR_INVALID =3D -1 + }; + +static enum efi_var_type +parse_efi_var_type (const char *type) +{ + if (!grub_strncmp (type, "ascii", sizeof("ascii"))) + return EFI_VAR_ASCII; + + if (!grub_strncmp (type, "uint8", sizeof("uint8"))) + return EFI_VAR_UINT8; + + if (!grub_strncmp (type, "hex", sizeof("hex"))) + return EFI_VAR_HEX; + + if (!grub_strncmp (type, "dump", sizeof("dump"))) + return EFI_VAR_DUMP; + + return EFI_VAR_INVALID; +} + +static int +grub_print_ascii (char *str, char c) +{ + if (grub_iscntrl (c)) + { + switch (c) + { + case '\0': + str[0] =3D '\\'; + str[1] =3D '0'; + return 2; + + case '\a': + str[0] =3D '\\'; + str[1] =3D 'a'; + return 2; + + case '\b': + str[0] =3D '\\'; + str[1] =3D 'b'; + return 2; + + case '\f': + str[0] =3D '\\'; + str[1] =3D 'f'; + return 2; + + case '\n': + str[0] =3D '\\'; + str[1] =3D 'n'; + return 2; + + case '\r': + str[0] =3D '\\'; + str[1] =3D 'r'; + return 2; + + case '\t': + str[0] =3D '\\'; + str[1] =3D 't'; + return 2; + + case '\v': + str[0] =3D '\\'; + str[1] =3D 'v'; + return 2; + + default: + str[0] =3D '.'; /* as in hexdump -C */ + return 1; + } + } + + str[0] =3D c; + return 1; +} + +static grub_err_t +grub_cmd_get_efi_var (struct grub_extcmd_context *ctxt, + int argc, char **args) +{ + struct grub_arg_list *state =3D ctxt->state; + grub_err_t status; + void *efi_var =3D NULL; + grub_size_t efi_var_size =3D 0; + enum efi_var_type efi_type =3D EFI_VAR_HEX; + grub_efi_guid_t global =3D GRUB_EFI_GLOBAL_VARIABLE_GUID; + char *env_var =3D NULL; + grub_size_t i; + char *ptr; + + if (1 !=3D argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"))= ; + + if (state[0].set) + efi_type =3D parse_efi_var_type (state[0].arg); + + if (EFI_VAR_INVALID =3D=3D efi_type) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier= ")); + + efi_var =3D grub_efi_get_variable (args[0], &global, &efi_var_size); + if (!efi_var || !efi_var_size) + { + status =3D grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable= ")); + goto err; + } + + switch (efi_type) + { + case EFI_VAR_ASCII: + env_var =3D grub_malloc (efi_var_size * 2 + 1); + if (!env_var) + { + status =3D grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory= ")); + break; + } + + ptr =3D env_var; + + for (i =3D 0; i < efi_var_size; i++) + ptr +=3D grub_print_ascii (ptr, ((const char *)efi_var)[i]); + *ptr =3D '\0'; + break; + + case EFI_VAR_UINT8: + env_var =3D grub_malloc (4); + if (!env_var) + { + status =3D grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory= ")); + break; + } + grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var)); + break; + + case EFI_VAR_HEX: + env_var =3D grub_malloc (efi_var_size * 2 + 1); + if (!env_var) + { + status =3D grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory= ")); + break; + } + for (i =3D 0; i < efi_var_size; i++) + grub_snprintf (env_var + (i * 2), 3, "%02x", ((grub_uint8_t *)efi_var)[i]); + break; + + case EFI_VAR_DUMP: + if (state[1].set) + status =3D grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set variable with dump format specifier")); + else + { + hexdump (0, (char *)efi_var, efi_var_size); + status =3D GRUB_ERR_NONE; + } + break; + + default: + status =3D grub_error (GRUB_ERR_BUG, N_("should not happen (bug in module?)")); + } + + if (efi_type !=3D EFI_VAR_DUMP) + { + if (state[1].set) + status =3D grub_env_set (state[1].arg, env_var); + else + { + grub_printf ("%s\n", (const char *)env_var); + status =3D GRUB_ERR_NONE; + } + } + +err: + + if (env_var) + grub_free (env_var); + + if (efi_var) + grub_free (efi_var); + + return status; +} + +static grub_extcmd_t cmd =3D NULL; + +GRUB_MOD_INIT (efivar) +{ + cmd =3D grub_register_extcmd ("get_efivar", grub_cmd_get_efi_var, 0, N_("[-f FORMAT] [-s ENV_VAR] EFI_VAR"), + N_("Read EFI variable and print it or save its contents to environment variable."), options); +} + +GRUB_MOD_FINI (efivar) +{ + if (cmd) + grub_unregister_extcmd (cmd); +} On Wed, Dec 2, 2015 at 1:05 PM, Vladimir 'phcoder' Serbinenko wrote: > Le 2 d=C3=A9c. 2015 2:01 PM, "Andrei Borzenkov" a = =C3=A9crit : > >> > >> On Wed, Dec 2, 2015 at 3:53 PM, Ignat Korchagin >> wrote: > >> > Let's add utf16 later then (if needed). I also noticed a typo in one > >> > error string in my above patch (it was checking that command receives > >> > one argument, but prints that two arguments expected), so here is the > >> > updated one. > >> > > >> > >> It is much more difficult to remove anything than to add it later. > >> Unless we have use case right now, I'd skip it. > >> > >> > So, finally, should I remove the "raw" parser (as per Vladimir's > >> > request). Personally, I would keep it. It might be useful to modify > >> > the hexdump command, that it can dump the contents of a variable. Then > >> > those pieces will fit together: storing raw value in the variable and > >> > examining it with hexdump cmd. > >> > > >> > >> hexdump does not support showing variable if that is what you mean. By > >> the same logic, unless we have current use case we probably should not > >> add it initially. > >> > > We don't even support storing non-utf8 in a variable. So please skip it > >> _______________________________________________ > >> Grub-devel mailing list > >> Grub-devel@gnu.org > >> https://lists.gnu.org/mailman/listinfo/grub-devel > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel >