From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZthQT-0006qv-2u for mharc-grub-devel@gnu.org; Tue, 03 Nov 2015 14:39:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45806) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZthQQ-0006qS-OR for grub-devel@gnu.org; Tue, 03 Nov 2015 14:39:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZthQP-0008U8-PE for grub-devel@gnu.org; Tue, 03 Nov 2015 14:39:22 -0500 Received: from mail-io0-x22a.google.com ([2607:f8b0:4001:c06::22a]:33790) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZthQP-0008Ty-LD for grub-devel@gnu.org; Tue, 03 Nov 2015 14:39:21 -0500 Received: by iodd200 with SMTP id d200so30327460iod.0 for ; Tue, 03 Nov 2015 11:39:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=yrqlAvmg6jsB+oqtfhn9+fg+zCNkDrM4dAXL60NvfZU=; b=oImwph5NVYJPlaOEigcCP5tvbpSE0yUq39P5Zu+pQae7EH1Ih0i6N6iyp9ZLSxcU2c i2U0cxt+5HJwrYF9pxniWpMCH54FfP1OxYQj/zq5ZgxILinaUzGI/s6iLv+wWpZNcpXP 3kJAp9EcVtvwUhdWtfjJjJVwhoXTq6LQBeu5r0kN6/dvLUQsvH4bFLcuWE0K5kGNgmQM pbSAvNOjr5FsVVG55pPOdSkNPh0CI19XCX7FIGrXNy8sUtEGi/Csl3xHR28v5c1R7D/n wUgSOjSC54kSp/JFchWLVyiypxMX+AnFo9Xvz6jJD343SavR4/Ap32P6mPAeYwiXrA+H JCfw== MIME-Version: 1.0 X-Received: by 10.107.31.138 with SMTP id f132mr30427486iof.84.1446579560953; Tue, 03 Nov 2015 11:39:20 -0800 (PST) Received: by 10.36.51.74 with HTTP; Tue, 3 Nov 2015 11:39:20 -0800 (PST) Date: Tue, 3 Nov 2015 11:39:20 -0800 Message-ID: Subject: Grub get and set efi variables From: Mat Troi To: The development of GNU GRUB Content-Type: multipart/alternative; boundary=001a11409c5adebc840523a80cf4 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4001:c06::22a 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: Tue, 03 Nov 2015 19:39:23 -0000 --001a11409c5adebc840523a80cf4 Content-Type: text/plain; charset=UTF-8 Hi, Searching through google, I see there was an email thread to add a patch for getting and setting efi variable in GRUB2. https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00328.html However, looking at the tree, it doesn't look like this patch was added, am I missing something? Does anyone know if we have command to get/set efi variables in GRUB2? http://git.savannah.gnu.org/gitweb/?p=grub.git;a=tree;f=grub-core/commands/efi;h=005fd2efc9a2eede2a1eb1cab8081c360219107b;hb=HEAD Thanks, Mat --001a11409c5adebc840523a80cf4 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi,

Searching through goo= gle, I see there was an email thread to add a patch for getting and setting= efi variable in GRUB2.
https://lists.gnu.org/archive/html/grub-dev= el/2013-11/msg00328.html

However, looking at the tree, it = doesn't look like this patch was added, am I missing something?=C2=A0 D= oes anyone know if we have command to get/set efi variables in GRUB2?
= http://git.savannah.gnu.org/gitweb/?p=3Dgrub.git;a=3Dtree;f=3Dgrub-core/com= mands/efi;h=3D005fd2efc9a2eede2a1eb1cab8081c360219107b;hb=3DHEAD
Thanks,
Mat
--001a11409c5adebc840523a80cf4-- From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZthwL-00010I-OC for mharc-grub-devel@gnu.org; Tue, 03 Nov 2015 15:12:21 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34766) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZthwI-0000zC-Eg for grub-devel@gnu.org; Tue, 03 Nov 2015 15:12:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZthwH-0001vy-Ea for grub-devel@gnu.org; Tue, 03 Nov 2015 15:12:18 -0500 Received: from mail-ig0-x233.google.com ([2607:f8b0:4001:c05::233]:33366) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZthwH-0001vc-9B for grub-devel@gnu.org; Tue, 03 Nov 2015 15:12:17 -0500 Received: by igvi2 with SMTP id i2so76173564igv.0 for ; Tue, 03 Nov 2015 12:12:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=06fgVJQjo/kelVecqFuAdbs0lVpb+WrGo6aOC4mJBsQ=; b=pqh4fvLc/7UE2fz1kYRAIdBbbsTsmsROhFoR7chkSjwZXW8cmoBYrcSQu2es51zl3J cBl9mFaIe4/1r60huChcORPhmFSx8s4aN+MdmsIC5jO0aUwg5CZHLQYooYZBmN5xgtI4 w2gTE2okMmGYFF/3gQmajcg3ITc2+uSkd0m9GlAkSmQE2cceM3eEtYELBT/uCLZ0DH/9 q5GLkeQFsA17ogBbIiXUcexhBWflyCCtLS6sXutVU4qcChgjXZKWJM8vIzTTxJS+Xu7H 7EbbPbfQ/bTssbEGnmvZm6FDedbY5RNRRoqJBOOywupeWlr26zWubAaNFw2+rEun/MTW yucg== MIME-Version: 1.0 X-Received: by 10.50.142.34 with SMTP id rt2mr18847355igb.40.1446581536518; Tue, 03 Nov 2015 12:12:16 -0800 (PST) Received: by 10.36.0.133 with HTTP; Tue, 3 Nov 2015 12:12:16 -0800 (PST) In-Reply-To: References: Date: Tue, 3 Nov 2015 15:12:16 -0500 Message-ID: Subject: Re: Grub get and set efi variables From: SevenBits To: The development of GNU GRUB Content-Type: multipart/alternative; boundary=001a1130c9de9f77fd0523a8825a X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4001:c05::233 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: Tue, 03 Nov 2015 20:12:19 -0000 --001a1130c9de9f77fd0523a8825a Content-Type: text/plain; charset=UTF-8 On Tuesday, November 3, 2015, Mat Troi wrote: > Hi, > > Searching through google, I see there was an email thread to add a patch > for getting and setting efi variable in GRUB2. > https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00328.html > > However, looking at the tree, it doesn't look like this patch was added, > am I missing something? Does anyone know if we have command to get/set efi > variables in GRUB2? > > > http://git.savannah.gnu.org/gitweb/?p=grub.git;a=tree;f=grub-core/commands/efi;h=005fd2efc9a2eede2a1eb1cab8081c360219107b;hb=HEAD > > I'm the author of that patch. No, it was never merged into the tree. As far as I know, there is no equivalent functionality; GRUB does not support this feature. > Thanks, > Mat > --001a1130c9de9f77fd0523a8825a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Tuesday, November 3, 2015, Mat Troi <mattroisang@gmail.com> wrote:
Hi,

Searching throug= h google, I see there was an email thread to add a patch for getting and se= tting efi variable in GRUB2.
https://lists.gnu.or= g/archive/html/grub-devel/2013-11/msg00328.html

However, l= ooking at the tree, it doesn't look like this patch was added, am I mis= sing something?=C2=A0 Does anyone know if we have command to get/set efi va= riables in GRUB2?

I'm the author of that patch. No, it was n= ever merged into the tree. As far as I know, there is no equivalent functio= nality; GRUB does not support this feature.
=C2=A0
Thanks,
Mat
--001a1130c9de9f77fd0523a8825a-- From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1Ztkdn-0004Gn-Hn for mharc-grub-devel@gnu.org; Tue, 03 Nov 2015 18:05:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35442) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ztkdl-0004GX-IM for grub-devel@gnu.org; Tue, 03 Nov 2015 18:05:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ztkdk-0005w5-IM for grub-devel@gnu.org; Tue, 03 Nov 2015 18:05:21 -0500 Received: from mail-io0-x229.google.com ([2607:f8b0:4001:c06::229]:35664) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ztkdk-0005vm-DD for grub-devel@gnu.org; Tue, 03 Nov 2015 18:05:20 -0500 Received: by iofz202 with SMTP id z202so35731997iof.2 for ; Tue, 03 Nov 2015 15:05:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=SkQXIYKKSjqpEwMzPGmxrYL/qW3vgcZVBQTRYcTMA40=; b=UbgFJtJwbTZCAX+IjSJ99nVScR/ibVBfNwjBTW6bb4QpPDa9HSEc84daZoMLa+80M5 Vf8KRrtTwe4jy0yOjdOvstO68lIN/MgkTQPXVCbBVUc5lLpDV2hEgZv3AN7HDqGIOGIm zrCtpk0Q6rGf4Hw1at6fGi1o602TevFJ9r5y/miSvCwZLHJLhwvSlHGsM21u6ugJsbxy Di1H5WVycV8w6wmY+tnzhGtwO5lE6k7WUvqMvdrsBxVsDPuD77S1czW+gqo7it2UlbyQ 30mKAOurLi5BrGy6vEiiZ1gMTePEFkcooqijG0XOko9/9H3UsBn3/7LM/dgQV0nctEtX biWg== MIME-Version: 1.0 X-Received: by 10.107.3.79 with SMTP id 76mr30544120iod.30.1446591919859; Tue, 03 Nov 2015 15:05:19 -0800 (PST) Received: by 10.36.51.74 with HTTP; Tue, 3 Nov 2015 15:05:19 -0800 (PST) In-Reply-To: References: Date: Tue, 3 Nov 2015 15:05:19 -0800 Message-ID: Subject: Re: Grub get and set efi variables From: Mat Troi To: The development of GNU GRUB Content-Type: multipart/alternative; boundary=001a113ea6c284aff80523aaed48 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4001:c06::229 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: Tue, 03 Nov 2015 23:05:22 -0000 --001a113ea6c284aff80523aaed48 Content-Type: text/plain; charset=UTF-8 Hi SevenBits, Thanks for letting me know. Out of curiosity, any particular reason why this patch did not get merged? It looks to be a useful feature. Thanks, Mat On Tue, Nov 3, 2015 at 12:12 PM, SevenBits wrote: > On Tuesday, November 3, 2015, Mat Troi wrote: > >> Hi, >> >> Searching through google, I see there was an email thread to add a patch >> for getting and setting efi variable in GRUB2. >> https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00328.html >> >> However, looking at the tree, it doesn't look like this patch was added, >> am I missing something? Does anyone know if we have command to get/set efi >> variables in GRUB2? >> >> >> http://git.savannah.gnu.org/gitweb/?p=grub.git;a=tree;f=grub-core/commands/efi;h=005fd2efc9a2eede2a1eb1cab8081c360219107b;hb=HEAD >> >> > I'm the author of that patch. No, it was never merged into the tree. As > far as I know, there is no equivalent functionality; GRUB does not support > this feature. > > >> Thanks, >> Mat >> > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel > > --001a113ea6c284aff80523aaed48 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi SevenBits,

Thanks for letti= ng me know.=C2=A0 Out of curiosity, any particular reason why this patch di= d not get merged?=C2=A0 It looks to be a useful feature.

Thank= s,
Mat

On Tue, Nov 3, 2015 at 12:12 PM, SevenBits <sevenbitstech@gm= ail.com> wrote:
On Tuesday, November 3, 2015, Mat Troi <mattroisang@gmail.com> wrote:
Hi,
Searching through google, I see there was an email thread to add a = patch for getting and setting efi variable in GRUB2.
https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00328.html=

However, looking at the tree, it doesn't look like this p= atch was added, am I missing something?=C2=A0 Does anyone know if we have c= ommand to get/set efi variables in GRUB2?

I'm the aut= hor of that patch. No, it was never merged into the tree. As far as I know,= there is no equivalent functionality; GRUB does not support this feature.<= /div>
=C2=A0
= Thanks,
Mat

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


--001a113ea6c284aff80523aaed48-- From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1Ztqlx-0007D7-4N for mharc-grub-devel@gnu.org; Wed, 04 Nov 2015 00:38:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55109) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ztqlt-0007Bl-RQ for grub-devel@gnu.org; Wed, 04 Nov 2015 00:38:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ztqlo-0004l3-RM for grub-devel@gnu.org; Wed, 04 Nov 2015 00:38:09 -0500 Received: from mail-lb0-x233.google.com ([2a00:1450:4010:c04::233]:34066) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ztqlo-0004ky-Js for grub-devel@gnu.org; Wed, 04 Nov 2015 00:38:04 -0500 Received: by lbbwb3 with SMTP id wb3so7814051lbb.1 for ; Tue, 03 Nov 2015 21:38:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type:content-transfer-encoding; bh=T+fFzuKCt8SWk8SjcWaQ4m5CNjbGYCUmtGSgbLitem4=; b=sr95sCNz3LO6mGYj4DFFvufDLqPWW7cW1OWppG5/dmSDbQaYhm4zcBKXdagd5wi4ZA +kZOwSV8HsHVUprfb9j+ueQVn+FcrjycCWUKl197IpaTD1ouDH52abJ/eDXIIs8oGPXS qV74Ge5fx+0WZmL5Nyi7c082B9FxhRQIVDy2L1XS3CMz8vU6VmnA2nUOtQD50YZ9lvYN 1HyGY0XqznltZbdTubYvbjdoVW6P3wyU0tP6mnsEHgPgPzfQNf8DVlX6fsr5ebzEyL8J 1bgFe5NtOcnHppZ1GsRSj+HDiQVAYwmLlbXpz0zb8GeN+eCQTQ8XzmTpFYaUJfjegRqs cT+g== X-Received: by 10.112.180.230 with SMTP id dr6mr14762609lbc.72.1446615483515; Tue, 03 Nov 2015 21:38:03 -0800 (PST) Received: from [192.168.1.41] (ppp91-76-25-247.pppoe.mtu-net.ru. [91.76.25.247]) by smtp.gmail.com with ESMTPSA id d18sm5415370lfe.44.2015.11.03.21.38.02 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Nov 2015 21:38:02 -0800 (PST) Subject: Re: Grub get and set efi variables To: The development of GNU GRUB References: From: Andrei Borzenkov Message-ID: <563999B9.7020108@gmail.com> Date: Wed, 4 Nov 2015 08:38:01 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4010:c04::233 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, 04 Nov 2015 05:38:11 -0000 04.11.2015 02:05, Mat Troi пишет: > Hi SevenBits, > > Thanks for letting me know. Out of curiosity, any particular reason why > this patch did not get merged? It looks to be a useful feature. > First, this patch was reverse patch :) I am not convinced making it easy to set EFI variable from within GRUB is good thing, because there are known reports about systems rendered unbootable by writing too much into EFI flash. What is your use case that absolutely requires setting EFI variables? How are you going to implement it on other platforms? Reading does not harm and may be useful, but then it should provide generic interface to access arbitrary vendor namespace, not only EFI global variables, and handle arbitrary binary data, even if initial implementation handles only subset of them. Once someone starts to use it changing it will be much more difficult. May be it should take hints how to interpret variable values, or have format option akin to printf. > Thanks, > Mat > > On Tue, Nov 3, 2015 at 12:12 PM, SevenBits wrote: > >> On Tuesday, November 3, 2015, Mat Troi wrote: >> >>> Hi, >>> >>> Searching through google, I see there was an email thread to add a patch >>> for getting and setting efi variable in GRUB2. >>> https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00328.html >>> >>> However, looking at the tree, it doesn't look like this patch was added, >>> am I missing something? Does anyone know if we have command to get/set efi >>> variables in GRUB2? >>> >>> >>> http://git.savannah.gnu.org/gitweb/?p=grub.git;a=tree;f=grub-core/commands/efi;h=005fd2efc9a2eede2a1eb1cab8081c360219107b;hb=HEAD >>> >>> >> I'm the author of that patch. No, it was never merged into the tree. As >> far as I know, there is no equivalent functionality; GRUB does not support >> this feature. >> >> >>> Thanks, >>> Mat >>> >> >> _______________________________________________ >> 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 > From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZuPE1-000662-Rr for mharc-grub-devel@gnu.org; Thu, 05 Nov 2015 13:25:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50888) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZuPDx-0005yU-V5 for grub-devel@gnu.org; Thu, 05 Nov 2015 13:25:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZuPDw-0008Bw-Gz for grub-devel@gnu.org; Thu, 05 Nov 2015 13:25:25 -0500 Received: from mail-io0-x229.google.com ([2607:f8b0:4001:c06::229]:35798) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZuPDw-0008Bp-BQ for grub-devel@gnu.org; Thu, 05 Nov 2015 13:25:24 -0500 Received: by ioc74 with SMTP id 74so33483064ioc.2 for ; Thu, 05 Nov 2015 10:25:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=BR1H94eYspJ1XKAm0ALZjm5zAT6Wd6MTW5KqwIbEyA8=; b=Dlrt0YyOKV1f0vkVq/uVLa0EA4kyZvi7oQhUK31mCanU+wBGZ9/6T442iW78IcTJvU CXYpo+z4TN0z/RLEwcgU9RuLTbL8mSHbUfVmB/Egl9yb6kwHQeFiHbC2zSY5Sm0K5cZH lt4P2aFQDVmT2ePbGq5jJsgLmU/aVbMChmYlvyu2kuLkmbQvRiK7qaXHpyaKV6UW+TbR EI/Krg56GGvwo7nxopnsIE3uQNOVSiG9qaAIqEUNuSS7QLXB4VcMI/g3qo62C8jwJgQK yj3pUrqKg0l5ER/cZAQjJ9G7mehBtd56qIte4SPjAHNpcl4MTPNZ8HoyGtI1rSC/dcGN dLCg== MIME-Version: 1.0 X-Received: by 10.107.17.13 with SMTP id z13mr1254267ioi.97.1446747923794; Thu, 05 Nov 2015 10:25:23 -0800 (PST) Received: by 10.36.39.193 with HTTP; Thu, 5 Nov 2015 10:25:23 -0800 (PST) In-Reply-To: <563999B9.7020108@gmail.com> References: <563999B9.7020108@gmail.com> Date: Thu, 5 Nov 2015 13:25:23 -0500 Message-ID: Subject: Re: Grub get and set efi variables From: SevenBits To: The development of GNU GRUB Content-Type: multipart/alternative; boundary=001a113ecf3213cf910523cf406f X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4001:c06::229 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: Thu, 05 Nov 2015 18:25:28 -0000 --001a113ecf3213cf910523cf406f Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Wednesday, November 4, 2015, Andrei Borzenkov wrote: > 04.11.2015 02:05, Mat Troi =D0=BF=D0=B8=D1=88=D0=B5=D1=82: > >> Hi SevenBits, >> >> Thanks for letting me know. Out of curiosity, any particular reason why >> this patch did not get merged? It looks to be a useful feature. >> >> > First, this patch was reverse patch :) Yeah, I think I had accidentally passed the arguments to the diff command in the wrong order. > > I am not convinced making it easy to set EFI variable from within GRUB is > good thing, because there are known reports about systems rendered > unbootable by writing too much into EFI flash. What is your use case that > absolutely requires setting EFI variables? How are you going to implement > it on other platforms? I should probably note that I wrote this patch for a specific project of mine which required the ability to read UEFI variables. I added in write functionality for good measure because I could. But I agree, this would only encourage tinkering and users messing with their systems and potentially bricking it, which would of course be blamed on GRUB. > > Reading does not harm and may be useful, but then it should provide > generic interface to access arbitrary vendor namespace, not only EFI glob= al > variables, and handle arbitrary binary data, even if initial implementati= on > handles only subset of them. Once someone starts to use it changing it wi= ll > be much more difficult. > > Maybe it should take hints how to interpret variable values, or have > format option akin to printf. I would be happy to resume work on this, and debase it on the current code, if GRUB has a clear need for such functionality. I would prefer to have it be clear what the patch should consist of, though. A key question would be how to e.g. handle arbitrary data stored in variables if it is not something easily represent able like a string. Right now, the patch stores it's value into an environment variable specified by the user. Unless the powers that be think otherwise, I think this is the best way to go. > > Thanks, >> Mat >> >> On Tue, Nov 3, 2015 at 12:12 PM, SevenBits >> wrote: >> >> On Tuesday, November 3, 2015, Mat Troi wrote: >>> >>> Hi, >>>> >>>> Searching through google, I see there was an email thread to add a pat= ch >>>> for getting and setting efi variable in GRUB2. >>>> https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00328.html >>>> >>>> However, looking at the tree, it doesn't look like this patch was adde= d, >>>> am I missing something? Does anyone know if we have command to get/se= t >>>> efi >>>> variables in GRUB2? >>>> >>>> >>>> >>>> http://git.savannah.gnu.org/gitweb/?p=3Dgrub.git;a=3Dtree;f=3Dgrub-cor= e/commands/efi;h=3D005fd2efc9a2eede2a1eb1cab8081c360219107b;hb=3DHEAD >>>> >>>> >>>> I'm the author of that patch. No, it was never merged into the tree. A= s >>> far as I know, there is no equivalent functionality; GRUB does not >>> support >>> this feature. >>> >>> >>> Thanks, >>>> Mat >>>> >>>> >>> _______________________________________________ >>> 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 >> >> > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel > --001a113ecf3213cf910523cf406f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Wednesday, November 4, 2015, Andrei Borzenkov <arvidjaar@gmail.com> wrote:
04.11.2015 02:05, Mat Troi =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
Hi SevenBits,

Thanks for letting me know.=C2=A0 Out of curiosity, any particular reason w= hy
this patch did not get merged?=C2=A0 It looks to be a useful feature.


First, this patch was reverse patch :)

Yeah= , I think I had accidentally passed the arguments to the diff command in th= e wrong order.
=C2=A0

I am not convinced making it easy to set EFI variable from within GRUB is g= ood thing, because there are known reports about systems rendered unbootabl= e by writing too much into EFI flash. What is your use case that absolutely= requires setting EFI variables? How are you going to implement it on other= platforms?

I should probably note that I w= rote this patch for a specific project of mine which required the ability t= o read UEFI variables. I added in write functionality for good measure beca= use I could. But I agree, this would only encourage tinkering and users mes= sing with their systems and potentially bricking it, which would of course = be blamed on GRUB.
=C2=A0

Reading does not harm and may be useful, but then it should provide generic= interface to access arbitrary vendor namespace, not only EFI global variab= les, and handle arbitrary binary data, even if initial implementation handl= es only subset of them. Once someone starts to use it changing it will be m= uch more difficult.

Maybe it should take hints how to interpret variable values, or have format= option akin to printf.

I would be happy to= resume work on this, and debase it on the current code, if GRUB has a clea= r need for such functionality. I would prefer to have it be clear what the = patch should consist of, though.

A key question wo= uld be how to e.g. handle arbitrary data stored in variables if it is not s= omething easily represent able like a string. Right now, the patch stores i= t's value into an environment variable specified by the user. Unless th= e powers that be think otherwise, I think this is the best way to go.
=
=C2=A0

Thanks,
Mat

On Tue, Nov 3, 2015 at 12:12 PM, SevenBits <sevenbitstech@gmail.com> wrote:

On Tuesday, November 3, 2015, Mat Troi <mattroisang@gmail.com>= wrote:

Hi,

Searching through google, I see there was an email thread to add a patch for getting and setting efi variable in GRUB2.
https://lists.gnu.org/archive/html/grub-devel/2013-1= 1/msg00328.html

However, looking at the tree, it doesn't look like this patch was added= ,
am I missing something?=C2=A0 Does anyone know if we have command to get/se= t efi
variables in GRUB2?


http://git.savannah.gnu.org/gitweb/?p=3Dgrub.git;a=3Dtr= ee;f=3Dgrub-core/commands/efi;h=3D005fd2efc9a2eede2a1eb1cab8081c360219107b;= hb=3DHEAD


I'm the author of that patch. No, it was never merged into the tree. As=
far as I know, there is no equivalent functionality; GRUB does not support<= br> this feature.


Thanks,
Mat


_______________________________________________
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



_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
--001a113ecf3213cf910523cf406f-- From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZuWKe-0008Bo-87 for mharc-grub-devel@gnu.org; Thu, 05 Nov 2015 21:00:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55742) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZuWKX-0008Az-Gr for grub-devel@gnu.org; Thu, 05 Nov 2015 21:00:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZuWKV-0007nY-Bl for grub-devel@gnu.org; Thu, 05 Nov 2015 21:00:41 -0500 Received: from mail-yk0-x231.google.com ([2607:f8b0:4002:c07::231]:36436) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZuWKV-0007nU-0t for grub-devel@gnu.org; Thu, 05 Nov 2015 21:00:39 -0500 Received: by ykba4 with SMTP id a4so165710752ykb.3 for ; Thu, 05 Nov 2015 18:00:38 -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=kV7ucqkf+sD9zmiI1GhrHLtlNIeSyzxXjsP9QIVIEck=; b=e/wn08ApnW7Qokabx4sAtVE4GrRX/Jou4NQNIMCxIJImBpjencu9uPHXs4kcy68QzJ zZGMqjC3rUiCkKu/gBwJKXKaXNEg1O0PSPecJoF5T6gBdw+IQX5KGLIF78cPRozormz4 4O2h0bI4BSdVwC+DHB0f6gtah9Qvh4lc/WrNs= 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=kV7ucqkf+sD9zmiI1GhrHLtlNIeSyzxXjsP9QIVIEck=; b=dvoR02lIVgFMIZUCAC3xXmiMcv62JbpYDIGksWylT+fI4bVikTJ1el2ucgjicjtMPw +kCrqHg8SxhgnG3xbU6q4LF/R8YXaQKP5T2wMeP3/PiBeYQ0TDfgZhq/Xa7vL02ulyhV //pM5iaoNXpiHmYXj2IunWGqHKYgFc3f5Z7IxWDtWaciABwqr/RXBBAdJw1U5ZZNmTly Qw91HoDFNzOtwn16F+jhdFWI3y/oVXIdXnIgyzV5ubTHGQ3U/HTMyBknYnLA41YvLekD 394Kr8B+zOaiC3LnLcB671krvq3195jQ+0tub68qkjfLI9POwLV+9G9cRGRuJNTupzIO zFJg== X-Gm-Message-State: ALoCoQkknlTm933QcrHmOiIjw50ctS9AaVsXTJAt2prFFtUz2nv79tssmckeLLBwWb/6kb7FXgem MIME-Version: 1.0 X-Received: by 10.129.72.151 with SMTP id v145mr10657719ywa.330.1446775238158; Thu, 05 Nov 2015 18:00:38 -0800 (PST) Received: by 10.129.113.84 with HTTP; Thu, 5 Nov 2015 18:00:38 -0800 (PST) In-Reply-To: References: <563999B9.7020108@gmail.com> Date: Thu, 5 Nov 2015 18:00:38 -0800 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: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4002:c07::231 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: Fri, 06 Nov 2015 02:00:46 -0000 Actually, I submitted similar patch recently as well. It provides read function for variables and accepts a hint on how to process them. The original patch is here: https://lists.gnu.org/archive/html/grub-devel/2015-09/msg00043.html. Probably, I forgot to enable plain-text mode, so it got there as a binary attachment. I will repeat it here for convenience. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 9764cd2..49fa3ec 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -728,6 +728,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..ca206eb --- /dev/null +++ b/grub-core/commands/efi/efivar.c @@ -0,0 +1,146 @@ +/* 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 + +GRUB_MOD_LICENSE ("GPLv3+"); + +static const struct grub_arg_option options[] =3D { + {"type", 't', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR as specific type (hex, uint8, string). Default: hex."), N_("TYPE"), ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} +}; + +enum efi_var_type + { + EFI_VAR_STRING =3D 0, + EFI_VAR_UINT8, + EFI_VAR_HEX, + EFI_VAR_INVALID =3D -1 + }; + +static enum efi_var_type +parse_efi_var_type (const char *type) +{ + if (!grub_strncmp (type, "string", sizeof("string"))) + return EFI_VAR_STRING; + + if (!grub_strncmp (type, "uint8", sizeof("uint8"))) + return EFI_VAR_UINT8; + + if (!grub_strncmp (type, "hex", sizeof("hex"))) + return EFI_VAR_HEX; + + return EFI_VAR_INVALID; +} + +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; + + if (2 !=3D argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments 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 EFI variable typ= e")); + + 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")= ); + + switch (efi_type) + { + case EFI_VAR_STRING: + env_var =3D grub_malloc (efi_var_size + 1); + if (!env_var) + { + status =3D grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory= ")); + break; + } + grub_memcpy(env_var, efi_var, efi_var_size); + env_var[efi_var_size] =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; + + default: + status =3D grub_error (GRUB_ERR_BUG, N_("should not happen (bug in module?)")); + } + + status =3D grub_env_set (args[1], env_var); + + 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_("[-t TYPE] EFI_VAR ENV_VAR"), + N_("Read EFI variable and put its contents in environment variable."), options); +} + +GRUB_MOD_FINI (efivar) +{ + if (cmd) + grub_unregister_extcmd (cmd); +} On Thu, Nov 5, 2015 at 10:25 AM, SevenBits wrote: > On Wednesday, November 4, 2015, Andrei Borzenkov > wrote: >> >> 04.11.2015 02:05, Mat Troi =D0=BF=D0=B8=D1=88=D0=B5=D1=82: >>> >>> Hi SevenBits, >>> >>> Thanks for letting me know. Out of curiosity, any particular reason wh= y >>> this patch did not get merged? It looks to be a useful feature. >>> >> >> First, this patch was reverse patch :) > > > Yeah, I think I had accidentally passed the arguments to the diff command= in > the wrong order. > >> >> >> I am not convinced making it easy to set EFI variable from within GRUB i= s >> good thing, because there are known reports about systems rendered >> unbootable by writing too much into EFI flash. What is your use case tha= t >> absolutely requires setting EFI variables? How are you going to implemen= t it >> on other platforms? > > > I should probably note that I wrote this patch for a specific project of > mine which required the ability to read UEFI variables. I added in write > functionality for good measure because I could. But I agree, this would o= nly > encourage tinkering and users messing with their systems and potentially > bricking it, which would of course be blamed on GRUB. > >> >> >> Reading does not harm and may be useful, but then it should provide >> generic interface to access arbitrary vendor namespace, not only EFI glo= bal >> variables, and handle arbitrary binary data, even if initial implementat= ion >> handles only subset of them. Once someone starts to use it changing it w= ill >> be much more difficult. >> >> Maybe it should take hints how to interpret variable values, or have >> format option akin to printf. > > > I would be happy to resume work on this, and debase it on the current cod= e, > if GRUB has a clear need for such functionality. I would prefer to have i= t > be clear what the patch should consist of, though. > > A key question would be how to e.g. handle arbitrary data stored in > variables if it is not something easily represent able like a string. Rig= ht > now, the patch stores it's value into an environment variable specified b= y > the user. Unless the powers that be think otherwise, I think this is the > best way to go. > >> >> >>> Thanks, >>> Mat >>> >>> On Tue, Nov 3, 2015 at 12:12 PM, SevenBits >>> wrote: >>> >>>> On Tuesday, November 3, 2015, Mat Troi wrote: >>>> >>>>> Hi, >>>>> >>>>> Searching through google, I see there was an email thread to add a >>>>> patch >>>>> for getting and setting efi variable in GRUB2. >>>>> https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00328.html >>>>> >>>>> However, looking at the tree, it doesn't look like this patch was >>>>> added, >>>>> am I missing something? Does anyone know if we have command to get/s= et >>>>> efi >>>>> variables in GRUB2? >>>>> >>>>> >>>>> >>>>> http://git.savannah.gnu.org/gitweb/?p=3Dgrub.git;a=3Dtree;f=3Dgrub-co= re/commands/efi;h=3D005fd2efc9a2eede2a1eb1cab8081c360219107b;hb=3DHEAD >>>>> >>>>> >>>> I'm the author of that patch. No, it was never merged into the tree. A= s >>>> far as I know, there is no equivalent functionality; GRUB does not >>>> support >>>> this feature. >>>> >>>> >>>>> Thanks, >>>>> Mat >>>>> >>>> >>>> _______________________________________________ >>>> 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 >>> >> >> >> _______________________________________________ >> 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 > From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZwZq5-00088a-Bb for mharc-grub-devel@gnu.org; Wed, 11 Nov 2015 13:09:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46870) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZwZq1-00083n-GU for grub-devel@gnu.org; Wed, 11 Nov 2015 13:09:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZwZpy-00087B-6d for grub-devel@gnu.org; Wed, 11 Nov 2015 13:09:41 -0500 Received: from mail-lf0-x22c.google.com ([2a00:1450:4010:c07::22c]:34559) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZwZpx-000871-Ri for grub-devel@gnu.org; Wed, 11 Nov 2015 13:09:38 -0500 Received: by lffu14 with SMTP id u14so20783454lff.1 for ; Wed, 11 Nov 2015 10:09:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type:content-transfer-encoding; bh=avVeKilwDSY1MV7cTJzSXOH1e+/+97qp2zlafkCTcAE=; b=JpvE0NIftPNvYqGfAM/RUTJChA+Pey3ymsYaQD3HrCeJcnH5b/ytr9aq5OwJVekh4u yZ1//afe6Zpd6e6MAitpOkVofJkJi8gsoRlkebAupK/gtNmv5YZw240ydfnUTfuNQGzk F0SoixbbK8duuNCjXCzt1j+TxPOR3t92mqM9jSluhN0DdmLhNYrYiu/0yWNKrPgdfXhE Amll3Z9Rm29dBU0mjm96mO1HJzxZWfPB2/zIJfvKMfhiOQJ7Rc5tNTvosc4G6SKldqYg EL3zZZJGK9ezvarSZ8de1NIrqOLyDLf5fL+EGQP0AgpUibtkqNQJqv4piXZTzryPo9wg X7pg== X-Received: by 10.25.22.214 with SMTP id 83mr5109807lfw.8.1447265376857; Wed, 11 Nov 2015 10:09:36 -0800 (PST) Received: from [192.168.1.41] (ppp91-76-25-247.pppoe.mtu-net.ru. [91.76.25.247]) by smtp.gmail.com with ESMTPSA id o199sm1651480lfa.12.2015.11.11.10.09.35 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Nov 2015 10:09:35 -0800 (PST) Subject: Re: Grub get and set efi variables To: The development of GNU GRUB References: <563999B9.7020108@gmail.com> From: Andrei Borzenkov Message-ID: <5643845E.9060204@gmail.com> Date: Wed, 11 Nov 2015 21:09:34 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4010:c07::22c 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, 11 Nov 2015 18:09:43 -0000 06.11.2015 05:00, Ignat Korchagin пишет: > Actually, I submitted similar patch recently as well. It provides read > function for variables and accepts a hint on how to process them. The > original patch is here: > https://lists.gnu.org/archive/html/grub-devel/2015-09/msg00043.html. > Yes, I was intending to comment on it, sorry. I am still unsure whether printf-like format specifier could be more flexible, but otherwise I like it in that it provides for future extensions. see comments below. > Probably, I forgot to enable plain-text mode, so it got there as a > binary attachment. I will repeat it here for convenience. > > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def > index 9764cd2..49fa3ec 100644 > --- a/grub-core/Makefile.core.def > +++ b/grub-core/Makefile.core.def > @@ -728,6 +728,12 @@ module = { > }; > > module = { > + name = efivar; > + efi = commands/efi/efivar.c; > + enable = efi; > +}; > + > +module = { > name = blocklist; > common = commands/blocklist.c; > }; > diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.c > new file mode 100644 > index 0000000..ca206eb > --- /dev/null > +++ b/grub-core/commands/efi/efivar.c > @@ -0,0 +1,146 @@ > +/* 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 > + > +GRUB_MOD_LICENSE ("GPLv3+"); > + > +static const struct grub_arg_option options[] = { > + {"type", 't', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR as > specific type (hex, uint8, string). Default: hex."), N_("TYPE"), > ARG_TYPE_STRING}, > + {0, 0, 0, 0, 0, 0} > +}; > + > +enum efi_var_type > + { > + EFI_VAR_STRING = 0, > + EFI_VAR_UINT8, > + EFI_VAR_HEX, > + EFI_VAR_INVALID = -1 > + }; > + > +static enum efi_var_type > +parse_efi_var_type (const char *type) > +{ > + if (!grub_strncmp (type, "string", sizeof("string"))) > + return EFI_VAR_STRING; > + I think this should be "ascii" or "utf8". "string" is too ambiguous in UEFI environment, it can also mean sequence of UCS-2 characters. > + if (!grub_strncmp (type, "uint8", sizeof("uint8"))) > + return EFI_VAR_UINT8; > + > + if (!grub_strncmp (type, "hex", sizeof("hex"))) > + return EFI_VAR_HEX; > + > + return EFI_VAR_INVALID; > +} > + > +static grub_err_t > +grub_cmd_get_efi_var (struct grub_extcmd_context *ctxt, > + int argc, char **args) > +{ > + struct grub_arg_list *state = ctxt->state; > + grub_err_t status; > + void *efi_var = NULL; > + grub_size_t efi_var_size = 0; > + enum efi_var_type efi_type = EFI_VAR_HEX; > + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; > + char *env_var = NULL; > + grub_size_t i; > + > + if (2 != argc) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); > + May be follow the suite and use "--set var". It could be useful to simply display variable on screen, like efivar OsIndicators or even efivar --all > + if (state[0].set) > + efi_type = parse_efi_var_type (state[0].arg); > + > + if (EFI_VAR_INVALID == efi_type) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid EFI variable type")); > + > + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); > + if (!efi_var || !efi_var_size) > + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); > + Should it distinguish between non-existent variable and failure to read variable? Is non-existent variable an error? > + switch (efi_type) > + { > + case EFI_VAR_STRING: > + env_var = grub_malloc (efi_var_size + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + break; > + } > + grub_memcpy(env_var, efi_var, efi_var_size); > + env_var[efi_var_size] = '\0'; > + break; > + > + case EFI_VAR_UINT8: > + env_var = grub_malloc (4); > + if (!env_var) > + { > + status = 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 = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + break; > + } > + for (i = 0; i < efi_var_size; i++) > + grub_snprintf (env_var + (i * 2), 3, "%02x", ((grub_uint8_t > *)efi_var)[i]); > + break; > + > + default: > + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug > in module?)")); > + } > + > + status = grub_env_set (args[1], env_var); > + > + if (env_var) > + grub_free (env_var); > + > + if (efi_var) > + grub_free (efi_var); > + > + return status; > +} > + > +static grub_extcmd_t cmd = NULL; > + > +GRUB_MOD_INIT (efivar) > +{ > + cmd = grub_register_extcmd ("get_efivar", grub_cmd_get_efi_var, 0, > N_("[-t TYPE] EFI_VAR ENV_VAR"), > + N_("Read EFI variable and put its contents in environment > variable."), options); > +} > + > +GRUB_MOD_FINI (efivar) > +{ > + if (cmd) > + grub_unregister_extcmd (cmd); > +} > > > On Thu, Nov 5, 2015 at 10:25 AM, SevenBits wrote: >> On Wednesday, November 4, 2015, Andrei Borzenkov >> wrote: >>> >>> 04.11.2015 02:05, Mat Troi пишет: >>>> >>>> Hi SevenBits, >>>> >>>> Thanks for letting me know. Out of curiosity, any particular reason why >>>> this patch did not get merged? It looks to be a useful feature. >>>> >>> >>> First, this patch was reverse patch :) >> >> >> Yeah, I think I had accidentally passed the arguments to the diff command in >> the wrong order. >> >>> >>> >>> I am not convinced making it easy to set EFI variable from within GRUB is >>> good thing, because there are known reports about systems rendered >>> unbootable by writing too much into EFI flash. What is your use case that >>> absolutely requires setting EFI variables? How are you going to implement it >>> on other platforms? >> >> >> I should probably note that I wrote this patch for a specific project of >> mine which required the ability to read UEFI variables. I added in write >> functionality for good measure because I could. But I agree, this would only >> encourage tinkering and users messing with their systems and potentially >> bricking it, which would of course be blamed on GRUB. >> >>> >>> >>> Reading does not harm and may be useful, but then it should provide >>> generic interface to access arbitrary vendor namespace, not only EFI global >>> variables, and handle arbitrary binary data, even if initial implementation >>> handles only subset of them. Once someone starts to use it changing it will >>> be much more difficult. >>> >>> Maybe it should take hints how to interpret variable values, or have >>> format option akin to printf. >> >> >> I would be happy to resume work on this, and debase it on the current code, >> if GRUB has a clear need for such functionality. I would prefer to have it >> be clear what the patch should consist of, though. >> >> A key question would be how to e.g. handle arbitrary data stored in >> variables if it is not something easily represent able like a string. Right >> now, the patch stores it's value into an environment variable specified by >> the user. Unless the powers that be think otherwise, I think this is the >> best way to go. >> >>> >>> >>>> Thanks, >>>> Mat >>>> >>>> On Tue, Nov 3, 2015 at 12:12 PM, SevenBits >>>> wrote: >>>> >>>>> On Tuesday, November 3, 2015, Mat Troi wrote: >>>>> >>>>>> Hi, >>>>>> >>>>>> Searching through google, I see there was an email thread to add a >>>>>> patch >>>>>> for getting and setting efi variable in GRUB2. >>>>>> https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00328.html >>>>>> >>>>>> However, looking at the tree, it doesn't look like this patch was >>>>>> added, >>>>>> am I missing something? Does anyone know if we have command to get/set >>>>>> efi >>>>>> variables in GRUB2? >>>>>> >>>>>> >>>>>> >>>>>> http://git.savannah.gnu.org/gitweb/?p=grub.git;a=tree;f=grub-core/commands/efi;h=005fd2efc9a2eede2a1eb1cab8081c360219107b;hb=HEAD >>>>>> >>>>>> >>>>> I'm the author of that patch. No, it was never merged into the tree. As >>>>> far as I know, there is no equivalent functionality; GRUB does not >>>>> support >>>>> this feature. >>>>> >>>>> >>>>>> Thanks, >>>>>> Mat >>>>>> >>>>> >>>>> _______________________________________________ >>>>> 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 >>>> >>> >>> >>> _______________________________________________ >>> 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 >> > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel > From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZxK6w-0007MU-6m for mharc-grub-devel@gnu.org; Fri, 13 Nov 2015 14:34:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57580) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZxK6s-0007Kj-6R for grub-devel@gnu.org; Fri, 13 Nov 2015 14:34:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZxK6q-0001mB-EU for grub-devel@gnu.org; Fri, 13 Nov 2015 14:34:10 -0500 Received: from mail-yk0-x22f.google.com ([2607:f8b0:4002:c07::22f]:35023) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZxK6q-0001m7-8b for grub-devel@gnu.org; Fri, 13 Nov 2015 14:34:08 -0500 Received: by ykba77 with SMTP id a77so163876183ykb.2 for ; Fri, 13 Nov 2015 11:34:07 -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=daS0vfrcyvCH4n/j+xU1ZE4mXnEC8+XspSh9Yhym2NI=; b=KBGQnMAua+C+kb0rRw6eCQkYuRZdrdqRWhemrRnNgZJlRdi/7pL0dViiynuIPEDh0i Mr/dlGXhVdSssfvnMOsUFYe3M+eKhltridxn0CXCYjh/xBpBtd9KdN3l5nubuEECTX1d hcbzwVWSxXH2uMvriEl2m+2rkgVoGPxLsEais= 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=daS0vfrcyvCH4n/j+xU1ZE4mXnEC8+XspSh9Yhym2NI=; b=AMCRDWcRSM3xDaVWbPk1WQkh3LWPhaOFAFASJivULaZmot3OAWCFnuO+ZKtWDCAJXO 9v4XtGUVvIq7uI8To0Fx34sC25thLhCkOjhjKGbV4PTZ4DtH1g83fDPDTtXhxsimZ/Ya kIchDSZsSe6YekmNNXC16KGLIppELBbBc5yMe2IjzZTaklQEapTpB4UE8Pb7kaSiSGhQ i5mxkJiVffbASvkqfMVdXi3lFN3NWgYFdaWlhTGjXV/q2XASEhcMz4u/ISKvtX1p8QqS rl0hPeGS9nacd+yea3uswOOXesv3UeD/b9vZ0/LSlFz2oskczA/qBOSwAzLuZx5W3x/U aUMw== X-Gm-Message-State: ALoCoQlZR8fodygjWL9yAZ8+FQB2JozUKhGmXHwdDw+0axrxqPHEVjOa5G/Io6GFxCeC+zSlR59+ MIME-Version: 1.0 X-Received: by 10.129.10.214 with SMTP id 205mr23755705ywk.7.1447443247517; Fri, 13 Nov 2015 11:34:07 -0800 (PST) Received: by 10.129.113.84 with HTTP; Fri, 13 Nov 2015 11:34:07 -0800 (PST) In-Reply-To: <5643845E.9060204@gmail.com> References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> Date: Fri, 13 Nov 2015 11:34:07 -0800 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: Error: Malformed IPv6 address (bad octet value). 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: Fri, 13 Nov 2015 19:34:12 -0000 On Wed, Nov 11, 2015 at 10:09 AM, Andrei Borzenkov wr= ote: > 06.11.2015 05:00, Ignat Korchagin =D0=BF=D0=B8=D1=88=D0=B5=D1=82: >> >> Actually, I submitted similar patch recently as well. It provides read >> function for variables and accepts a hint on how to process them. The >> original patch is here: >> https://lists.gnu.org/archive/html/grub-devel/2015-09/msg00043.html. >> > > Yes, I was intending to comment on it, sorry. > > I am still unsure whether printf-like format specifier could be more > flexible, but otherwise I like it in that it provides for future extensio= ns. > see comments below. > > >> Probably, I forgot to enable plain-text mode, so it got there as a >> binary attachment. I will repeat it here for convenience. >> >> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def >> index 9764cd2..49fa3ec 100644 >> --- a/grub-core/Makefile.core.def >> +++ b/grub-core/Makefile.core.def >> @@ -728,6 +728,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/efivar.c >> new file mode 100644 >> index 0000000..ca206eb >> --- /dev/null >> +++ b/grub-core/commands/efi/efivar.c >> @@ -0,0 +1,146 @@ >> +/* 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 b= y >> + * 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 >> + >> +GRUB_MOD_LICENSE ("GPLv3+"); >> + >> +static const struct grub_arg_option options[] =3D { >> + {"type", 't', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR as >> specific type (hex, uint8, string). Default: hex."), N_("TYPE"), >> ARG_TYPE_STRING}, >> + {0, 0, 0, 0, 0, 0} >> +}; >> + >> +enum efi_var_type >> + { >> + EFI_VAR_STRING =3D 0, >> + EFI_VAR_UINT8, >> + EFI_VAR_HEX, >> + EFI_VAR_INVALID =3D -1 >> + }; >> + >> +static enum efi_var_type >> +parse_efi_var_type (const char *type) >> +{ >> + if (!grub_strncmp (type, "string", sizeof("string"))) >> + return EFI_VAR_STRING; >> + > > > I think this should be "ascii" or "utf8". "string" is too ambiguous in UE= FI > environment, it can also mean sequence of UCS-2 characters. I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" when printing. Maybe, to avoid confusion, it might be better to completely remove this option. Basically, you do not want to interpret raw buffers as strings. For best compatibility "hex" mode should be promoted, I guess. What do you think? > >> + if (!grub_strncmp (type, "uint8", sizeof("uint8"))) >> + return EFI_VAR_UINT8; >> + >> + if (!grub_strncmp (type, "hex", sizeof("hex"))) >> + return EFI_VAR_HEX; >> + >> + return EFI_VAR_INVALID; >> +} >> + >> +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; >> + >> + if (2 !=3D argc) >> + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments >> expected")); >> + > > > May be follow the suite and use "--set var". It could be useful to simply > display variable on screen, like > > efivar OsIndicators > > or even > > efivar --all > Yes. Agree. >> + 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 EFI variable >> type")); >> + >> + 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")); >> + > > > Should it distinguish between non-existent variable and failure to read > variable? Is non-existent variable an error? > > grub_efi_get_variable itself does not report the difference. It should be modified to do that. From possible use-cases does it really matter why you did not get the variable? >> + switch (efi_type) >> + { >> + case EFI_VAR_STRING: >> + env_var =3D grub_malloc (efi_var_size + 1); >> + if (!env_var) >> + { >> + status =3D grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of >> memory")); >> + break; >> + } >> + grub_memcpy(env_var, efi_var, efi_var_size); >> + env_var[efi_var_size] =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; >> + >> + default: >> + status =3D grub_error (GRUB_ERR_BUG, N_("should not happen (bug >> in module?)")); >> + } >> + >> + status =3D grub_env_set (args[1], env_var); >> + >> + 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_("[-t TYPE] EFI_VAR ENV_VAR"), >> + N_("Read EFI variable and put its contents in environment >> variable."), options); >> +} >> + >> +GRUB_MOD_FINI (efivar) >> +{ >> + if (cmd) >> + grub_unregister_extcmd (cmd); >> +} >> >> >> On Thu, Nov 5, 2015 at 10:25 AM, SevenBits >> wrote: >>> >>> On Wednesday, November 4, 2015, Andrei Borzenkov >>> wrote: >>>> >>>> >>>> 04.11.2015 02:05, Mat Troi =D0=BF=D0=B8=D1=88=D0=B5=D1=82: >>>>> >>>>> >>>>> Hi SevenBits, >>>>> >>>>> Thanks for letting me know. Out of curiosity, any particular reason >>>>> why >>>>> this patch did not get merged? It looks to be a useful feature. >>>>> >>>> >>>> First, this patch was reverse patch :) >>> >>> >>> >>> Yeah, I think I had accidentally passed the arguments to the diff comma= nd >>> in >>> the wrong order. >>> >>>> >>>> >>>> I am not convinced making it easy to set EFI variable from within GRUB >>>> is >>>> good thing, because there are known reports about systems rendered >>>> unbootable by writing too much into EFI flash. What is your use case >>>> that >>>> absolutely requires setting EFI variables? How are you going to >>>> implement it >>>> on other platforms? >>> >>> >>> >>> I should probably note that I wrote this patch for a specific project o= f >>> mine which required the ability to read UEFI variables. I added in writ= e >>> functionality for good measure because I could. But I agree, this would >>> only >>> encourage tinkering and users messing with their systems and potentiall= y >>> bricking it, which would of course be blamed on GRUB. >>> >>>> >>>> >>>> Reading does not harm and may be useful, but then it should provide >>>> generic interface to access arbitrary vendor namespace, not only EFI >>>> global >>>> variables, and handle arbitrary binary data, even if initial >>>> implementation >>>> handles only subset of them. Once someone starts to use it changing it >>>> will >>>> be much more difficult. >>>> >>>> Maybe it should take hints how to interpret variable values, or have >>>> format option akin to printf. >>> >>> >>> >>> I would be happy to resume work on this, and debase it on the current >>> code, >>> if GRUB has a clear need for such functionality. I would prefer to have >>> it >>> be clear what the patch should consist of, though. >>> >>> A key question would be how to e.g. handle arbitrary data stored in >>> variables if it is not something easily represent able like a string. >>> Right >>> now, the patch stores it's value into an environment variable specified >>> by >>> the user. Unless the powers that be think otherwise, I think this is th= e >>> best way to go. >>> >>>> >>>> >>>>> Thanks, >>>>> Mat >>>>> >>>>> On Tue, Nov 3, 2015 at 12:12 PM, SevenBits >>>>> wrote: >>>>> >>>>>> On Tuesday, November 3, 2015, Mat Troi wrote= : >>>>>> >>>>>>> Hi, >>>>>>> >>>>>>> Searching through google, I see there was an email thread to add a >>>>>>> patch >>>>>>> for getting and setting efi variable in GRUB2. >>>>>>> https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00328.html >>>>>>> >>>>>>> However, looking at the tree, it doesn't look like this patch was >>>>>>> added, >>>>>>> am I missing something? Does anyone know if we have command to >>>>>>> get/set >>>>>>> efi >>>>>>> variables in GRUB2? >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> http://git.savannah.gnu.org/gitweb/?p=3Dgrub.git;a=3Dtree;f=3Dgrub-= core/commands/efi;h=3D005fd2efc9a2eede2a1eb1cab8081c360219107b;hb=3DHEAD >>>>>>> >>>>>>> >>>>>> I'm the author of that patch. No, it was never merged into the tree. >>>>>> As >>>>>> far as I know, there is no equivalent functionality; GRUB does not >>>>>> support >>>>>> this feature. >>>>>> >>>>>> >>>>>>> Thanks, >>>>>>> Mat >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> 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 >>>>> >>>> >>>> >>>> _______________________________________________ >>>> 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 >>> >> >> _______________________________________________ >> 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 From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZxKFQ-0005Ag-IH for mharc-grub-devel@gnu.org; Fri, 13 Nov 2015 14:43:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59668) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZxKFM-00058E-OG for grub-devel@gnu.org; Fri, 13 Nov 2015 14:42:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZxKFK-0004YQ-Tr for grub-devel@gnu.org; Fri, 13 Nov 2015 14:42:56 -0500 Received: from mail-yk0-x22b.google.com ([2607:f8b0:4002:c07::22b]:34753) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZxKFK-0004YM-OI for grub-devel@gnu.org; Fri, 13 Nov 2015 14:42:54 -0500 Received: by ykfs79 with SMTP id s79so165146381ykf.1 for ; Fri, 13 Nov 2015 11:42:54 -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=+HkRzFaZ3fuvecMXJPbhoaT7l9mrxrpTMHKYd48Nj/A=; b=jl2teypwrfMEXgiZNP7bCC//vIlrmmCvkwXLXZZkYPcccNoQL5EdJG641+LfeCLZ2L v7HlmF5qVm1LBCUOHntb4EsTrStiuFHxMC5xgmAfjN5tX+Y4NdrtAIpB291k8uOOM+93 R9FQqaMZFX9NBitgznvmQpAsKim6kNIXNFQPE= 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=+HkRzFaZ3fuvecMXJPbhoaT7l9mrxrpTMHKYd48Nj/A=; b=ELIP/U9MqSoJgKvWWGK+/xKD3x3JRbIxW+x22nuYcBdAvapL/siBsnvCv4NDuK4RER 08NpBrLFCq2kUKEq3fG2RM9aHoKwfG04HIjuQHQ06kNP15ySvcRFr2r9lARa2yVuecS3 PGSc/ajjaFwMUA8xVk8GtrOrFrtpJL54W3+1o8i1FXJ6sEIE24ocrLvCELuh2mwgHw9o oaQeTJ1E2NdC5rUUFvCQkyGKv6wcVDDKZWdiBZE9xOB/i+mrW+BfK6zXuTfkuaWV8dz+ v7ql+1KYMNzdu4Yy8yYhcLQYKwaIbXK346JTMmgd+vDBzasRbtGIn46OJ/VvWXYW9DGt Y89A== X-Gm-Message-State: ALoCoQkvOHbwixc+Lj83whgVfXChJXZwkw2KFjGBmFCe+lVJ8UwA5g7sx+3Merabn0kcPCcon7d7 MIME-Version: 1.0 X-Received: by 10.13.226.142 with SMTP id l136mr23949744ywe.313.1447443774309; Fri, 13 Nov 2015 11:42:54 -0800 (PST) Received: by 10.129.113.84 with HTTP; Fri, 13 Nov 2015 11:42:54 -0800 (PST) In-Reply-To: References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> Date: Fri, 13 Nov 2015 11:42:54 -0800 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: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4002:c07::22b 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: Fri, 13 Nov 2015 19:42:58 -0000 On Fri, Nov 13, 2015 at 11:34 AM, Ignat Korchagin wr= ote: > On Wed, Nov 11, 2015 at 10:09 AM, Andrei Borzenkov = wrote: >> 06.11.2015 05:00, Ignat Korchagin =D0=BF=D0=B8=D1=88=D0=B5=D1=82: >>> >>> Actually, I submitted similar patch recently as well. It provides read >>> function for variables and accepts a hint on how to process them. The >>> original patch is here: >>> https://lists.gnu.org/archive/html/grub-devel/2015-09/msg00043.html. >>> >> >> Yes, I was intending to comment on it, sorry. >> >> I am still unsure whether printf-like format specifier could be more >> flexible, but otherwise I like it in that it provides for future extensi= ons. >> see comments below. >> >> >>> Probably, I forgot to enable plain-text mode, so it got there as a >>> binary attachment. I will repeat it here for convenience. >>> >>> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def >>> index 9764cd2..49fa3ec 100644 >>> --- a/grub-core/Makefile.core.def >>> +++ b/grub-core/Makefile.core.def >>> @@ -728,6 +728,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/efivar.c >>> new file mode 100644 >>> index 0000000..ca206eb >>> --- /dev/null >>> +++ b/grub-core/commands/efi/efivar.c >>> @@ -0,0 +1,146 @@ >>> +/* 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 >>> + >>> +GRUB_MOD_LICENSE ("GPLv3+"); >>> + >>> +static const struct grub_arg_option options[] =3D { >>> + {"type", 't', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR as >>> specific type (hex, uint8, string). Default: hex."), N_("TYPE"), >>> ARG_TYPE_STRING}, >>> + {0, 0, 0, 0, 0, 0} >>> +}; >>> + >>> +enum efi_var_type >>> + { >>> + EFI_VAR_STRING =3D 0, >>> + EFI_VAR_UINT8, >>> + EFI_VAR_HEX, >>> + EFI_VAR_INVALID =3D -1 >>> + }; >>> + >>> +static enum efi_var_type >>> +parse_efi_var_type (const char *type) >>> +{ >>> + if (!grub_strncmp (type, "string", sizeof("string"))) >>> + return EFI_VAR_STRING; >>> + >> >> >> I think this should be "ascii" or "utf8". "string" is too ambiguous in U= EFI >> environment, it can also mean sequence of UCS-2 characters. > I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" > when printing. Maybe, to avoid confusion, it might be better to > completely remove this option. Basically, you do not want to interpret > raw buffers as strings. For best compatibility "hex" mode should be > promoted, I guess. What do you think? Checked again the UEFI spec. For globally defined variables which are strings they specify ASCII. So if we leave this option, ascii is the best name. >> >>> + if (!grub_strncmp (type, "uint8", sizeof("uint8"))) >>> + return EFI_VAR_UINT8; >>> + >>> + if (!grub_strncmp (type, "hex", sizeof("hex"))) >>> + return EFI_VAR_HEX; >>> + >>> + return EFI_VAR_INVALID; >>> +} >>> + >>> +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; >>> + >>> + if (2 !=3D argc) >>> + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments >>> expected")); >>> + >> >> >> May be follow the suite and use "--set var". It could be useful to simpl= y >> display variable on screen, like >> >> efivar OsIndicators >> >> or even >> >> efivar --all >> > Yes. Agree. >>> + 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 EFI variable >>> type")); >>> + >>> + 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")); >>> + >> >> >> Should it distinguish between non-existent variable and failure to read >> variable? Is non-existent variable an error? >> >> > grub_efi_get_variable itself does not report the difference. It should > be modified to do that. From possible use-cases does it really matter > why you did not get the variable? >>> + switch (efi_type) >>> + { >>> + case EFI_VAR_STRING: >>> + env_var =3D grub_malloc (efi_var_size + 1); >>> + if (!env_var) >>> + { >>> + status =3D grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of >>> memory")); >>> + break; >>> + } >>> + grub_memcpy(env_var, efi_var, efi_var_size); >>> + env_var[efi_var_size] =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; >>> + >>> + default: >>> + status =3D grub_error (GRUB_ERR_BUG, N_("should not happen (bug >>> in module?)")); >>> + } >>> + >>> + status =3D grub_env_set (args[1], env_var); >>> + >>> + 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_("[-t TYPE] EFI_VAR ENV_VAR"), >>> + N_("Read EFI variable and put its contents in environment >>> variable."), options); >>> +} >>> + >>> +GRUB_MOD_FINI (efivar) >>> +{ >>> + if (cmd) >>> + grub_unregister_extcmd (cmd); >>> +} >>> >>> >>> On Thu, Nov 5, 2015 at 10:25 AM, SevenBits >>> wrote: >>>> >>>> On Wednesday, November 4, 2015, Andrei Borzenkov >>>> wrote: >>>>> >>>>> >>>>> 04.11.2015 02:05, Mat Troi =D0=BF=D0=B8=D1=88=D0=B5=D1=82: >>>>>> >>>>>> >>>>>> Hi SevenBits, >>>>>> >>>>>> Thanks for letting me know. Out of curiosity, any particular reason >>>>>> why >>>>>> this patch did not get merged? It looks to be a useful feature. >>>>>> >>>>> >>>>> First, this patch was reverse patch :) >>>> >>>> >>>> >>>> Yeah, I think I had accidentally passed the arguments to the diff comm= and >>>> in >>>> the wrong order. >>>> >>>>> >>>>> >>>>> I am not convinced making it easy to set EFI variable from within GRU= B >>>>> is >>>>> good thing, because there are known reports about systems rendered >>>>> unbootable by writing too much into EFI flash. What is your use case >>>>> that >>>>> absolutely requires setting EFI variables? How are you going to >>>>> implement it >>>>> on other platforms? >>>> >>>> >>>> >>>> I should probably note that I wrote this patch for a specific project = of >>>> mine which required the ability to read UEFI variables. I added in wri= te >>>> functionality for good measure because I could. But I agree, this woul= d >>>> only >>>> encourage tinkering and users messing with their systems and potential= ly >>>> bricking it, which would of course be blamed on GRUB. >>>> >>>>> >>>>> >>>>> Reading does not harm and may be useful, but then it should provide >>>>> generic interface to access arbitrary vendor namespace, not only EFI >>>>> global >>>>> variables, and handle arbitrary binary data, even if initial >>>>> implementation >>>>> handles only subset of them. Once someone starts to use it changing i= t >>>>> will >>>>> be much more difficult. >>>>> >>>>> Maybe it should take hints how to interpret variable values, or have >>>>> format option akin to printf. >>>> >>>> >>>> >>>> I would be happy to resume work on this, and debase it on the current >>>> code, >>>> if GRUB has a clear need for such functionality. I would prefer to hav= e >>>> it >>>> be clear what the patch should consist of, though. >>>> >>>> A key question would be how to e.g. handle arbitrary data stored in >>>> variables if it is not something easily represent able like a string. >>>> Right >>>> now, the patch stores it's value into an environment variable specifie= d >>>> by >>>> the user. Unless the powers that be think otherwise, I think this is t= he >>>> best way to go. >>>> >>>>> >>>>> >>>>>> Thanks, >>>>>> Mat >>>>>> >>>>>> On Tue, Nov 3, 2015 at 12:12 PM, SevenBits >>>>>> wrote: >>>>>> >>>>>>> On Tuesday, November 3, 2015, Mat Troi wrot= e: >>>>>>> >>>>>>>> Hi, >>>>>>>> >>>>>>>> Searching through google, I see there was an email thread to add a >>>>>>>> patch >>>>>>>> for getting and setting efi variable in GRUB2. >>>>>>>> https://lists.gnu.org/archive/html/grub-devel/2013-11/msg00328.htm= l >>>>>>>> >>>>>>>> However, looking at the tree, it doesn't look like this patch was >>>>>>>> added, >>>>>>>> am I missing something? Does anyone know if we have command to >>>>>>>> get/set >>>>>>>> efi >>>>>>>> variables in GRUB2? >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> http://git.savannah.gnu.org/gitweb/?p=3Dgrub.git;a=3Dtree;f=3Dgrub= -core/commands/efi;h=3D005fd2efc9a2eede2a1eb1cab8081c360219107b;hb=3DHEAD >>>>>>>> >>>>>>>> >>>>>>> I'm the author of that patch. No, it was never merged into the tree= . >>>>>>> As >>>>>>> far as I know, there is no equivalent functionality; GRUB does not >>>>>>> support >>>>>>> this feature. >>>>>>> >>>>>>> >>>>>>>> Thanks, >>>>>>>> Mat >>>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> 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 >>>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> 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 >>>> >>> >>> _______________________________________________ >>> 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 From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZxS3T-00084s-7s for mharc-grub-devel@gnu.org; Fri, 13 Nov 2015 23:03:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41641) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZxS3R-00084m-Gw for grub-devel@gnu.org; Fri, 13 Nov 2015 23:03:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZxS3M-0008OB-DH for grub-devel@gnu.org; Fri, 13 Nov 2015 23:03:09 -0500 Received: from mail-lf0-x234.google.com ([2a00:1450:4010:c07::234]:36562) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZxS3M-0008O7-6D for grub-devel@gnu.org; Fri, 13 Nov 2015 23:03:04 -0500 Received: by lfs39 with SMTP id 39so62714549lfs.3 for ; Fri, 13 Nov 2015 20:03:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type:content-transfer-encoding; bh=0thehxmpcVZD3o8qX0y50noAmfo2Ci+tx18FOxtWT8A=; b=yiPKmyp/pod6G0LVlCTwxq7DzX6cZ8JbEMGplB0DfJfC0ehREw6sAygdj9Dqxjasxh euigXc6kL+c72X5rowvsFCV+RR+uFIuGD4uXPh4g62pQKyXPknXwmwWRb1gHwIrkoAX+ rhMEAA4gcf0WCHAhR7DErF00BOPnGNtoZGSzTOKZcReKhgFkzHN4ocg/6yhYmUI9ixSf +qgIHH8gdAwWyEdrRf5XX94XF+gO/x812THh+Vq/PGUo8A5W/7Gn4ze/gQTpOQBxDUZz CP5Zz+hO4KxaPb9ix0ZEzYWjS1BgIMvfjHJkgxs8jmyLcm3QxOiL0eBVSTyOdbJSgmaZ Ll7g== X-Received: by 10.25.38.2 with SMTP id m2mr9724818lfm.113.1447473783255; Fri, 13 Nov 2015 20:03:03 -0800 (PST) Received: from [192.168.1.41] (ppp91-76-25-247.pppoe.mtu-net.ru. [91.76.25.247]) by smtp.gmail.com with ESMTPSA id gg8sm3632792lbc.17.2015.11.13.20.03.01 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 13 Nov 2015 20:03:02 -0800 (PST) Subject: Re: Grub get and set efi variables To: grub-devel@gnu.org References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> From: Andrei Borzenkov Message-ID: <5646B275.5040707@gmail.com> Date: Sat, 14 Nov 2015 07:03:01 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4010:c07::234 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: Sat, 14 Nov 2015 04:03:10 -0000 13.11.2015 22:42, Ignat Korchagin пишет: >>>> +static enum efi_var_type >>>> +parse_efi_var_type (const char *type) >>>> +{ >>>> + if (!grub_strncmp (type, "string", sizeof("string"))) >>>> + return EFI_VAR_STRING; >>>> + >>> >>> >>> I think this should be "ascii" or "utf8". "string" is too ambiguous in UEFI >>> environment, it can also mean sequence of UCS-2 characters. >> I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" >> when printing. Maybe, to avoid confusion, it might be better to >> completely remove this option. Basically, you do not want to interpret >> raw buffers as strings. For best compatibility "hex" mode should be >> promoted, I guess. What do you think? > Checked again the UEFI spec. For globally defined variables which are > strings they specify ASCII. So if we leave this option, ascii is the > best name. > What about - ascii - print ASCII characters verbatim, escape non-ASCII in usual way (similar to "od -c") - raw - simply put raw variable without any interpretation. This is better aligned with argument describing output formatting rather than attempting to "type" variable. Alternative (or in addition to) ascii - dump which prints usual pretty hex dump of content (hexdump -C). This is handy to interactively look at variable content. Or, and change name from --type to --format :) From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZyekI-0006lm-5M for mharc-grub-devel@gnu.org; Tue, 17 Nov 2015 06:48:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42445) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZyekF-0006ku-0k for grub-devel@gnu.org; Tue, 17 Nov 2015 06:48:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZyekD-00028E-5o for grub-devel@gnu.org; Tue, 17 Nov 2015 06:48:18 -0500 Received: from mail-yk0-x231.google.com ([2607:f8b0:4002:c07::231]:33463) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZyekC-00027m-WC for grub-devel@gnu.org; Tue, 17 Nov 2015 06:48:17 -0500 Received: by ykdv3 with SMTP id v3so6022820ykd.0 for ; Tue, 17 Nov 2015 03:48:16 -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=uz0+9R6B0sFHHcwd5WABeOYM8dJyvpXrHOt0ckVgUPA=; b=W+b+SUrdnmla9rFPrON2Ch0PJU1T/kmT2ypFvlX9xbKB4fYxWKkuGb2f+DICXW3Q4K lphNhlMx23U3rm3BPrpIuN+c3CLICeD7x2rBkacOItTDSnIOPMIxMK2CQ6O8UvSYgQS1 Lcbx56caAjM68xvXb34FOWc0OPFnF8zX76Mn8= 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=uz0+9R6B0sFHHcwd5WABeOYM8dJyvpXrHOt0ckVgUPA=; b=VoJE15zeIiJRrk4Lr0SWymp+ukW1Yvx1LetES+qIKoR+0Zz218xEsrp+Cf2PdHmA9J IDf2+kZRHUd6l0hZHwSSTHfKtCw/S5Geo5Q2E8YxaI2Y3fWdQboysBP6RIJ5cWeYiViv Vr5iMFEynxMNrMItpu05cZN7MfujicwdN02s6FII6iJ1Kr4/xoGejNEgPQgxk6DMKwmS ox6+kWZDebs42ECCpojHb2l4oHWq8pFgan9md6d/pI9Oh5zPyv2O+winOL1GN576q+dB O9+wmFrv4kRLZxJBM06bvnPzob7M1YK0/b3P3uSXxwhadUnC6fG1VX6VZI8dt3hJvBgL 9jjg== X-Gm-Message-State: ALoCoQm0MjZZRTOIYcM34IpIg1NNl/L/o7AoVtGYNOtKxQ7SfdA7esO5E7mVsP7QSRKtpR9dqtKO MIME-Version: 1.0 X-Received: by 10.129.107.2 with SMTP id g2mr20899535ywc.200.1447760895874; Tue, 17 Nov 2015 03:48:15 -0800 (PST) Received: by 10.129.97.137 with HTTP; Tue, 17 Nov 2015 03:48:15 -0800 (PST) In-Reply-To: <5646B275.5040707@gmail.com> References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> Date: Tue, 17 Nov 2015 11:48:15 +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: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4002:c07::231 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: Tue, 17 Nov 2015 11:48:20 -0000 Please, see updated patch below. I tried to reuse GRUB hexdump function, so as a result dump will not work with setting vatiables - just dumping to stdout. But it doesn't make sense to assign dump to a variable anyway. diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efiva= r.c new file mode 100644 index 0000000..3ffd5ca --- /dev/null +++ b/grub-core/commands/efi/efivar.c @@ -0,0 +1,253 @@ +/* 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, raw, 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_RAW, + 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, "raw", sizeof("raw"))) + 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_("two arguments 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_RAW: + env_var =3D grub_malloc (efi_var_size + 1); + if (!env_var) + { + status =3D grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory= ")); + break; + } + grub_memcpy (env_var, efi_var, efi_var_size); + env_var[efi_var_size] =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); +} diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index a6101de..2c8f023 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -728,6 +728,12 @@ }; module =3D { + name =3D efivar; + efi =3D commands/efi/efivar.c; + enable =3D efi; +}; + +module =3D { name =3D blocklist; common =3D commands/blocklist.c; }; On Sat, Nov 14, 2015 at 4:03 AM, Andrei Borzenkov wro= te: > 13.11.2015 22:42, Ignat Korchagin =D0=BF=D0=B8=D1=88=D0=B5=D1=82: >>>>> >>>>> +static enum efi_var_type >>>>> +parse_efi_var_type (const char *type) >>>>> +{ >>>>> + if (!grub_strncmp (type, "string", sizeof("string"))) >>>>> + return EFI_VAR_STRING; >>>>> + >>>> >>>> >>>> >>>> I think this should be "ascii" or "utf8". "string" is too ambiguous in >>>> UEFI >>>> environment, it can also mean sequence of UCS-2 characters. >>> >>> I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" >>> when printing. Maybe, to avoid confusion, it might be better to >>> completely remove this option. Basically, you do not want to interpret >>> raw buffers as strings. For best compatibility "hex" mode should be >>> promoted, I guess. What do you think? >> >> Checked again the UEFI spec. For globally defined variables which are >> strings they specify ASCII. So if we leave this option, ascii is the >> best name. >> > > What about > > - ascii - print ASCII characters verbatim, escape non-ASCII in usual wa= y > (similar to "od -c") > > - raw - simply put raw variable without any interpretation. > > This is better aligned with argument describing output formatting rather > than attempting to "type" variable. > > Alternative (or in addition to) ascii - dump which prints usual pretty he= x > dump of content (hexdump -C). This is handy to interactively look at > variable content. > > Or, and change name from --type to --format :) > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a1JBj-00013n-30 for mharc-grub-devel@gnu.org; Tue, 24 Nov 2015 14:23:39 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46745) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a1JBf-00012S-MQ for grub-devel@gnu.org; Tue, 24 Nov 2015 14:23:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a1JBe-0002Qt-Ib for grub-devel@gnu.org; Tue, 24 Nov 2015 14:23:35 -0500 Received: from mail-io0-x235.google.com ([2607:f8b0:4001:c06::235]:35385) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a1JBe-0002Qp-Bx for grub-devel@gnu.org; Tue, 24 Nov 2015 14:23:34 -0500 Received: by ioc74 with SMTP id 74so30837555ioc.2 for ; Tue, 24 Nov 2015 11:23:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=UaJjr+tRAQnJ1keYxAWpDdagd9aYqXxFHt8qeY6hb8Y=; b=vcJG2RibiI6OLbei9qXW5Z21RHrzHa8hdOZI6PDH+9V/Eue/U4mcY4HFzb8ZUoyIS5 MEYsPpi6nkGqeOc2ndXnFVRaCjCiT+VoQxoxSC7KyMFn5kLDb/zeTodD5gBw7gt5Igla tb+BPAVXIt0HtB70yu/8SSz54a5SctsLCxEaFzWv+vGASbVAZx9mPYidmcSGIsCH9rS4 RnacFrRIA+SxsEK/uRE4FBiq+LAaUMScXEATRe0+Parvy3uAZIC5R5h4/aRxCBTCH2uv X86v3bMauMXGFtGVadwkMvCFmDIAZk1FX3QRSQqkXCWGsMDeeMMJ1pc3mbhE/Wi6OFIF 9FJQ== MIME-Version: 1.0 X-Received: by 10.107.11.166 with SMTP id 38mr32608666iol.186.1448393013646; Tue, 24 Nov 2015 11:23:33 -0800 (PST) Received: by 10.36.51.74 with HTTP; Tue, 24 Nov 2015 11:23:33 -0800 (PST) In-Reply-To: <5646B275.5040707@gmail.com> References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> Date: Tue, 24 Nov 2015 11:23:33 -0800 Message-ID: Subject: Re: Grub get and set efi variables From: Mat Troi To: The development of GNU GRUB Content-Type: multipart/alternative; boundary=001a113ed81812d9f305254e4747 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4001:c06::235 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: Tue, 24 Nov 2015 19:23:37 -0000 --001a113ed81812d9f305254e4747 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable For a specific project implementation, I need to be able to write and read one EFI variable during boot only. So I have written a grub command to do just that. But the issue is with setting these attributes to the variable (GRUB_EFI_VARIABLE_NON_VOLATILE, GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS), I am not able to modify it during boot on some platform. Since this is so specific, I am wondering if anyone has seen similar issue? On Fri, Nov 13, 2015 at 8:03 PM, Andrei Borzenkov wrote: > 13.11.2015 22:42, Ignat Korchagin =D0=BF=D0=B8=D1=88=D0=B5=D1=82: > >> +static enum efi_var_type >>>>> +parse_efi_var_type (const char *type) >>>>> +{ >>>>> + if (!grub_strncmp (type, "string", sizeof("string"))) >>>>> + return EFI_VAR_STRING; >>>>> + >>>>> >>>> >>>> >>>> I think this should be "ascii" or "utf8". "string" is too ambiguous in >>>> UEFI >>>> environment, it can also mean sequence of UCS-2 characters. >>>> >>> I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" >>> when printing. Maybe, to avoid confusion, it might be better to >>> completely remove this option. Basically, you do not want to interpret >>> raw buffers as strings. For best compatibility "hex" mode should be >>> promoted, I guess. What do you think? >>> >> Checked again the UEFI spec. For globally defined variables which are >> strings they specify ASCII. So if we leave this option, ascii is the >> best name. >> >> > What about > > - ascii - print ASCII characters verbatim, escape non-ASCII in usual wa= y > (similar to "od -c") > > - raw - simply put raw variable without any interpretation. > > This is better aligned with argument describing output formatting rather > than attempting to "type" variable. > > Alternative (or in addition to) ascii - dump which prints usual pretty he= x > dump of content (hexdump -C). This is handy to interactively look at > variable content. > > Or, and change name from --type to --format :) > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel > --001a113ed81812d9f305254e4747 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
For a specific project implementation, I need to be able t= o write and read one EFI variable during boot only.=C2=A0 So I have written= a grub command to do just that.=C2=A0 But the issue is with setting these = attributes to the variable (GRUB_EFI_VARIABLE_NON_VOLATILE, GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS), I am not able to modify it durin= g boot on some platform.=C2=A0 Since this is so specific, I am wondering if= anyone has seen similar issue?

On Fri, Nov 13, 2015 at 8:03 PM, Andrei Borzenkov <= arvidjaar@gmail.com> wrote:
13.11.2015 22:42, Ignat Korchagin =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
+static enum efi_var_type
+parse_efi_var_type (const char *type)
+{
+=C2=A0 if (!grub_strncmp (type, "string", sizeof("string&qu= ot;)))
+=C2=A0 =C2=A0 return EFI_VAR_STRING;
+


I think this should be "ascii" or "utf8". "string&= quot; is too ambiguous in UEFI
environment, it can also mean sequence of UCS-2 characters.
I'm still not sure how exactly GRUB + UEFI interprets "raw buffers= "
when printing. Maybe, to avoid confusion, it might be better to
completely remove this option. Basically, you do not want to interpret
raw buffers as strings. For best compatibility "hex" mode should = be
promoted, I guess. What do you think?
Checked again the UEFI spec. For globally defined variables which are
strings they specify ASCII. So if we leave this option, ascii is the
best name.


What about

=C2=A0 - ascii - print ASCII characters verbatim, escape non-ASCII in usual= way (similar to "od -c")

=C2=A0 - raw - simply put raw variable without any interpretation.

This is better aligned with argument describing output formatting rather th= an attempting to "type" variable.

Alternative (or in addition to) ascii - dump which prints usual pretty hex = dump of content (hexdump -C). This is handy to interactively look at variab= le content.

Or, and change name from --type to --format :)


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org<= /a>
https://lists.gnu.org/mailman/listinfo/grub-devel

--001a113ed81812d9f305254e4747-- From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a1KW2-0005t2-IE for mharc-grub-devel@gnu.org; Tue, 24 Nov 2015 15:48:42 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38482) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a1KVy-0005ls-BJ for grub-devel@gnu.org; Tue, 24 Nov 2015 15:48:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a1KVu-0007tF-9L for grub-devel@gnu.org; Tue, 24 Nov 2015 15:48:38 -0500 Received: from userp1040.oracle.com ([156.151.31.81]:34723) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a1KVu-0007sb-1v for grub-devel@gnu.org; Tue, 24 Nov 2015 15:48:34 -0500 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAOKmV3m011667 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 24 Nov 2015 20:48:31 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tAOKmUgM032567 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Tue, 24 Nov 2015 20:48:31 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tAOKmUNr032445 for ; Tue, 24 Nov 2015 20:48:30 GMT Received: from [192.168.2.112] (/73.189.216.229) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 24 Nov 2015 12:48:30 -0800 From: Seth Goldberg Content-Type: multipart/alternative; boundary=Apple-Mail-734BB423-E2E2-4B73-98B2-257C3F121A60 Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (1.0) Subject: Re: Grub get and set efi variables Message-Id: Date: Tue, 24 Nov 2015 12:48:28 -0800 References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> In-Reply-To: To: The development of GNU GRUB X-Mailer: iPhone Mail (13B143) X-Source-IP: userv0021.oracle.com [156.151.31.71] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 156.151.31.81 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: Tue, 24 Nov 2015 20:48:39 -0000 --Apple-Mail-734BB423-E2E2-4B73-98B2-257C3F121A60 Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: quoted-printable That sounds like a firmware implementation bug, unfortunately. I've seen it= be hit or miss setting boot service only variables on some platforms. =20 --S > On Nov 24, 2015, at 11:23 AM, Mat Troi wrote: >=20 > For a specific project implementation, I need to be able to write and read= one EFI variable during boot only. So I have written a grub command to do j= ust that. But the issue is with setting these attributes to the variable (G= RUB_EFI_VARIABLE_NON_VOLATILE, GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS), I am n= ot able to modify it during boot on some platform. Since this is so specifi= c, I am wondering if anyone has seen similar issue? >=20 >> On Fri, Nov 13, 2015 at 8:03 PM, Andrei Borzenkov w= rote: >> 13.11.2015 22:42, Ignat Korchagin =D0=C9=DB=C5=D4: >>>>>> +static enum efi_var_type >>>>>> +parse_efi_var_type (const char *type) >>>>>> +{ >>>>>> + if (!grub_strncmp (type, "string", sizeof("string"))) >>>>>> + return EFI_VAR_STRING; >>>>>> + >>>>>=20 >>>>>=20 >>>>> I think this should be "ascii" or "utf8". "string" is too ambiguous in= UEFI >>>>> environment, it can also mean sequence of UCS-2 characters. >>>> I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" >>>> when printing. Maybe, to avoid confusion, it might be better to >>>> completely remove this option. Basically, you do not want to interpret >>>> raw buffers as strings. For best compatibility "hex" mode should be >>>> promoted, I guess. What do you think? >>> Checked again the UEFI spec. For globally defined variables which are >>> strings they specify ASCII. So if we leave this option, ascii is the >>> best name. >>=20 >> What about >>=20 >> - ascii - print ASCII characters verbatim, escape non-ASCII in usual wa= y (similar to "od -c") >>=20 >> - raw - simply put raw variable without any interpretation. >>=20 >> This is better aligned with argument describing output formatting rather t= han attempting to "type" variable. >>=20 >> Alternative (or in addition to) ascii - dump which prints usual pretty he= x dump of content (hexdump -C). This is handy to interactively look at varia= ble content. >>=20 >> Or, and change name from --type to --format :) >>=20 >>=20 >> _______________________________________________ >> Grub-devel mailing list >> Grub-devel@gnu.org >> https://lists.gnu.org/mailman/listinfo/grub-devel >=20 > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel --Apple-Mail-734BB423-E2E2-4B73-98B2-257C3F121A60 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
That sounds like a firmware= implementation bug, unfortunately.  I've seen it be hit or miss settin= g boot service only variables on some platforms.  

=
   --S
For a spec= ific project implementation, I need to be able to write and read one EFI var= iable during boot only.  So I have written a grub command to do just th= at.  But the issue is with setting these attributes to the variable (GR= UB_EFI_VARIABLE_NON_VOLATILE, GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS), I am not able to modify it during= boot on some platform.  Since this is so specific, I am wondering if a= nyone has seen similar issue?

On Fri, Nov 13, 2015 at 8:03 PM, Andrei Borzenkov <arvid= jaar@gmail.com> wrote:
13.11.= 2015 22:42, Ignat Korchagin =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
+static enum efi_var_type
+parse_efi_var_type (const char *type)
+{
+  if (!grub_strncmp (type, "string", sizeof("string")))
+    return EFI_VAR_STRING;
+


I think this should be "ascii" or "utf8". "string" is too ambiguous in UEFI<= br> environment, it can also mean sequence of UCS-2 characters.
I'm still not sure how exactly GRUB + UEFI interprets "raw buffers"
when printing. Maybe, to avoid confusion, it might be better to
completely remove this option. Basically, you do not want to interpret
raw buffers as strings. For best compatibility "hex" mode should be
promoted, I guess. What do you think?
Checked again the UEFI spec. For globally defined variables which are
strings they specify ASCII. So if we leave this option, ascii is the
best name.


What about

  - ascii - print ASCII characters verbatim, escape non-ASCII in usual w= ay (similar to "od -c")

  - raw - simply put raw variable without any interpretation.

This is better aligned with argument describing output formatting rather tha= n attempting to "type" variable.

Alternative (or in addition to) ascii - dump which prints usual pretty hex d= ump of content (hexdump -C). This is handy to interactively look at variable= content.

Or, and change name from --type to --format :)


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel=

____________________= ___________________________
Grub-devel mailing listGrub-devel@gnu.org<= br>https= ://lists.gnu.org/mailman/listinfo/grub-devel
= --Apple-Mail-734BB423-E2E2-4B73-98B2-257C3F121A60-- From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a2JgD-0002Cr-3w for mharc-grub-devel@gnu.org; Fri, 27 Nov 2015 09:07:17 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48244) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a2Jg7-00025I-4x for grub-devel@gnu.org; Fri, 27 Nov 2015 09:07:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a2Jg5-0004gB-OZ for grub-devel@gnu.org; Fri, 27 Nov 2015 09:07:11 -0500 Received: from mail-wm0-x22e.google.com ([2a00:1450:400c:c09::22e]:35276) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a2Jg5-0004fw-Hs for grub-devel@gnu.org; Fri, 27 Nov 2015 09:07:09 -0500 Received: by wmuu63 with SMTP id u63so56902175wmu.0 for ; Fri, 27 Nov 2015 06:07:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type; bh=Er13rmbdnQ1VHjgNSQkbUsyEDMLR5yKRExfVJwh5Waw=; b=PsclHdeH3vqSFfpgYR7Dat38w3gSaUpnmWOaXWouOs3uzCGkDi91Nb2SqhrT1RdGtu +2KV2nKgk4/REaqaInv0ckNBsDTdpGu2bLfFM64eGq/UvNeuQh46sbFs0bF51vIw3+uv wsb7ca59u54tWGGT6wwR/10V/qTTwNJ2V6l6VZjQpWMjGwAIbkBRq6Wa8lLjtGi6JXvh D4ZjFQlZmCGt124lUEv5lc93RU5tAlSscR86TzshKkBUF/HNlVGjGc09exGthvR25Xpx cc7wDqo4xJrp/Hi5xU1Chwk74qE/upSK4eXeq9xcHC+i3dPmAStCIOmAhxd6tY6OajpX 5nIA== X-Received: by 10.194.117.163 with SMTP id kf3mr44281163wjb.139.1448633228685; Fri, 27 Nov 2015 06:07:08 -0800 (PST) Received: from ?IPv6:2620:0:105f:fd00:a2a8:cdff:fe64:b3b5? ([2620:0:105f:fd00:a2a8:cdff:fe64:b3b5]) by smtp.gmail.com with ESMTPSA id pc2sm32957040wjb.11.2015.11.27.06.07.07 for (version=TLSv1/SSLv3 cipher=OTHER); Fri, 27 Nov 2015 06:07:07 -0800 (PST) Subject: Re: Grub get and set efi variables To: The development of GNU GRUB References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> From: =?UTF-8?Q?Vladimir_'=cf=86-coder/phcoder'_Serbinenko?= Message-ID: <56586384.1030504@gmail.com> Date: Fri, 27 Nov 2015 15:07:00 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Icedove/38.3.0 MIME-Version: 1.0 In-Reply-To: <5646B275.5040707@gmail.com> Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="8cKOOTMc3JckqtIHkoNhMbtxg0OU1Klg4" X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c09::22e 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: Fri, 27 Nov 2015 14:07:15 -0000 This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --8cKOOTMc3JckqtIHkoNhMbtxg0OU1Klg4 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 14.11.2015 05:03, Andrei Borzenkov wrote: > 13.11.2015 22:42, Ignat Korchagin =D0=BF=D0=B8=D1=88=D0=B5=D1=82: >>>>> +static enum efi_var_type >>>>> +parse_efi_var_type (const char *type) >>>>> +{ >>>>> + if (!grub_strncmp (type, "string", sizeof("string"))) >>>>> + return EFI_VAR_STRING; >>>>> + >>>> >>>> >>>> I think this should be "ascii" or "utf8". "string" is too ambiguous >>>> in UEFI >>>> environment, it can also mean sequence of UCS-2 characters. >>> I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" >>> when printing. Maybe, to avoid confusion, it might be better to >>> completely remove this option. Basically, you do not want to interpre= t >>> raw buffers as strings. For best compatibility "hex" mode should be >>> promoted, I guess. What do you think? >> Checked again the UEFI spec. For globally defined variables which are >> strings they specify ASCII. So if we leave this option, ascii is the >> best name. >> >=20 > What about >=20 > - ascii - print ASCII characters verbatim, escape non-ASCII in usual > way (similar to "od -c") >=20 > - raw - simply put raw variable without any interpretation. >=20 I would add: * hex. To print and store in hex form * utf16. Decode utf16 into utf8. utf16 is a common encoding in EFI land. I would also skip on raw, at least until we have a real need for it as we currently are not equiped to handle raw strings in variable contents, including but not limited to \0 being considered a terminator > This is better aligned with argument describing output formatting rathe= r > than attempting to "type" variable. >=20 > Alternative (or in addition to) ascii - dump which prints usual pretty > hex dump of content (hexdump -C). This is handy to interactively look a= t > variable content. >=20 > Or, and change name from --type to --format :) >=20 > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel --8cKOOTMc3JckqtIHkoNhMbtxg0OU1Klg4 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iF4EAREKAAYFAlZYY4QACgkQmBXlbbo5nOvf6gD+KrMI5//UeEY1OdT1ZjwTkvjR wq1tzHb+8gsn+2DBxMkA/RF78G9XrO5MIu/kbTa0kISclYqfZ+fNmtT14C+zPABk =kvi2 -----END PGP SIGNATURE----- --8cKOOTMc3JckqtIHkoNhMbtxg0OU1Klg4-- From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a2JxZ-0007v0-FD for mharc-grub-devel@gnu.org; Fri, 27 Nov 2015 09:25:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51536) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a2JxW-0007sL-5p for grub-devel@gnu.org; Fri, 27 Nov 2015 09:25:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a2JxR-0008PD-Ro for grub-devel@gnu.org; Fri, 27 Nov 2015 09:25:10 -0500 Received: from mail-yk0-x235.google.com ([2607:f8b0:4002:c07::235]:36068) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a2JxR-0008Oz-OB for grub-devel@gnu.org; Fri, 27 Nov 2015 09:25:05 -0500 Received: by ykdr82 with SMTP id r82so119144887ykd.3 for ; Fri, 27 Nov 2015 06:25:05 -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=WXVg5n/U2cCgZxXWshvQB8svMYM5Yp8zJVAwNMUQop0=; b=sbW4nf4PBGLQ0DmqzY0XubTknmI1O3S8m9Gv1IXmJuNrtm4P1I1fJYzU7HXdljhOL4 Yk25atZq1WrrLR1Pk9MD+qnILh4C64rGNmOUd7f0+EDGQuyJzJLXCWny1dtITLFQY+rO bmhDzw7TxXstbEee46ziMP9OlRGq9AJfpjAH8= 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=WXVg5n/U2cCgZxXWshvQB8svMYM5Yp8zJVAwNMUQop0=; b=gZvn6/+l0RlFKGJa+ViD/uxx0kIDVrmjGGRJHIUcds3GN9M6cRwtOheE7VQnsUxYgi M/Z7hD5Tcb5YStSwtARUcB4fBrXFFWHSgEvmkrHVrpNiaKUfkq12Nrsj81yl13Xrn/Bw eyVDNE/NMtmZE+aPieQK3PSpfyhRnlkKUsssIXLYL+MEHW3Q0m+3Fhf+n8djscSg8ivh Qk4tT8ERZazeUg1/QD1aBlvC0oAHCZMAEIGz40KoK6kPBXcGcPAzdp5CS+r8aAnqO3ey 3RdnIHMxzlMbhrf2LZXKYETUK4DwdY16M7e4tMq5CpIGbtTjjY3hoZ8bsxJgi8Tqzp6o qClw== X-Gm-Message-State: ALoCoQnaLoRCeQ7mdnxFiXzbDfGfNG3y93xTrWsJSKzJ8bQrX3TOTVBE0uj8F52Xz7HQ6uc52CDX MIME-Version: 1.0 X-Received: by 10.129.74.6 with SMTP id x6mr38531448ywa.46.1448634305084; Fri, 27 Nov 2015 06:25:05 -0800 (PST) Received: by 10.129.27.14 with HTTP; Fri, 27 Nov 2015 06:25:04 -0800 (PST) In-Reply-To: <56586384.1030504@gmail.com> References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> <56586384.1030504@gmail.com> Date: Fri, 27 Nov 2015 14:25:04 +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: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4002:c07::235 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: Fri, 27 Nov 2015 14:25:11 -0000 > I would add: > * hex. To print and store in hex form > * utf16. Decode utf16 into utf8. utf16 is a common encoding in EFI land. hex is already part of the latest proposed patch: >> + case EFI_VAR_HEX: I'm not sure whether utf16 will be useful, as all standard UEFI variables now are using ASCII for string data. On Fri, Nov 27, 2015 at 2:07 PM, Vladimir '=CF=86-coder/phcoder' Serbinenko wrote: > On 14.11.2015 05:03, Andrei Borzenkov wrote: >> 13.11.2015 22:42, Ignat Korchagin =D0=BF=D0=B8=D1=88=D0=B5=D1=82: >>>>>> +static enum efi_var_type >>>>>> +parse_efi_var_type (const char *type) >>>>>> +{ >>>>>> + if (!grub_strncmp (type, "string", sizeof("string"))) >>>>>> + return EFI_VAR_STRING; >>>>>> + >>>>> >>>>> >>>>> I think this should be "ascii" or "utf8". "string" is too ambiguous >>>>> in UEFI >>>>> environment, it can also mean sequence of UCS-2 characters. >>>> I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" >>>> when printing. Maybe, to avoid confusion, it might be better to >>>> completely remove this option. Basically, you do not want to interpret >>>> raw buffers as strings. For best compatibility "hex" mode should be >>>> promoted, I guess. What do you think? >>> Checked again the UEFI spec. For globally defined variables which are >>> strings they specify ASCII. So if we leave this option, ascii is the >>> best name. >>> >> >> What about >> >> - ascii - print ASCII characters verbatim, escape non-ASCII in usual >> way (similar to "od -c") >> >> - raw - simply put raw variable without any interpretation. >> > I would add: > * hex. To print and store in hex form > * utf16. Decode utf16 into utf8. utf16 is a common encoding in EFI land. > I would also skip on raw, at least until we have a real need for it as > we currently are not equiped to handle raw strings in variable contents, > including but not limited to \0 being considered a terminator >> This is better aligned with argument describing output formatting rather >> than attempting to "type" variable. >> >> Alternative (or in addition to) ascii - dump which prints usual pretty >> hex dump of content (hexdump -C). This is handy to interactively look at >> variable content. >> >> Or, and change name from --type to --format :) >> >> _______________________________________________ >> 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 > From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a2xnK-0001sN-Qh for mharc-grub-devel@gnu.org; Sun, 29 Nov 2015 03:57:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34211) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a2xnH-0001s6-Rm for grub-devel@gnu.org; Sun, 29 Nov 2015 03:57:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a2xnE-00039S-Hm for grub-devel@gnu.org; Sun, 29 Nov 2015 03:57:15 -0500 Received: from mail-lf0-x232.google.com ([2a00:1450:4010:c07::232]:35706) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a2xnE-00039C-7Y for grub-devel@gnu.org; Sun, 29 Nov 2015 03:57:12 -0500 Received: by lfdl133 with SMTP id l133so164994208lfd.2 for ; Sun, 29 Nov 2015 00:57:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type:content-transfer-encoding; bh=w+ItrlkWt6SrIaImAAHwj56xAnrHVtT50V4e6zKEq3I=; b=Uwrrp1VtmPC6KP4p4B3G6MWYqyTYTfXFxQSgEMH2ge97cIUmOM2bAw1HkOsvzF2UYM mvHxeNlze9enLrgw96owviGl7xX2e4E7BMvCVp61LtFquCv94/uViCRUGj7clAAy1yyk Nw32z3jkWR3gBm+mV+Pf+gwZJE3eo9Alo9pG1dAKWWMwg1yfsjs3ch1sGIpwrJLnYUJP 3r4arTGEXmPIjUJFwrCjlyLChKaR6ImL0V0C381ZxPQ/Awosi5lrukkxVa3pnQER8SXd MrS2Y67vRvRe2BCzai4BStEFDSXM8CICoN8fucky8rErqpii6Ks3OpO+ySbZbE8K+2Ea U8yA== X-Received: by 10.25.148.202 with SMTP id w193mr23683095lfd.130.1448787431162; Sun, 29 Nov 2015 00:57:11 -0800 (PST) Received: from [192.168.1.41] (ppp91-76-25-247.pppoe.mtu-net.ru. [91.76.25.247]) by smtp.gmail.com with ESMTPSA id qp7sm6291717lbc.24.2015.11.29.00.57.10 for (version=TLSv1/SSLv3 cipher=OTHER); Sun, 29 Nov 2015 00:57:10 -0800 (PST) Subject: Re: Grub get and set efi variables To: The development of GNU GRUB References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> From: Andrei Borzenkov X-Enigmail-Draft-Status: N1110 Message-ID: <565ABDE5.1030300@gmail.com> Date: Sun, 29 Nov 2015 11:57:09 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4010:c07::232 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: Sun, 29 Nov 2015 08:57:17 -0000 17.11.2015 14:48, Ignat Korchagin пишет: > Please, see updated patch below. I tried to reuse GRUB hexdump > function, so as a result dump will not work with setting vatiables - > just dumping to stdout. But it doesn't make sense to assign dump to a > variable anyway. > > diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.c > new file mode 100644 > index 0000000..3ffd5ca > --- /dev/null > +++ b/grub-core/commands/efi/efivar.c > @@ -0,0 +1,253 @@ > +/* 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[] = { > + {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR in > specific format (hex, uint8, ascii, raw, 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 = 0, > + EFI_VAR_RAW, > + EFI_VAR_UINT8, > + EFI_VAR_HEX, > + EFI_VAR_DUMP, > + EFI_VAR_INVALID = -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, "raw", sizeof("raw"))) > + 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; > + Should not this be strcmp, not str*n*cmp? > + return EFI_VAR_INVALID; > +} > + > +static int > +grub_print_ascii (char *str, char c) > +{ > + if (grub_iscntrl (c)) > + { > + switch (c) > + { > + case '\0': > + str[0] = '\\'; > + str[1] = '0'; > + return 2; > + > + case '\a': > + str[0] = '\\'; > + str[1] = 'a'; > + return 2; > + > + case '\b': > + str[0] = '\\'; > + str[1] = 'b'; > + return 2; > + > + case '\f': > + str[0] = '\\'; > + str[1] = 'f'; > + return 2; > + > + case '\n': > + str[0] = '\\'; > + str[1] = 'n'; > + return 2; > + > + case '\r': > + str[0] = '\\'; > + str[1] = 'r'; > + return 2; > + > + case '\t': > + str[0] = '\\'; > + str[1] = 't'; > + return 2; > + > + case '\v': > + str[0] = '\\'; > + str[1] = 'v'; > + return 2; > + > + default: > + str[0] = '.'; /* as in hexdump -C */ > + return 1; > + } > + } > + > + str[0] = 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 = ctxt->state; > + grub_err_t status; > + void *efi_var = NULL; > + grub_size_t efi_var_size = 0; > + enum efi_var_type efi_type = EFI_VAR_HEX; > + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; > + char *env_var = NULL; > + grub_size_t i; > + char *ptr; > + > + if (1 != argc) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); One argument expected > + > + if (state[0].set) > + efi_type = parse_efi_var_type (state[0].arg); > + > + if (EFI_VAR_INVALID == efi_type) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier")); > + > + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); > + if (!efi_var || !efi_var_size) > + { > + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); > + goto err; > + } > + > + switch (efi_type) > + { > + case EFI_VAR_ASCII: > + env_var = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + break; > + } > + > + ptr = env_var; > + > + for (i = 0; i < efi_var_size; i++) > + ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); > + *ptr = '\0'; > + break; > + > + case EFI_VAR_RAW: > + env_var = grub_malloc (efi_var_size + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + break; > + } > + grub_memcpy (env_var, efi_var, efi_var_size); > + env_var[efi_var_size] = '\0'; That would be wrong ("raw" implies no modification) but I am not keen on keeping "raw" as was discussed. > + break; > + > + case EFI_VAR_UINT8: > + env_var = grub_malloc (4); > + if (!env_var) > + { > + status = 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 = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + break; > + } > + for (i = 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 = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set > variable with dump format specifier")); > + else > + { > + hexdump (0, (char *)efi_var, efi_var_size); > + status = GRUB_ERR_NONE; > + } > + break; > + > + default: > + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug > in module?)")); > + } > + > + if (efi_type != EFI_VAR_DUMP) > + { > + if (state[1].set) > + status = grub_env_set (state[1].arg, env_var); > + else > + { > + grub_printf ("%s\n", (const char *)env_var); > + status = 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 = NULL; > + > +GRUB_MOD_INIT (efivar) > +{ > + cmd = 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); > +} > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def > index a6101de..2c8f023 100644 > --- a/grub-core/Makefile.core.def > +++ b/grub-core/Makefile.core.def > @@ -728,6 +728,12 @@ > }; > > module = { > + name = efivar; > + efi = commands/efi/efivar.c; > + enable = efi; > +}; > + > +module = { > name = blocklist; > common = commands/blocklist.c; > }; > > On Sat, Nov 14, 2015 at 4:03 AM, Andrei Borzenkov wrote: >> 13.11.2015 22:42, Ignat Korchagin пишет: >>>>>> >>>>>> +static enum efi_var_type >>>>>> +parse_efi_var_type (const char *type) >>>>>> +{ >>>>>> + if (!grub_strncmp (type, "string", sizeof("string"))) >>>>>> + return EFI_VAR_STRING; >>>>>> + >>>>> >>>>> >>>>> >>>>> I think this should be "ascii" or "utf8". "string" is too ambiguous in >>>>> UEFI >>>>> environment, it can also mean sequence of UCS-2 characters. >>>> >>>> I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" >>>> when printing. Maybe, to avoid confusion, it might be better to >>>> completely remove this option. Basically, you do not want to interpret >>>> raw buffers as strings. For best compatibility "hex" mode should be >>>> promoted, I guess. What do you think? >>> >>> Checked again the UEFI spec. For globally defined variables which are >>> strings they specify ASCII. So if we leave this option, ascii is the >>> best name. >>> >> >> What about >> >> - ascii - print ASCII characters verbatim, escape non-ASCII in usual way >> (similar to "od -c") >> >> - raw - simply put raw variable without any interpretation. >> >> This is better aligned with argument describing output formatting rather >> than attempting to "type" variable. >> >> Alternative (or in addition to) ascii - dump which prints usual pretty hex >> dump of content (hexdump -C). This is handy to interactively look at >> variable content. >> >> Or, and change name from --type to --format :) >> >> >> _______________________________________________ >> 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 > From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a2xqD-0002xv-G2 for mharc-grub-devel@gnu.org; Sun, 29 Nov 2015 04:00:17 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34667) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a2xqB-0002xp-29 for grub-devel@gnu.org; Sun, 29 Nov 2015 04:00:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a2xq6-0003fr-1g for grub-devel@gnu.org; Sun, 29 Nov 2015 04:00:14 -0500 Received: from mail-lf0-x234.google.com ([2a00:1450:4010:c07::234]:36594) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a2xq5-0003fh-NO for grub-devel@gnu.org; Sun, 29 Nov 2015 04:00:09 -0500 Received: by lfs39 with SMTP id 39so163264796lfs.3 for ; Sun, 29 Nov 2015 01:00:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type:content-transfer-encoding; bh=34ePAwRWZ8HnA36C8Y3yl4UX92jzgWnJndUyk7k9HWI=; b=qSLEBfMeUTdwPCL5i3tPpjp8LtH07J650gz/hJHBJK+L/ttgP96ioiYbrhd8RWda6i ZTe6jLRZFglpD9tHUY/jGORhQkeKTqYxZmBTDJ1XNQA2H9Iy2+iOgOKKORaFnSmtmhz/ Rh9j6ig0+EEAgFUU1NZsO55QcUswu88irIwLbp94iVJw/YGBBKeVD8m8nIorCugAq/PW zceMMdf1/+t6UM7Sn/adEOBQORw/wtNrM1CCx5bYV3XR6TEQaq1VtUW7+fUp8iOqhf1g to1rJsjGJ22UvffhFuT3K0/eER/I19DklnwKD1+kdbn/4d/HKRsk/SVMZEPskmudeDyb ZGzQ== X-Received: by 10.25.24.193 with SMTP id 62mr23914729lfy.84.1448787608895; Sun, 29 Nov 2015 01:00:08 -0800 (PST) Received: from [192.168.1.41] (ppp91-76-25-247.pppoe.mtu-net.ru. [91.76.25.247]) by smtp.gmail.com with ESMTPSA id of8sm4129202lbb.7.2015.11.29.01.00.08 for (version=TLSv1/SSLv3 cipher=OTHER); Sun, 29 Nov 2015 01:00:08 -0800 (PST) Subject: Re: Grub get and set efi variables To: grub-devel@gnu.org References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> <56586384.1030504@gmail.com> From: Andrei Borzenkov Message-ID: <565ABE97.5060109@gmail.com> Date: Sun, 29 Nov 2015 12:00:07 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4010:c07::234 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: Sun, 29 Nov 2015 09:00:16 -0000 27.11.2015 17:25, Ignat Korchagin пишет: >> I would add: >> * hex. To print and store in hex form >> * utf16. Decode utf16 into utf8. utf16 is a common encoding in EFI land. > > hex is already part of the latest proposed patch: >>> + case EFI_VAR_HEX: > > I'm not sure whether utf16 will be useful, as all standard UEFI > variables now are using ASCII for string data. > I agree; it can be added later if use case emerges. So far all "interesting" cases that use UTF-16 are not limited to strings, and need much more elaborate parsing. That is why I mentioned generic format specifier before. But this also can be added if needed, overall syntax seems to be flexible enough. > On Fri, Nov 27, 2015 at 2:07 PM, Vladimir 'φ-coder/phcoder' Serbinenko > wrote: >> On 14.11.2015 05:03, Andrei Borzenkov wrote: >>> 13.11.2015 22:42, Ignat Korchagin пишет: >>>>>>> +static enum efi_var_type >>>>>>> +parse_efi_var_type (const char *type) >>>>>>> +{ >>>>>>> + if (!grub_strncmp (type, "string", sizeof("string"))) >>>>>>> + return EFI_VAR_STRING; >>>>>>> + >>>>>> >>>>>> >>>>>> I think this should be "ascii" or "utf8". "string" is too ambiguous >>>>>> in UEFI >>>>>> environment, it can also mean sequence of UCS-2 characters. >>>>> I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" >>>>> when printing. Maybe, to avoid confusion, it might be better to >>>>> completely remove this option. Basically, you do not want to interpret >>>>> raw buffers as strings. For best compatibility "hex" mode should be >>>>> promoted, I guess. What do you think? >>>> Checked again the UEFI spec. For globally defined variables which are >>>> strings they specify ASCII. So if we leave this option, ascii is the >>>> best name. >>>> >>> >>> What about >>> >>> - ascii - print ASCII characters verbatim, escape non-ASCII in usual >>> way (similar to "od -c") >>> >>> - raw - simply put raw variable without any interpretation. >>> >> I would add: >> * hex. To print and store in hex form >> * utf16. Decode utf16 into utf8. utf16 is a common encoding in EFI land. >> I would also skip on raw, at least until we have a real need for it as >> we currently are not equiped to handle raw strings in variable contents, >> including but not limited to \0 being considered a terminator >>> This is better aligned with argument describing output formatting rather >>> than attempting to "type" variable. >>> >>> Alternative (or in addition to) ascii - dump which prints usual pretty >>> hex dump of content (hexdump -C). This is handy to interactively look at >>> variable content. >>> >>> Or, and change name from --type to --format :) >>> >>> _______________________________________________ >>> 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 >> > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel > From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a46up-0008KS-Jo for mharc-grub-devel@gnu.org; Wed, 02 Dec 2015 07:53:47 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54838) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a46um-0008GW-Cs for grub-devel@gnu.org; Wed, 02 Dec 2015 07:53:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a46uk-0002qe-9q for grub-devel@gnu.org; Wed, 02 Dec 2015 07:53:44 -0500 Received: from mail-yk0-x231.google.com ([2607:f8b0:4002:c07::231]:34541) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a46uk-0002qX-3l for grub-devel@gnu.org; Wed, 02 Dec 2015 07:53:42 -0500 Received: by ykfs79 with SMTP id s79so45162936ykf.1 for ; Wed, 02 Dec 2015 04:53:41 -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=g0AFrG3+XItOYS6FXgtzETCyihkGmj+EmvX6+CgwMbE=; b=qnxrKeN1xMz9nguKOTgT+QiifPeYfXEGaBJNrPMNFh0/jozIw7GGYFi7WE1D8UPfrf sFiXPpOr8Ldj9fGZW1lBLcFRrOEXV3VVH53FI00JorFtOcjysuqbmDYNxUBPByA7eekj MFNsrt0nMKEmOc1o7i+lxiHOZwPn0iL9h8Nmw= 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=g0AFrG3+XItOYS6FXgtzETCyihkGmj+EmvX6+CgwMbE=; b=kd9lD/yZsSkBYcAaWXeAEElT9ACJNy9RMujwkDv9QopLV2Hbcd8VGVtKgGTP8Gx+cT N9OoyBBYeK4epbiVXZl28IFe8Me3ImICgcY54z4YVcpYW366INqFwBbTCHvz6mzE1V6I eoAkhaMup6f23Fo6RNTJ2wAqMQXqcTfWlSDjE3ea3DKrDrRycWYF7GDfa1ths8yeOXg7 b29ilyeDPSjmfboH12aYHHNDa0Kr6RXJtQCvLmFh6kevPzd6gCmbdCTIo/Dp56T87alX PN4BiVAwK3HuEadRMpzz70AvGYs1MLUdV/u/rdvoMS/HEmLYj5LehbUwbnAO+1N9pthg WRHg== X-Gm-Message-State: ALoCoQnPnSUAaZvQSBF36gI4NggCZwdhT8aseL/gfhh/nDQjd8g5+adKAQriRP0lZSFz839ZFVTv MIME-Version: 1.0 X-Received: by 10.129.102.193 with SMTP id a184mr1869539ywc.7.1449060821435; Wed, 02 Dec 2015 04:53:41 -0800 (PST) Received: by 10.129.27.14 with HTTP; Wed, 2 Dec 2015 04:53:41 -0800 (PST) In-Reply-To: <565ABE97.5060109@gmail.com> 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 12:53:41 +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::231 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 12:53:46 -0000 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. 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. diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efiva= r.c new file mode 100644 index 0000000..3ffd5ca --- /dev/null +++ b/grub-core/commands/efi/efivar.c @@ -0,0 +1,253 @@ +/* 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, raw, 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_RAW, + 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, "raw", sizeof("raw"))) + 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_RAW: + env_var =3D grub_malloc (efi_var_size + 1); + if (!env_var) + { + status =3D grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory= ")); + break; + } + grub_memcpy (env_var, efi_var, efi_var_size); + env_var[efi_var_size] =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); +} diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index a6101de..2c8f023 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -728,6 +728,12 @@ }; module =3D { + name =3D efivar; + efi =3D commands/efi/efivar.c; + enable =3D efi; +}; + +module =3D { name =3D blocklist; common =3D commands/blocklist.c; }; On Sun, Nov 29, 2015 at 9:00 AM, Andrei Borzenkov wro= te: > 27.11.2015 17:25, Ignat Korchagin =D0=BF=D0=B8=D1=88=D0=B5=D1=82: >>> I would add: >>> * hex. To print and store in hex form >>> * utf16. Decode utf16 into utf8. utf16 is a common encoding in EFI land= . >> >> hex is already part of the latest proposed patch: >>>> + case EFI_VAR_HEX: >> >> I'm not sure whether utf16 will be useful, as all standard UEFI >> variables now are using ASCII for string data. >> > > I agree; it can be added later if use case emerges. So far all > "interesting" cases that use UTF-16 are not limited to strings, and need > much more elaborate parsing. That is why I mentioned generic format > specifier before. But this also can be added if needed, overall syntax > seems to be flexible enough. > >> On Fri, Nov 27, 2015 at 2:07 PM, Vladimir '=CF=86-coder/phcoder' Serbine= nko >> wrote: >>> On 14.11.2015 05:03, Andrei Borzenkov wrote: >>>> 13.11.2015 22:42, Ignat Korchagin =D0=BF=D0=B8=D1=88=D0=B5=D1=82: >>>>>>>> +static enum efi_var_type >>>>>>>> +parse_efi_var_type (const char *type) >>>>>>>> +{ >>>>>>>> + if (!grub_strncmp (type, "string", sizeof("string"))) >>>>>>>> + return EFI_VAR_STRING; >>>>>>>> + >>>>>>> >>>>>>> >>>>>>> I think this should be "ascii" or "utf8". "string" is too ambiguous >>>>>>> in UEFI >>>>>>> environment, it can also mean sequence of UCS-2 characters. >>>>>> I'm still not sure how exactly GRUB + UEFI interprets "raw buffers" >>>>>> when printing. Maybe, to avoid confusion, it might be better to >>>>>> completely remove this option. Basically, you do not want to interpr= et >>>>>> raw buffers as strings. For best compatibility "hex" mode should be >>>>>> promoted, I guess. What do you think? >>>>> Checked again the UEFI spec. For globally defined variables which are >>>>> strings they specify ASCII. So if we leave this option, ascii is the >>>>> best name. >>>>> >>>> >>>> What about >>>> >>>> - ascii - print ASCII characters verbatim, escape non-ASCII in usual >>>> way (similar to "od -c") >>>> >>>> - raw - simply put raw variable without any interpretation. >>>> >>> I would add: >>> * hex. To print and store in hex form >>> * utf16. Decode utf16 into utf8. utf16 is a common encoding in EFI land= . >>> I would also skip on raw, at least until we have a real need for it as >>> we currently are not equiped to handle raw strings in variable contents= , >>> including but not limited to \0 being considered a terminator >>>> This is better aligned with argument describing output formatting rath= er >>>> than attempting to "type" variable. >>>> >>>> Alternative (or in addition to) ascii - dump which prints usual pretty >>>> hex dump of content (hexdump -C). This is handy to interactively look = at >>>> variable content. >>>> >>>> Or, and change name from --type to --format :) >>>> >>>> _______________________________________________ >>>> 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 >>> >> >> _______________________________________________ >> 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 From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a471q-0003a0-SN for mharc-grub-devel@gnu.org; Wed, 02 Dec 2015 08:01:02 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57008) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a471n-0003YM-V7 for grub-devel@gnu.org; Wed, 02 Dec 2015 08:01:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a471n-00053O-2P for grub-devel@gnu.org; Wed, 02 Dec 2015 08:00:59 -0500 Received: from mail-oi0-x230.google.com ([2607:f8b0:4003:c06::230]:36176) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a471m-00053A-Sm for grub-devel@gnu.org; Wed, 02 Dec 2015 08:00:58 -0500 Received: by oiww189 with SMTP id w189so23836868oiw.3 for ; Wed, 02 Dec 2015 05:00:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=pCrZcEEhWXBtW+QQxNxsf/3xNOZxWDvfha+NVCvr2R4=; b=sbih5bPxXRrVv7RKCdoTXd2xeM9OLgtWWQaqNDRND3ZNUK0YrldXrMtgX0QWRx4KM2 5VUTqMsjLmMUbWa9iJVOjbM4kt7sEmAXr0fkY0/DV4EJSkBV/t/ikn6r+R88Vi+ac2S1 chg7B1h9AtVyitI4NrkDitF72DWNRwwb6OcLUpFQUHAtG0ISlDN6HQb2LpQMEon8er5M mULSh4IwVC245JML4ljFxizyZYlrEMtcIlNJeKL6q0gM5Elj1FnM6sG472GBYdJMvvS6 1WQbP4tEnb3X1FSkIm2hxB8ZScQtwP+AXGIpTCiV2NlZH570ojfGWmHMjCy4wbobLNLt dbtw== MIME-Version: 1.0 X-Received: by 10.202.192.87 with SMTP id q84mr2355863oif.59.1449061258079; Wed, 02 Dec 2015 05:00:58 -0800 (PST) Received: by 10.202.102.151 with HTTP; Wed, 2 Dec 2015 05:00: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 16:00:57 +0300 Message-ID: Subject: Re: Grub get and set efi variables From: Andrei Borzenkov To: The development of GNU GRUB Content-Type: text/plain; charset=UTF-8 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:4003:c06::230 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 13:01:00 -0000 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. From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a475z-0005uw-5A for mharc-grub-devel@gnu.org; Wed, 02 Dec 2015 08:05:19 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58163) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a475t-0005ko-5s for grub-devel@gnu.org; Wed, 02 Dec 2015 08:05:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a475s-0006ZQ-3M for grub-devel@gnu.org; Wed, 02 Dec 2015 08:05:13 -0500 Received: from mail-wm0-x22d.google.com ([2a00:1450:400c:c09::22d]:33475) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a475r-0006Yv-Rp for grub-devel@gnu.org; Wed, 02 Dec 2015 08:05:12 -0500 Received: by wmec201 with SMTP id c201so252197972wme.0 for ; Wed, 02 Dec 2015 05:05:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=XI5v+rE46iBWt7ex+ssIQBN9wZJqGtLkYGxFPzMvF+M=; b=k6l6oJBHLVyE/wXvbBQIxm8VSmyuVmiyHca7Cypnf7kIbFIo9OCzVaUdsMqGizVZd+ 0lyrN99kK9wa84KLe959oeccB8QXz5iFrXBVYzSv64ztbgeYgWQuinKThyvI8ctUqXCE Zu+FvJAG4JzZeXSz9XF42GdnRBDoVd9fKQ5vVapAH25vd9u+48bbkuNDvRv8JU1AbYxB xSDZTFVJdeh4D7dFsOHcBbcXDhKY4R7zhCJ25eS/WjtnOTr9mzfMi42h+QxHsTCcvZyx pWbM/F/qEtbRTPzo8yKHkRaUYt3hH0PMTTJp+c5LHWki0K5mvBM8uo0xKXok1d8NKH36 OuSg== MIME-Version: 1.0 X-Received: by 10.28.126.197 with SMTP id z188mr5984682wmc.88.1449061511202; Wed, 02 Dec 2015 05:05:11 -0800 (PST) Received: by 10.27.30.149 with HTTP; Wed, 2 Dec 2015 05:05:10 -0800 (PST) Received: by 10.27.30.149 with HTTP; Wed, 2 Dec 2015 05:05:10 -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:05:10 +0100 Message-ID: Subject: Re: Grub get and set efi variables From: "Vladimir 'phcoder' Serbinenko" To: The development of GRUB 2 Content-Type: multipart/alternative; boundary=001a11419caaa20ee20525e9ec68 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::22d 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 13:05:17 -0000 --001a11419caaa20ee20525e9ec68 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 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 --001a11419caaa20ee20525e9ec68 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

Le=C2=A02 d=C3=A9c. 2015 2:01 PM, "Andrei Borzenkov" &l= t;arvidjaar@gmail.com> a =C3= =A9crit=C2=A0:

>

> On Wed, Dec 2, 2015 at 3:53 PM, Ignat = Korchagin <ignat@cloudflare.com<= /a>> 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 p= rints that two arguments expected), so here is the

> > updated = one.

> >

>

> It is much more difficult to rem= ove anything than to add it later.

> Unless we have use case right= now, I'd skip it.

>

> > So, finally, should I rem= ove the "raw" parser (as per Vladimir's

> > reque= st). Personally, I would keep it. It might be useful to modify

> &= gt; the hexdump command, that it can dump the contents of a variable. Then<= /p>

> > those pieces will fit together: storing raw value in the va= riable and

> > examining it with hexdump cmd.

> >

>

> hexdump does not support showing variable if that is w= hat you mean. By

> the same logic, unless we have current use case= we probably should not

> add it initially.

>

We do= n't even support storing non-utf8 in a variable. So please skip it

<= p>> _______________________________________________

> Grub-deve= l mailing list

> Grub-devel@= gnu.org

> https://lists.gnu.org/mailman/listinfo/grub-devel

--001a11419caaa20ee20525e9ec68-- 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 > From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a4Wz8-0004Ej-OH for mharc-grub-devel@gnu.org; Thu, 03 Dec 2015 11:43:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40707) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a4Wz4-0004DN-Uz for grub-devel@gnu.org; Thu, 03 Dec 2015 11:43:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a4Wyz-0000ef-Oq for grub-devel@gnu.org; Thu, 03 Dec 2015 11:43:54 -0500 Received: from mail-lb0-x22b.google.com ([2a00:1450:4010:c04::22b]:35001) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a4Wyz-0000e8-EL for grub-devel@gnu.org; Thu, 03 Dec 2015 11:43:49 -0500 Received: by lbcdv4 with SMTP id dv4so5143988lbc.2 for ; Thu, 03 Dec 2015 08:43:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type:content-transfer-encoding; bh=ZVDDAnzt2lUEiZvV4fTSXefSCUnPjngqnnKXEOjBN3w=; b=BZatr6MkKTSk4smllVCc7kaUOVXmdZW9spsin5edinXZsvJVPHQf1plRlW1b8V2nre //cILJCUKXWGzIuv//Tg9MNw2Rs8lvne/ZY1sUZ7/Fo1vyMjaw66w9wZE+EGyk9TJfV9 ayADo7hSQBx6c6RUgX7FO6nCoFxcA9XxYla8aw4LI6B4Zp49eg6Dl5sWrt3+ojoMsUAn Zs9Wklu1efhbhSj0DvfqBAydejqTrxxadPviy7RkFPU2ygF/kQz8u4e7qCBrmo+yLdJ5 3qeLQ8Z/ga+5IYbmwhEAtXCZqoFUwHQyE3/sdmN65lehJt7t1y867QEC31M6HlKreqa8 ZEaw== X-Received: by 10.112.167.131 with SMTP id zo3mr5840577lbb.91.1449161028338; Thu, 03 Dec 2015 08:43:48 -0800 (PST) Received: from [192.168.1.41] (ppp91-76-25-247.pppoe.mtu-net.ru. [91.76.25.247]) by smtp.gmail.com with ESMTPSA id m64sm1529579lfd.45.2015.12.03.08.43.46 for (version=TLSv1/SSLv3 cipher=OTHER); Thu, 03 Dec 2015 08:43:47 -0800 (PST) Subject: Re: Grub get and set efi variables To: The development of GNU GRUB References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> <56586384.1030504@gmail.com> <565ABE97.5060109@gmail.com> From: Andrei Borzenkov Message-ID: <56607141.8030209@gmail.com> Date: Thu, 3 Dec 2015 19:43:45 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:4010:c04::22b 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: Thu, 03 Dec 2015 16:43:56 -0000 02.12.2015 17:52, Ignat Korchagin пишет: > 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 = { > }; > > module = { > + name = efivar; > + efi = commands/efi/efivar.c; > + enable = efi; > +}; > + > +module = { > name = blocklist; > common = commands/blocklist.c; > }; > diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.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[] = { > + {"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 = 0, > + EFI_VAR_UINT8, > + EFI_VAR_HEX, > + EFI_VAR_DUMP, > + EFI_VAR_INVALID = -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; > +} > + This should be grub_strcmp everywhere, there is no reason to use grub_strncmp. > + > +GRUB_MOD_INIT (efivar) > +{ > + cmd = 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 I believe it should be "content" (without final `s') but English is not native. Otherwise OK from my side. Could you also add documentation part for it? From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a4XXx-0002hi-Od for mharc-grub-devel@gnu.org; Thu, 03 Dec 2015 12:19:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52253) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a4XXp-0002VN-2d for grub-devel@gnu.org; Thu, 03 Dec 2015 12:19:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a4XXn-0004s1-KB for grub-devel@gnu.org; Thu, 03 Dec 2015 12:19:49 -0500 Received: from mail-yk0-x236.google.com ([2607:f8b0:4002:c07::236]:34133) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a4XXn-0004rv-Ey for grub-devel@gnu.org; Thu, 03 Dec 2015 12:19:47 -0500 Received: by ykfs79 with SMTP id s79so94324281ykf.1 for ; Thu, 03 Dec 2015 09:19:46 -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; bh=FkccZWc/nDOFGBdJtr8FAXPato4u1QCR8nep+ze2lP8=; b=VKm88vy6H5nJhLTpNMYkt3b6FWEeX4j5fd4jN+LhwEAAZzofetO9M16lwE8GB5qY3T Xtw7VHKhEE7i0yTFutWigoDD1SrjxevHjwO7YWzkO20Nt7QDd3LIyHbh9eOVo+rr27lY avmVMIeXJuESeSevmoc2KrCytakw/0YbUoiCA= 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; bh=FkccZWc/nDOFGBdJtr8FAXPato4u1QCR8nep+ze2lP8=; b=jONdTPFwXA7/PMWy3QsDHZoVGK/a+VwyGQjdSBfAcTEEb/ppWvU7Im0FfrvH4KaxRg NnTT8jt4ShgmeSw2QruDry2nrqIJSrgad6DxAWWnj0YfTOQttNRiEe+XTaQn0XzA0h2V PguQKzqrwVgmdWccD0v7Do/cIhJscw9bffhbmArZ8ub2nLNw2cwQG1MntHzTNgBBvZB2 KDxtCK2WpRL6s9FuL6iGG9ysgqYOK8m0eQZ31h1f2Cghy4lnYdxvn019DKsIjAXEyU9T P6SEpidZ834o3ir78YrznAvLxaYDVkeLXNIg1jqv2nSH+0nuSqas/KKQtIQ22xhrxs8I fWlQ== X-Gm-Message-State: ALoCoQmodw5FNLn9wndTfEUiYhczH2W96gV1nDsIZUtJo4lw7ZlNVZp0v8J2Jg+iA+NTTogGUPBX MIME-Version: 1.0 X-Received: by 10.129.152.82 with SMTP id p79mr8356408ywg.200.1449163186769; Thu, 03 Dec 2015 09:19:46 -0800 (PST) Received: by 10.129.27.14 with HTTP; Thu, 3 Dec 2015 09:19:46 -0800 (PST) In-Reply-To: <56607141.8030209@gmail.com> References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> <56586384.1030504@gmail.com> <565ABE97.5060109@gmail.com> <56607141.8030209@gmail.com> Date: Thu, 3 Dec 2015 17:19:46 +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 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:4002:c07::236 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: Thu, 03 Dec 2015 17:19:55 -0000 > This should be grub_strcmp everywhere, there is no reason to use grub_strncmp. Yes, you are right. Please, find updated patch below > I believe it should be "content" (without final `s') but English is not native Mine not as well, but asked my native colleagues and they confirmed "contents". Also this aligns with Google search. > Could you also add documentation part for it? Yes, sure. Could you give me a hint how the project handles documentation? I didn't find the overall module descriptions, but, maybe, I didn't look very well :) 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 = { }; module = { + name = efivar; + efi = commands/efi/efivar.c; + enable = efi; +}; + +module = { name = blocklist; common = commands/blocklist.c; }; diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.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[] = { + {"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 = 0, + EFI_VAR_UINT8, + EFI_VAR_HEX, + EFI_VAR_DUMP, + EFI_VAR_INVALID = -1 + }; + +static enum efi_var_type +parse_efi_var_type (const char *type) +{ + if (!grub_strcmp (type, "ascii")) + return EFI_VAR_ASCII; + + if (!grub_strcmp (type, "uint8")) + return EFI_VAR_UINT8; + + if (!grub_strcmp (type, "hex")) + return EFI_VAR_HEX; + + if (!grub_strcmp (type, "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] = '\\'; + str[1] = '0'; + return 2; + + case '\a': + str[0] = '\\'; + str[1] = 'a'; + return 2; + + case '\b': + str[0] = '\\'; + str[1] = 'b'; + return 2; + + case '\f': + str[0] = '\\'; + str[1] = 'f'; + return 2; + + case '\n': + str[0] = '\\'; + str[1] = 'n'; + return 2; + + case '\r': + str[0] = '\\'; + str[1] = 'r'; + return 2; + + case '\t': + str[0] = '\\'; + str[1] = 't'; + return 2; + + case '\v': + str[0] = '\\'; + str[1] = 'v'; + return 2; + + default: + str[0] = '.'; /* as in hexdump -C */ + return 1; + } + } + + str[0] = 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 = ctxt->state; + grub_err_t status; + void *efi_var = NULL; + grub_size_t efi_var_size = 0; + enum efi_var_type efi_type = EFI_VAR_HEX; + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; + char *env_var = NULL; + grub_size_t i; + char *ptr; + + if (1 != argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + if (state[0].set) + efi_type = parse_efi_var_type (state[0].arg); + + if (EFI_VAR_INVALID == efi_type) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier")); + + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); + if (!efi_var || !efi_var_size) + { + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); + goto err; + } + + switch (efi_type) + { + case EFI_VAR_ASCII: + env_var = grub_malloc (efi_var_size * 2 + 1); + if (!env_var) + { + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + break; + } + + ptr = env_var; + + for (i = 0; i < efi_var_size; i++) + ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); + *ptr = '\0'; + break; + + case EFI_VAR_UINT8: + env_var = grub_malloc (4); + if (!env_var) + { + status = 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 = grub_malloc (efi_var_size * 2 + 1); + if (!env_var) + { + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + break; + } + for (i = 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 = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set variable with dump format specifier")); + else + { + hexdump (0, (char *)efi_var, efi_var_size); + status = GRUB_ERR_NONE; + } + break; + + default: + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug in module?)")); + } + + if (efi_type != EFI_VAR_DUMP) + { + if (state[1].set) + status = grub_env_set (state[1].arg, env_var); + else + { + grub_printf ("%s\n", (const char *)env_var); + status = 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 = NULL; + +GRUB_MOD_INIT (efivar) +{ + cmd = 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); +} From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a6fwe-0002vn-Fz for mharc-grub-devel@gnu.org; Wed, 09 Dec 2015 09:42:16 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51637) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a6fwb-0002uX-Ke for grub-devel@gnu.org; Wed, 09 Dec 2015 09:42:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a6fwa-0004ks-1q for grub-devel@gnu.org; Wed, 09 Dec 2015 09:42:13 -0500 Received: from mail-qg0-x22a.google.com ([2607:f8b0:400d:c04::22a]:32929) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a6fwZ-0004ki-Sf for grub-devel@gnu.org; Wed, 09 Dec 2015 09:42:11 -0500 Received: by qgea14 with SMTP id a14so82524074qge.0 for ; Wed, 09 Dec 2015 06:42:11 -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; bh=M/AGaokGbyuFlXlfhOj2J3ArrMgkm3TlYDcCXuYaBt0=; b=g3BjZCp/pY605590pZ73B1+V4eZRbxi/C+m7vVHpZ1ZvSQET6D6P1uunpsCDe/xoI5 COVF9PZpOvZqWt381LfjZWBZEwaRB/iX5MwFbvn1Wv96Ea7FXwmmWZi65nTO5cTlPxkR Jqdop7j75RuNWtoMIV6pjjzclWUySVCx2uQXc= 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; bh=M/AGaokGbyuFlXlfhOj2J3ArrMgkm3TlYDcCXuYaBt0=; b=WwhtukZov1OtMttJQltsLCZXBUxXTLx9TWZP6FW42hdMTdeRaf+F5b3euI9MJmo9CS jGh6h/7/X8z7vDFJySRq//TARhnBzK6xKt0a4SaYf+zZCRxMWWpb1iXj9ihLlHwXnk8w SpU1RQcvZcA68PGhxGZydZb0Mwj4OisGsvq//fZtmkiiFD4qAfKdZetfCFZx6VC/3bGh LcVVTrsjhixHc6GXFDRwGZz6lQcggN7meBd8C3QU8UDe5FDIIxfet5i5NGVTlKRVTVaa eEw7VCw5iL1CK49ISjc22zL+CiFlCvIR63aEy7qGsmqWWBiRHAaoiVU+6X0x3DWjQkh8 CGOA== X-Gm-Message-State: ALoCoQkrZuQooCcy9KawfIt9KPiqcqf8p3uacsa33dLf3vMj48Zuhp9MCEKLnBBXJqk26AQH3r+K8JLZkY9+516pRiiQ8UIsPayaHfUJoNDLFgqGoCuCsrk= MIME-Version: 1.0 X-Received: by 10.129.102.193 with SMTP id a184mr669594ywc.7.1449672130847; Wed, 09 Dec 2015 06:42:10 -0800 (PST) Received: by 10.129.27.14 with HTTP; Wed, 9 Dec 2015 06:42:10 -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> <56607141.8030209@gmail.com> Date: Wed, 9 Dec 2015 14:42:10 +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 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c04::22a 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, 09 Dec 2015 14:42:15 -0000 Is this still considered? On Thu, Dec 3, 2015 at 5:19 PM, Ignat Korchagin wrote: >> This should be grub_strcmp everywhere, there is no reason to use grub_strncmp. > Yes, you are right. Please, find updated patch below > >> I believe it should be "content" (without final `s') but English is not native > Mine not as well, but asked my native colleagues and they confirmed > "contents". Also this aligns with Google search. > >> Could you also add documentation part for it? > Yes, sure. Could you give me a hint how the project handles > documentation? I didn't find the overall module descriptions, but, > maybe, I didn't look very well :) > > 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 = { > }; > > module = { > + name = efivar; > + efi = commands/efi/efivar.c; > + enable = efi; > +}; > + > +module = { > name = blocklist; > common = commands/blocklist.c; > }; > diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.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[] = { > + {"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 = 0, > + EFI_VAR_UINT8, > + EFI_VAR_HEX, > + EFI_VAR_DUMP, > + EFI_VAR_INVALID = -1 > + }; > + > +static enum efi_var_type > +parse_efi_var_type (const char *type) > +{ > + if (!grub_strcmp (type, "ascii")) > + return EFI_VAR_ASCII; > + > + if (!grub_strcmp (type, "uint8")) > + return EFI_VAR_UINT8; > + > + if (!grub_strcmp (type, "hex")) > + return EFI_VAR_HEX; > + > + if (!grub_strcmp (type, "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] = '\\'; > + str[1] = '0'; > + return 2; > + > + case '\a': > + str[0] = '\\'; > + str[1] = 'a'; > + return 2; > + > + case '\b': > + str[0] = '\\'; > + str[1] = 'b'; > + return 2; > + > + case '\f': > + str[0] = '\\'; > + str[1] = 'f'; > + return 2; > + > + case '\n': > + str[0] = '\\'; > + str[1] = 'n'; > + return 2; > + > + case '\r': > + str[0] = '\\'; > + str[1] = 'r'; > + return 2; > + > + case '\t': > + str[0] = '\\'; > + str[1] = 't'; > + return 2; > + > + case '\v': > + str[0] = '\\'; > + str[1] = 'v'; > + return 2; > + > + default: > + str[0] = '.'; /* as in hexdump -C */ > + return 1; > + } > + } > + > + str[0] = 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 = ctxt->state; > + grub_err_t status; > + void *efi_var = NULL; > + grub_size_t efi_var_size = 0; > + enum efi_var_type efi_type = EFI_VAR_HEX; > + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; > + char *env_var = NULL; > + grub_size_t i; > + char *ptr; > + > + if (1 != argc) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); > + > + if (state[0].set) > + efi_type = parse_efi_var_type (state[0].arg); > + > + if (EFI_VAR_INVALID == efi_type) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier")); > + > + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); > + if (!efi_var || !efi_var_size) > + { > + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); > + goto err; > + } > + > + switch (efi_type) > + { > + case EFI_VAR_ASCII: > + env_var = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + break; > + } > + > + ptr = env_var; > + > + for (i = 0; i < efi_var_size; i++) > + ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); > + *ptr = '\0'; > + break; > + > + case EFI_VAR_UINT8: > + env_var = grub_malloc (4); > + if (!env_var) > + { > + status = 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 = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + break; > + } > + for (i = 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 = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set > variable with dump format specifier")); > + else > + { > + hexdump (0, (char *)efi_var, efi_var_size); > + status = GRUB_ERR_NONE; > + } > + break; > + > + default: > + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug > in module?)")); > + } > + > + if (efi_type != EFI_VAR_DUMP) > + { > + if (state[1].set) > + status = grub_env_set (state[1].arg, env_var); > + else > + { > + grub_printf ("%s\n", (const char *)env_var); > + status = 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 = NULL; > + > +GRUB_MOD_INIT (efivar) > +{ > + cmd = 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); > +} From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a7ffi-0001fT-A1 for mharc-grub-devel@gnu.org; Sat, 12 Dec 2015 03:36:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33609) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a7fff-0001fE-Bz for grub-devel@gnu.org; Sat, 12 Dec 2015 03:36:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a7ffa-0001ST-BT for grub-devel@gnu.org; Sat, 12 Dec 2015 03:36:51 -0500 Received: from mail-lf0-x229.google.com ([2a00:1450:4010:c07::229]:35616) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a7ffZ-0001SN-Vp for grub-devel@gnu.org; Sat, 12 Dec 2015 03:36:46 -0500 Received: by lfdl133 with SMTP id l133so92062678lfd.2 for ; Sat, 12 Dec 2015 00:36:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type:content-transfer-encoding; bh=qhiGfMlNHJcCkwBx3EZahwLAv/0Ds1z+wDqWtioGPKg=; b=S2kBcQ+Cf/q9z0JqaAXt+wrvIW471mtypyVUA6bOztckBnbrD2F/J5acw5fPJ3dldk HVsmXz/1aIR1H51Ze99WGR9J9qkZZzUQKRPfWUhg7Q0u6zZi762so+vLPBVubMbx+a6G BcB33ifUzOf63MHocQdnRPi2yMgKpK7bXCl9JJ0vZ1Liztn1CPdltW8pAZcJf6ZZUR2e 98m4ql70JVQAnLXY5HAY31cwD8Ecq70zjOzfB1P0AI2yvN8XIURgJx0c7PjVXv7LYLKu K+r1juv44Au24NuwY0ZQcqu4Rkl1zt+0rYvFHw7Uj/+WvEVrWOiuq1n8ZFff1p8amVtU fRTg== X-Received: by 10.25.166.15 with SMTP id p15mr8386499lfe.128.1449909405008; Sat, 12 Dec 2015 00:36:45 -0800 (PST) Received: from [192.168.1.41] (ppp91-76-25-247.pppoe.mtu-net.ru. [91.76.25.247]) by smtp.gmail.com with ESMTPSA id t82sm3852062lfe.14.2015.12.12.00.36.43 for (version=TLSv1/SSLv3 cipher=OTHER); Sat, 12 Dec 2015 00:36:43 -0800 (PST) Subject: Re: Grub get and set efi variables To: grub-devel@gnu.org References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> <56586384.1030504@gmail.com> <565ABE97.5060109@gmail.com> <56607141.8030209@gmail.com> From: Andrei Borzenkov X-Enigmail-Draft-Status: N1110 Message-ID: <566BDC9A.2080501@gmail.com> Date: Sat, 12 Dec 2015 11:36:42 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:4010:c07::229 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: Sat, 12 Dec 2015 08:36:53 -0000 03.12.2015 20:19, Ignat Korchagin пишет: >> This should be grub_strcmp everywhere, there is no reason to use grub_strncmp. > Yes, you are right. Please, find updated patch below > >> I believe it should be "content" (without final `s') but English is not native > Mine not as well, but asked my native colleagues and they confirmed > "contents". Also this aligns with Google search. > >> Could you also add documentation part for it? > Yes, sure. Could you give me a hint how the project handles > documentation? I didn't find the overall module descriptions, but, > maybe, I didn't look very well :) > Documentation is maintained in texinfo format in doc/grub.texi. It is lacking, but there is list of available commands with index, so just adding it would be good. It should ideally be a bit more verbose (examples are welcome) than usage printed at run time. > 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 = { > }; > > module = { > + name = efivar; > + efi = commands/efi/efivar.c; > + enable = efi; > +}; > + > +module = { > name = blocklist; > common = commands/blocklist.c; > }; > diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.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[] = { > + {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR in > specific format (hex, uint8, ascii, dump). Default: hex."), Do we really need unit8 at all? "hex" already provides exactly the same functionality, not? Do you think there are cases when uint8 is really required? If we remove unit8, this becomes really "Display EFI_VAR" not "Parse EFI_VAR", as no parsing really happens. > 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 = 0, > + EFI_VAR_UINT8, > + EFI_VAR_HEX, > + EFI_VAR_DUMP, > + EFI_VAR_INVALID = -1 > + }; > + > +static enum efi_var_type > +parse_efi_var_type (const char *type) > +{ > + if (!grub_strcmp (type, "ascii")) > + return EFI_VAR_ASCII; > + > + if (!grub_strcmp (type, "uint8")) > + return EFI_VAR_UINT8; > + > + if (!grub_strcmp (type, "hex")) > + return EFI_VAR_HEX; > + > + if (!grub_strcmp (type, "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] = '\\'; > + str[1] = '0'; > + return 2; > + > + case '\a': > + str[0] = '\\'; > + str[1] = 'a'; > + return 2; > + > + case '\b': > + str[0] = '\\'; > + str[1] = 'b'; > + return 2; > + > + case '\f': > + str[0] = '\\'; > + str[1] = 'f'; > + return 2; > + > + case '\n': > + str[0] = '\\'; > + str[1] = 'n'; > + return 2; > + > + case '\r': > + str[0] = '\\'; > + str[1] = 'r'; > + return 2; > + > + case '\t': > + str[0] = '\\'; > + str[1] = 't'; > + return 2; > + > + case '\v': > + str[0] = '\\'; > + str[1] = 'v'; > + return 2; > + > + default: > + str[0] = '.'; /* as in hexdump -C */ > + return 1; > + } > + } > + > + str[0] = 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 = ctxt->state; > + grub_err_t status; > + void *efi_var = NULL; > + grub_size_t efi_var_size = 0; > + enum efi_var_type efi_type = EFI_VAR_HEX; > + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; > + char *env_var = NULL; > + grub_size_t i; > + char *ptr; > + > + if (1 != argc) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); > + > + if (state[0].set) > + efi_type = parse_efi_var_type (state[0].arg); > + > + if (EFI_VAR_INVALID == efi_type) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier")); > + > + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); > + if (!efi_var || !efi_var_size) > + { > + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); > + goto err; > + } > + > + switch (efi_type) > + { > + case EFI_VAR_ASCII: > + env_var = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + break; goto err; see below > + } > + > + ptr = env_var; > + > + for (i = 0; i < efi_var_size; i++) > + ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); > + *ptr = '\0'; > + break; > + > + case EFI_VAR_UINT8: > + env_var = grub_malloc (4); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + break; > + } > + grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var)); Assuming uint8 remains - should not you check that variable size is exactly 1 byte in this case? > + break; > + > + case EFI_VAR_HEX: > + env_var = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + break; goto err > + } > + for (i = 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 = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set > variable with dump format specifier")); > + else > + { > + hexdump (0, (char *)efi_var, efi_var_size); > + status = GRUB_ERR_NONE; > + } > + break; > + > + default: > + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug > in module?)")); goto err > + } > + > + if (efi_type != EFI_VAR_DUMP) > + { > + if (state[1].set) > + status = grub_env_set (state[1].arg, env_var); > + else > + { > + grub_printf ("%s\n", (const char *)env_var); > + status = GRUB_ERR_NONE; > + } > + } > + In OOM case you access NULL pointer here. > +err: > + > + if (env_var) > + grub_free (env_var); > + > + if (efi_var) > + grub_free (efi_var); > + grub_free already checks for NULL, no need to do it extra. > + return status; > +} > + > +static grub_extcmd_t cmd = NULL; > + > +GRUB_MOD_INIT (efivar) > +{ > + cmd = 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); > +} > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel > From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a8Qzb-00050E-Of for mharc-grub-devel@gnu.org; Mon, 14 Dec 2015 06:08:35 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34318) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a8QzX-0004zZ-8s for grub-devel@gnu.org; Mon, 14 Dec 2015 06:08:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a8QzV-00023H-Je for grub-devel@gnu.org; Mon, 14 Dec 2015 06:08:31 -0500 Received: from mail-qk0-x236.google.com ([2607:f8b0:400d:c09::236]:34278) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a8QzV-00023D-EG for grub-devel@gnu.org; Mon, 14 Dec 2015 06:08:29 -0500 Received: by qkdp187 with SMTP id p187so129080675qkd.1 for ; Mon, 14 Dec 2015 03:08:29 -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; bh=1t68FIYVOdMGyZuFsP5+bhLnPqJ9yXe5LS5IYhJOWOc=; b=FTx5QDQCx6FYyOm3nv7W4PMYA3OgZaNoBnDwypClkTD989rxtaLBzEKTLXIn6YZqhN S1+NI3lgZncrpq0gYhi/5vPSIU06+wrHu8tZ6cOb8QqasiUIcew3Q2Zu7/jWgUmxjl6X lFGuSkKyfRQlkXDA5OFCYBpXsbdTFsD2JUmYs= 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; bh=1t68FIYVOdMGyZuFsP5+bhLnPqJ9yXe5LS5IYhJOWOc=; b=EWwaLpnui0IzPpYVrmi6HMSPZAC5yMBB4/dhOx20wujSOdrGR27kINsftHSzw7N2P0 OUVg/HXv4hTrJtCR72u3u6Sh3rlB9D65KBqcfji1l2wo2XheXLJdVEFFZ2Y06Lef1ISO m7JTDG1CGdcsSlbTgrqutv5LV8f7LvWtrW8ImvDOyMiKgRcORhF4dfSEb9cokUQP9M1c Ie1tPhq66m1zlL/cvtOZaXbkWAHLRAIsQomARILVEHEUExOCX1eSPwvfdt1EwvCoyZME JlfwLT8PUXJB4Gq2YfrCtQNcO4jAoGu/PgcKjD7aCdH/xQq3KGODLyWL4IauvuHTxF7D rAmA== X-Gm-Message-State: ALoCoQm/R1Nux+iPRXoSno/+bo43Bu1jh3LjFW8udj3ZDBuf4La4wcuPa5OW3VmsToE9XgrPVr7XTt1RpQfSsmk2FaC57mmNVjmMXvF/vwt8lh05MmIkYlk= MIME-Version: 1.0 X-Received: by 10.129.158.15 with SMTP id v15mr7458741ywg.236.1450091308864; Mon, 14 Dec 2015 03:08:28 -0800 (PST) Received: by 10.129.73.19 with HTTP; Mon, 14 Dec 2015 03:08:28 -0800 (PST) In-Reply-To: <566BDC9A.2080501@gmail.com> References: <563999B9.7020108@gmail.com> <5643845E.9060204@gmail.com> <5646B275.5040707@gmail.com> <56586384.1030504@gmail.com> <565ABE97.5060109@gmail.com> <56607141.8030209@gmail.com> <566BDC9A.2080501@gmail.com> Date: Mon, 14 Dec 2015 11:08:28 +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 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c09::236 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: Mon, 14 Dec 2015 11:08:32 -0000 > Assuming uint8 remains - should not you check that variable size is exactly 1 byte in this case? There are reports of a buggy firmware returning 4 bytes size for uint8 variables, however did not encounter them myself. > Do we really need unit8 at all? "hex" already provides exactly the same functionality, not? Do you think there are cases when uint8 is really required? Well, when checking for SecureBoot variable in grub configuration file hex mode makes it look weird and creates a point of confusion. For example to check if SecureBoot (suppose the result of the our command is stored in secure_boot env variable in hex mode) is enabled one should write: if [ secure_boot = "01" ] ... uint8 just allows to do a more straightforward config if [ secure_boot = 1] - this case would be false for hex mode - possible security breach ... Added goto err in the module as pointed, see patch below. I will do a follow-up patch for documentation once we get this confirmed. 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 = { }; module = { + name = efivar; + efi = commands/efi/efivar.c; + enable = efi; +}; + +module = { name = blocklist; common = commands/blocklist.c; }; diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.c new file mode 100644 index 0000000..7f5a957 --- /dev/null +++ b/grub-core/commands/efi/efivar.c @@ -0,0 +1,251 @@ +/* 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[] = { + {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR in specific format (hex, uint8, ascii, raw, 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 = 0, + EFI_VAR_RAW, + EFI_VAR_UINT8, + EFI_VAR_HEX, + EFI_VAR_DUMP, + EFI_VAR_INVALID = -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, "raw", sizeof("raw"))) + 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] = '\\'; + str[1] = '0'; + return 2; + + case '\a': + str[0] = '\\'; + str[1] = 'a'; + return 2; + + case '\b': + str[0] = '\\'; + str[1] = 'b'; + return 2; + + case '\f': + str[0] = '\\'; + str[1] = 'f'; + return 2; + + case '\n': + str[0] = '\\'; + str[1] = 'n'; + return 2; + + case '\r': + str[0] = '\\'; + str[1] = 'r'; + return 2; + + case '\t': + str[0] = '\\'; + str[1] = 't'; + return 2; + + case '\v': + str[0] = '\\'; + str[1] = 'v'; + return 2; + + default: + str[0] = '.'; /* as in hexdump -C */ + return 1; + } + } + + str[0] = 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 = ctxt->state; + grub_err_t status; + void *efi_var = NULL; + grub_size_t efi_var_size = 0; + enum efi_var_type efi_type = EFI_VAR_HEX; + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; + char *env_var = NULL; + grub_size_t i; + char *ptr; + + if (1 != argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + if (state[0].set) + efi_type = parse_efi_var_type (state[0].arg); + + if (EFI_VAR_INVALID == efi_type) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier")); + + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); + if (!efi_var || !efi_var_size) + { + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); + goto err; + } + + switch (efi_type) + { + case EFI_VAR_ASCII: + env_var = grub_malloc (efi_var_size * 2 + 1); + if (!env_var) + { + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto err; + } + + ptr = env_var; + + for (i = 0; i < efi_var_size; i++) + ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); + *ptr = '\0'; + break; + + case EFI_VAR_RAW: + env_var = grub_malloc (efi_var_size + 1); + if (!env_var) + { + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto err; + } + grub_memcpy (env_var, efi_var, efi_var_size); + env_var[efi_var_size] = '\0'; + break; + + case EFI_VAR_UINT8: + env_var = grub_malloc (4); + if (!env_var) + { + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto err; + } + grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var)); + break; + + case EFI_VAR_HEX: + env_var = grub_malloc (efi_var_size * 2 + 1); + if (!env_var) + { + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto err; + } + for (i = 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 = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set variable with dump format specifier")); + else + { + hexdump (0, (char *)efi_var, efi_var_size); + status = GRUB_ERR_NONE; + } + break; + + default: + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug in module?)")); + goto err; + } + + if (efi_type != EFI_VAR_DUMP) + { + if (state[1].set) + status = grub_env_set (state[1].arg, env_var); + else + { + grub_printf ("%s\n", (const char *)env_var); + status = GRUB_ERR_NONE; + } + } + +err: + + grub_free (env_var); + grub_free (efi_var); + + return status; +} + +static grub_extcmd_t cmd = NULL; + +GRUB_MOD_INIT (efivar) +{ + cmd = 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); +} From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a8R7v-0006Hb-7y for mharc-grub-devel@gnu.org; Mon, 14 Dec 2015 06:17:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35870) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a8R7q-0006GK-PZ for grub-devel@gnu.org; Mon, 14 Dec 2015 06:17:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a8R7o-0004IH-FJ for grub-devel@gnu.org; Mon, 14 Dec 2015 06:17:06 -0500 Received: from mail-qk0-x22c.google.com ([2607:f8b0:400d:c09::22c]:35424) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a8R7o-0004Hf-9o for grub-devel@gnu.org; Mon, 14 Dec 2015 06:17:04 -0500 Received: by qkfb125 with SMTP id b125so128978261qkf.2 for ; Mon, 14 Dec 2015 03:17:04 -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; bh=gfgcAmxVwnQ6boPpcnb7/JWC0WNslQGm/QnLGcbSk74=; b=qq1yrNzpjdp2lOET011GomgZD7FVCKV3IgMBppcg+U96M3ohH4nqcD6H4EXY/mddfF X+tAtVRFlOFhmYk4ZGprUpvh5Q3EoULIDzxFTwtXHjyJgKl4Xpi8J4SiMPHcx1ZAIWsN LCXCAbIm3RkPShaNz3kD+gEoU1cIh86G7ud9w= 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; bh=gfgcAmxVwnQ6boPpcnb7/JWC0WNslQGm/QnLGcbSk74=; b=DAOTu4LCUPTimnUCmYFTIvZyIVDgD/JXgtDyjQWKegcfPasw8gWRwn4C6Rjy1/H0ME mjfkDYlSjjePVoh54JooZI6r2qt2VDqXofPIqrsvSrfuXRZsmC5U50ksih7RSYwR5mlM Zwu4MiEgqVcsfn+99e6JgwOb/6yjX3zpbhrODN4gf8lhcFq8d1siGqIX21Mt4Ab7vZlf GnpAuCAAga7VrXeydtKFkvcuiNXHiJ1wcF5/Cla+bC7EzBcS2z/WxtxYOcNFdPsT19PT UtW9Xjzu0LNCMUOi4tJTdEB858Qg6yCl4ytd0i+346TYHKJ5dzR6ia6AqcKAl5dwxxMM czfA== X-Gm-Message-State: ALoCoQmTsPd59OryI2M2s1mJ2IPcLBt6jmfwgUsh0Znx4nL5iZwSnLdDSsnKAYJ2UF3G2ZeP4Fdhg7ApAr8gma/DwgGdBi3i77eCYgrXW/5PqJlHpbTPYV0= MIME-Version: 1.0 X-Received: by 10.129.158.15 with SMTP id v15mr7483134ywg.236.1450091823911; Mon, 14 Dec 2015 03:17:03 -0800 (PST) Received: by 10.129.73.19 with HTTP; Mon, 14 Dec 2015 03:17:03 -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> <56607141.8030209@gmail.com> <566BDC9A.2080501@gmail.com> Date: Mon, 14 Dec 2015 11:17:03 +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 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c09::22c 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: Mon, 14 Dec 2015 11:17:09 -0000 Sorry, pasted wrong file. Here is the correct one: 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 = { }; module = { + name = efivar; + efi = commands/efi/efivar.c; + enable = efi; +}; + +module = { name = blocklist; common = commands/blocklist.c; }; diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.c new file mode 100644 index 0000000..7fe7bda --- /dev/null +++ b/grub-core/commands/efi/efivar.c @@ -0,0 +1,236 @@ +/* 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[] = { + {"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 = 0, + EFI_VAR_UINT8, + EFI_VAR_HEX, + EFI_VAR_DUMP, + EFI_VAR_INVALID = -1 + }; + +static enum efi_var_type +parse_efi_var_type (const char *type) +{ + if (!grub_strcmp (type, "ascii")) + return EFI_VAR_ASCII; + + if (!grub_strcmp (type, "uint8")) + return EFI_VAR_UINT8; + + if (!grub_strcmp (type, "hex")) + return EFI_VAR_HEX; + + if (!grub_strcmp (type, "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] = '\\'; + str[1] = '0'; + return 2; + + case '\a': + str[0] = '\\'; + str[1] = 'a'; + return 2; + + case '\b': + str[0] = '\\'; + str[1] = 'b'; + return 2; + + case '\f': + str[0] = '\\'; + str[1] = 'f'; + return 2; + + case '\n': + str[0] = '\\'; + str[1] = 'n'; + return 2; + + case '\r': + str[0] = '\\'; + str[1] = 'r'; + return 2; + + case '\t': + str[0] = '\\'; + str[1] = 't'; + return 2; + + case '\v': + str[0] = '\\'; + str[1] = 'v'; + return 2; + + default: + str[0] = '.'; /* as in hexdump -C */ + return 1; + } + } + + str[0] = 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 = ctxt->state; + grub_err_t status; + void *efi_var = NULL; + grub_size_t efi_var_size = 0; + enum efi_var_type efi_type = EFI_VAR_HEX; + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; + char *env_var = NULL; + grub_size_t i; + char *ptr; + + if (1 != argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + if (state[0].set) + efi_type = parse_efi_var_type (state[0].arg); + + if (EFI_VAR_INVALID == efi_type) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier")); + + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); + if (!efi_var || !efi_var_size) + { + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); + goto err; + } + + switch (efi_type) + { + case EFI_VAR_ASCII: + env_var = grub_malloc (efi_var_size * 2 + 1); + if (!env_var) + { + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto err; + } + + ptr = env_var; + + for (i = 0; i < efi_var_size; i++) + ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); + *ptr = '\0'; + break; + + case EFI_VAR_UINT8: + env_var = grub_malloc (4); + if (!env_var) + { + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto err; + } + grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var)); + break; + + case EFI_VAR_HEX: + env_var = grub_malloc (efi_var_size * 2 + 1); + if (!env_var) + { + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto err; + } + for (i = 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 = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set variable with dump format specifier")); + else + { + hexdump (0, (char *)efi_var, efi_var_size); + status = GRUB_ERR_NONE; + } + break; + + default: + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug in module?)")); + goto err; + } + + if (efi_type != EFI_VAR_DUMP) + { + if (state[1].set) + status = grub_env_set (state[1].arg, env_var); + else + { + grub_printf ("%s\n", (const char *)env_var); + status = GRUB_ERR_NONE; + } + } + +err: + + grub_free (env_var); + grub_free (efi_var); + + return status; +} + +static grub_extcmd_t cmd = NULL; + +GRUB_MOD_INIT (efivar) +{ + cmd = 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 Mon, Dec 14, 2015 at 11:08 AM, Ignat Korchagin wrote: >> Assuming uint8 remains - should not you check that variable size is exactly 1 byte in this case? > There are reports of a buggy firmware returning 4 bytes size for uint8 > variables, however did not encounter them myself. > >> Do we really need unit8 at all? "hex" already provides exactly the same functionality, not? Do you think there are cases when uint8 is really required? > Well, when checking for SecureBoot variable in grub configuration file > hex mode makes it look weird and creates a point of confusion. For > example to check if SecureBoot (suppose the result of the our command > is stored in secure_boot env variable in hex mode) is enabled one > should write: > if [ secure_boot = "01" ] > ... > uint8 just allows to do a more straightforward config > if [ secure_boot = 1] - this case would be false for hex mode - > possible security breach > ... > > Added goto err in the module as pointed, see patch below. I will do a > follow-up patch for documentation once we get this confirmed. > > 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 = { > }; > > module = { > + name = efivar; > + efi = commands/efi/efivar.c; > + enable = efi; > +}; > + > +module = { > name = blocklist; > common = commands/blocklist.c; > }; > diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.c > new file mode 100644 > index 0000000..7f5a957 > --- /dev/null > +++ b/grub-core/commands/efi/efivar.c > @@ -0,0 +1,251 @@ > +/* 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[] = { > + {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR in > specific format (hex, uint8, ascii, raw, 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 = 0, > + EFI_VAR_RAW, > + EFI_VAR_UINT8, > + EFI_VAR_HEX, > + EFI_VAR_DUMP, > + EFI_VAR_INVALID = -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, "raw", sizeof("raw"))) > + 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] = '\\'; > + str[1] = '0'; > + return 2; > + > + case '\a': > + str[0] = '\\'; > + str[1] = 'a'; > + return 2; > + > + case '\b': > + str[0] = '\\'; > + str[1] = 'b'; > + return 2; > + > + case '\f': > + str[0] = '\\'; > + str[1] = 'f'; > + return 2; > + > + case '\n': > + str[0] = '\\'; > + str[1] = 'n'; > + return 2; > + > + case '\r': > + str[0] = '\\'; > + str[1] = 'r'; > + return 2; > + > + case '\t': > + str[0] = '\\'; > + str[1] = 't'; > + return 2; > + > + case '\v': > + str[0] = '\\'; > + str[1] = 'v'; > + return 2; > + > + default: > + str[0] = '.'; /* as in hexdump -C */ > + return 1; > + } > + } > + > + str[0] = 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 = ctxt->state; > + grub_err_t status; > + void *efi_var = NULL; > + grub_size_t efi_var_size = 0; > + enum efi_var_type efi_type = EFI_VAR_HEX; > + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; > + char *env_var = NULL; > + grub_size_t i; > + char *ptr; > + > + if (1 != argc) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); > + > + if (state[0].set) > + efi_type = parse_efi_var_type (state[0].arg); > + > + if (EFI_VAR_INVALID == efi_type) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier")); > + > + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); > + if (!efi_var || !efi_var_size) > + { > + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); > + goto err; > + } > + > + switch (efi_type) > + { > + case EFI_VAR_ASCII: > + env_var = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + goto err; > + } > + > + ptr = env_var; > + > + for (i = 0; i < efi_var_size; i++) > + ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); > + *ptr = '\0'; > + break; > + > + case EFI_VAR_RAW: > + env_var = grub_malloc (efi_var_size + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + goto err; > + } > + grub_memcpy (env_var, efi_var, efi_var_size); > + env_var[efi_var_size] = '\0'; > + break; > + > + case EFI_VAR_UINT8: > + env_var = grub_malloc (4); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + goto err; > + } > + grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var)); > + break; > + > + case EFI_VAR_HEX: > + env_var = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); > + goto err; > + } > + for (i = 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 = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set > variable with dump format specifier")); > + else > + { > + hexdump (0, (char *)efi_var, efi_var_size); > + status = GRUB_ERR_NONE; > + } > + break; > + > + default: > + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug > in module?)")); > + goto err; > + } > + > + if (efi_type != EFI_VAR_DUMP) > + { > + if (state[1].set) > + status = grub_env_set (state[1].arg, env_var); > + else > + { > + grub_printf ("%s\n", (const char *)env_var); > + status = GRUB_ERR_NONE; > + } > + } > + > +err: > + > + grub_free (env_var); > + grub_free (efi_var); > + > + return status; > +} > + > +static grub_extcmd_t cmd = NULL; > + > +GRUB_MOD_INIT (efivar) > +{ > + cmd = 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); > +} From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1aPBrt-0005HR-Hi for mharc-grub-devel@gnu.org; Fri, 29 Jan 2016 11:25:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57526) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aPBro-0005HD-78 for grub-devel@gnu.org; Fri, 29 Jan 2016 11:25:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aPBrk-0004LM-CW for grub-devel@gnu.org; Fri, 29 Jan 2016 11:25:48 -0500 Received: from mail-yk0-x22a.google.com ([2607:f8b0:4002:c07::22a]:35105) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aPBrk-0004LI-48 for grub-devel@gnu.org; Fri, 29 Jan 2016 11:25:44 -0500 Received: by mail-yk0-x22a.google.com with SMTP id r207so31071484ykd.2 for ; Fri, 29 Jan 2016 08:25:43 -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; bh=9+IvJ+jM+4zCZlMmmE1SYAqkStIqhZtCO6+O5gaa4Ys=; b=k1wYyM2sbiww0Eb+53Vcd8BAwQ3d4GRBCg9/Gsw8EKDIxBn3cNOLv3BApArwTojVLc 0CqjpeHio/Yqa/QnvweKH0kAxK9F98/2kSJPO4zX05w7hM/PjCedY1nl3HNsTpTGxBZq 1CIL9pYfOnMYiqzNNHpE92lM2w+IQyW6s02Gk= 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; bh=9+IvJ+jM+4zCZlMmmE1SYAqkStIqhZtCO6+O5gaa4Ys=; b=lLqGxxv4Z8fkIpfP1jRffgqiVubGu1BfIhIBpr5lmvbpO/DpU1Xa7tOvTf89MVYkqc Ex+YbR6+dKBIQLHEEUrNpbMMMK6x1geJNKhlF9suWtMsVwYOum+fpbWqWTQ7acnIxgka PcQG52xzH6CD55hG4knUOoFaR58KUYDJNQgu3Y8lvX8krE53Ukuv6Vtx0VikaNk/rk7T hqkcclozYl5dnVKpjNk59tNK9mb6XZvdo02BQENX8rXNDtnGZuR9BRD2F5tcDtNbxeCJ AlvcLoGDQkI6X19T/9JQGDc0uTBuIeEi2/Bfv3UFGdjOixwVKVLSg0qDUsnEbW+KEZYy Kn9g== X-Gm-Message-State: AG10YORHR598mF0WMlp1s/780DdjiAFNg0hCTfeUvgNUWJhuSipMg22AstqHkO1edkZkyWyTM/nkVtgSQGq1LPLZ MIME-Version: 1.0 X-Received: by 10.129.134.69 with SMTP id w66mr5466805ywf.193.1454084743256; Fri, 29 Jan 2016 08:25:43 -0800 (PST) Received: by 10.13.198.71 with HTTP; Fri, 29 Jan 2016 08:25:43 -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> <56607141.8030209@gmail.com> <566BDC9A.2080501@gmail.com> Date: Fri, 29 Jan 2016 16:25:43 +0000 Message-ID: Subject: Re: Grub get and set efi variables From: Ignat Korchagin To: The development of GNU GRUB Content-Type: multipart/alternative; boundary=001a114f098c988bba052a7b7c7d X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:4002:c07::22a 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: Fri, 29 Jan 2016 16:25:51 -0000 --001a114f098c988bba052a7b7c7d Content-Type: text/plain; charset=UTF-8 Hi. Are we still considering this? On Mon, Dec 14, 2015 at 11:17 AM, Ignat Korchagin wrote: > Sorry, pasted wrong file. Here is the correct one: > > 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 = { > }; > > module = { > + name = efivar; > + efi = commands/efi/efivar.c; > + enable = efi; > +}; > + > +module = { > name = blocklist; > common = commands/blocklist.c; > }; > diff --git a/grub-core/commands/efi/efivar.c > b/grub-core/commands/efi/efivar.c > new file mode 100644 > index 0000000..7fe7bda > --- /dev/null > +++ b/grub-core/commands/efi/efivar.c > @@ -0,0 +1,236 @@ > +/* 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[] = { > + {"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 = 0, > + EFI_VAR_UINT8, > + EFI_VAR_HEX, > + EFI_VAR_DUMP, > + EFI_VAR_INVALID = -1 > + }; > + > +static enum efi_var_type > +parse_efi_var_type (const char *type) > +{ > + if (!grub_strcmp (type, "ascii")) > + return EFI_VAR_ASCII; > + > + if (!grub_strcmp (type, "uint8")) > + return EFI_VAR_UINT8; > + > + if (!grub_strcmp (type, "hex")) > + return EFI_VAR_HEX; > + > + if (!grub_strcmp (type, "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] = '\\'; > + str[1] = '0'; > + return 2; > + > + case '\a': > + str[0] = '\\'; > + str[1] = 'a'; > + return 2; > + > + case '\b': > + str[0] = '\\'; > + str[1] = 'b'; > + return 2; > + > + case '\f': > + str[0] = '\\'; > + str[1] = 'f'; > + return 2; > + > + case '\n': > + str[0] = '\\'; > + str[1] = 'n'; > + return 2; > + > + case '\r': > + str[0] = '\\'; > + str[1] = 'r'; > + return 2; > + > + case '\t': > + str[0] = '\\'; > + str[1] = 't'; > + return 2; > + > + case '\v': > + str[0] = '\\'; > + str[1] = 'v'; > + return 2; > + > + default: > + str[0] = '.'; /* as in hexdump -C */ > + return 1; > + } > + } > + > + str[0] = 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 = ctxt->state; > + grub_err_t status; > + void *efi_var = NULL; > + grub_size_t efi_var_size = 0; > + enum efi_var_type efi_type = EFI_VAR_HEX; > + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; > + char *env_var = NULL; > + grub_size_t i; > + char *ptr; > + > + if (1 != argc) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument > expected")); > + > + if (state[0].set) > + efi_type = parse_efi_var_type (state[0].arg); > + > + if (EFI_VAR_INVALID == efi_type) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format > specifier")); > + > + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); > + if (!efi_var || !efi_var_size) > + { > + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read > variable")); > + goto err; > + } > + > + switch (efi_type) > + { > + case EFI_VAR_ASCII: > + env_var = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of > memory")); > + goto err; > + } > + > + ptr = env_var; > + > + for (i = 0; i < efi_var_size; i++) > + ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); > + *ptr = '\0'; > + break; > + > + case EFI_VAR_UINT8: > + env_var = grub_malloc (4); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of > memory")); > + goto err; > + } > + grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var)); > + break; > + > + case EFI_VAR_HEX: > + env_var = grub_malloc (efi_var_size * 2 + 1); > + if (!env_var) > + { > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of > memory")); > + goto err; > + } > + for (i = 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 = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set > variable with dump format specifier")); > + else > + { > + hexdump (0, (char *)efi_var, efi_var_size); > + status = GRUB_ERR_NONE; > + } > + break; > + > + default: > + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug > in module?)")); > + goto err; > + } > + > + if (efi_type != EFI_VAR_DUMP) > + { > + if (state[1].set) > + status = grub_env_set (state[1].arg, env_var); > + else > + { > + grub_printf ("%s\n", (const char *)env_var); > + status = GRUB_ERR_NONE; > + } > + } > + > +err: > + > + grub_free (env_var); > + grub_free (efi_var); > + > + return status; > +} > + > +static grub_extcmd_t cmd = NULL; > + > +GRUB_MOD_INIT (efivar) > +{ > + cmd = 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 Mon, Dec 14, 2015 at 11:08 AM, Ignat Korchagin > wrote: > >> Assuming uint8 remains - should not you check that variable size is > exactly 1 byte in this case? > > There are reports of a buggy firmware returning 4 bytes size for uint8 > > variables, however did not encounter them myself. > > > >> Do we really need unit8 at all? "hex" already provides exactly the same > functionality, not? Do you think there are cases when uint8 is really > required? > > Well, when checking for SecureBoot variable in grub configuration file > > hex mode makes it look weird and creates a point of confusion. For > > example to check if SecureBoot (suppose the result of the our command > > is stored in secure_boot env variable in hex mode) is enabled one > > should write: > > if [ secure_boot = "01" ] > > ... > > uint8 just allows to do a more straightforward config > > if [ secure_boot = 1] - this case would be false for hex mode - > > possible security breach > > ... > > > > Added goto err in the module as pointed, see patch below. I will do a > > follow-up patch for documentation once we get this confirmed. > > > > 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 = { > > }; > > > > module = { > > + name = efivar; > > + efi = commands/efi/efivar.c; > > + enable = efi; > > +}; > > + > > +module = { > > name = blocklist; > > common = commands/blocklist.c; > > }; > > diff --git a/grub-core/commands/efi/efivar.c > b/grub-core/commands/efi/efivar.c > > new file mode 100644 > > index 0000000..7f5a957 > > --- /dev/null > > +++ b/grub-core/commands/efi/efivar.c > > @@ -0,0 +1,251 @@ > > +/* 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[] = { > > + {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR in > > specific format (hex, uint8, ascii, raw, 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 = 0, > > + EFI_VAR_RAW, > > + EFI_VAR_UINT8, > > + EFI_VAR_HEX, > > + EFI_VAR_DUMP, > > + EFI_VAR_INVALID = -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, "raw", sizeof("raw"))) > > + 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] = '\\'; > > + str[1] = '0'; > > + return 2; > > + > > + case '\a': > > + str[0] = '\\'; > > + str[1] = 'a'; > > + return 2; > > + > > + case '\b': > > + str[0] = '\\'; > > + str[1] = 'b'; > > + return 2; > > + > > + case '\f': > > + str[0] = '\\'; > > + str[1] = 'f'; > > + return 2; > > + > > + case '\n': > > + str[0] = '\\'; > > + str[1] = 'n'; > > + return 2; > > + > > + case '\r': > > + str[0] = '\\'; > > + str[1] = 'r'; > > + return 2; > > + > > + case '\t': > > + str[0] = '\\'; > > + str[1] = 't'; > > + return 2; > > + > > + case '\v': > > + str[0] = '\\'; > > + str[1] = 'v'; > > + return 2; > > + > > + default: > > + str[0] = '.'; /* as in hexdump -C */ > > + return 1; > > + } > > + } > > + > > + str[0] = 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 = ctxt->state; > > + grub_err_t status; > > + void *efi_var = NULL; > > + grub_size_t efi_var_size = 0; > > + enum efi_var_type efi_type = EFI_VAR_HEX; > > + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; > > + char *env_var = NULL; > > + grub_size_t i; > > + char *ptr; > > + > > + if (1 != argc) > > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument > expected")); > > + > > + if (state[0].set) > > + efi_type = parse_efi_var_type (state[0].arg); > > + > > + if (EFI_VAR_INVALID == efi_type) > > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format > specifier")); > > + > > + efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); > > + if (!efi_var || !efi_var_size) > > + { > > + status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read > variable")); > > + goto err; > > + } > > + > > + switch (efi_type) > > + { > > + case EFI_VAR_ASCII: > > + env_var = grub_malloc (efi_var_size * 2 + 1); > > + if (!env_var) > > + { > > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of > memory")); > > + goto err; > > + } > > + > > + ptr = env_var; > > + > > + for (i = 0; i < efi_var_size; i++) > > + ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); > > + *ptr = '\0'; > > + break; > > + > > + case EFI_VAR_RAW: > > + env_var = grub_malloc (efi_var_size + 1); > > + if (!env_var) > > + { > > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of > memory")); > > + goto err; > > + } > > + grub_memcpy (env_var, efi_var, efi_var_size); > > + env_var[efi_var_size] = '\0'; > > + break; > > + > > + case EFI_VAR_UINT8: > > + env_var = grub_malloc (4); > > + if (!env_var) > > + { > > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of > memory")); > > + goto err; > > + } > > + grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var)); > > + break; > > + > > + case EFI_VAR_HEX: > > + env_var = grub_malloc (efi_var_size * 2 + 1); > > + if (!env_var) > > + { > > + status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of > memory")); > > + goto err; > > + } > > + for (i = 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 = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set > > variable with dump format specifier")); > > + else > > + { > > + hexdump (0, (char *)efi_var, efi_var_size); > > + status = GRUB_ERR_NONE; > > + } > > + break; > > + > > + default: > > + status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug > > in module?)")); > > + goto err; > > + } > > + > > + if (efi_type != EFI_VAR_DUMP) > > + { > > + if (state[1].set) > > + status = grub_env_set (state[1].arg, env_var); > > + else > > + { > > + grub_printf ("%s\n", (const char *)env_var); > > + status = GRUB_ERR_NONE; > > + } > > + } > > + > > +err: > > + > > + grub_free (env_var); > > + grub_free (efi_var); > > + > > + return status; > > +} > > + > > +static grub_extcmd_t cmd = NULL; > > + > > +GRUB_MOD_INIT (efivar) > > +{ > > + cmd = 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); > > +} > --001a114f098c988bba052a7b7c7d Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi. Are we still considering this?

On Mon, Dec 14, 2015 at 11:17 AM, Ignat K= orchagin <ignat@cloudflare.com> wrote:
Sorry, pasted wrong file. Here is the correct one:

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 {
=C2=A0};

=C2=A0module =3D {
+=C2=A0 name =3D efivar;
+=C2=A0 efi =3D commands/efi/efivar.c;
+=C2=A0 enable =3D efi;
+};
+
+module =3D {
=C2=A0 =C2=A0name =3D blocklist;
=C2=A0 =C2=A0common =3D commands/blocklist.c;
=C2=A0};
diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efiva= r.c
new file mode 100644
index 0000000..7fe7bda
--- /dev/null
+++ b/grub-core/commands/efi/efivar.c
@@ -0,0 +1,236 @@
+/* efivar.c - Read EFI global variables. */
+/*
+ *=C2=A0 GRUB=C2=A0 --=C2=A0 GRand Unified Bootloader
+ *=C2=A0 Copyright (C) 2015 Free Software Foundation, Inc.
+ *=C2=A0 Copyright (C) 2015 CloudFlare, Inc.
+ *
+ *=C2=A0 GRUB is free software: you can redistribute it and/or modify
+ *=C2=A0 it under the terms of the GNU General Public License as published= by
+ *=C2=A0 the Free Software Foundation, either version 3 of the License, or=
+ *=C2=A0 (at your option) any later version.
+ *
+ *=C2=A0 GRUB is distributed in the hope that it will be useful,
+ *=C2=A0 but WITHOUT ANY WARRANTY; without even the implied warranty of + *=C2=A0 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.=C2=A0 See th= e
+ *=C2=A0 GNU General Public License for more details.
+ *
+ *=C2=A0 You should have received a copy of the GNU General Public License=
+ *=C2=A0 along with GRUB.=C2=A0 If not, see <http://www.gnu.org/lice= nses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/extcmd.h>
+#include <grub/env.h>
+#include <grub/lib/hexdump.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static const struct grub_arg_option options[] =3D {
+=C2=A0 {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_(&quo= t;Parse EFI_VAR in
specific format (hex, uint8, ascii, dump). Default: hex.")= ,
N_("FORMAT"), ARG_TYPE_STRING},
+=C2=A0 {"set", 's', GRUB_ARG_OPTION_OPTIONAL, N_("S= ave parsed result to
environment variable (does not work with dump)."), N_("ENV_VAR&qu= ot;),
ARG_TYPE_STRING},
+=C2=A0 {0, 0, 0, 0, 0, 0}
+};
+
+enum efi_var_type
+=C2=A0 {
+=C2=A0 =C2=A0 EFI_VAR_ASCII =3D 0,
+=C2=A0 =C2=A0 EFI_VAR_UINT8,
+=C2=A0 =C2=A0 EFI_VAR_HEX,
+=C2=A0 =C2=A0 EFI_VAR_DUMP,
+=C2=A0 =C2=A0 EFI_VAR_INVALID =3D -1
+=C2=A0 };
+
+static enum efi_var_type
+parse_efi_var_type (const char *type)
+{
+=C2=A0 if (!grub_strcmp (type, "ascii"))
+=C2=A0 =C2=A0 return EFI_VAR_ASCII;
+
+=C2=A0 if (!grub_strcmp (type, "uint8"))
+=C2=A0 =C2=A0 return EFI_VAR_UINT8;
+
+=C2=A0 if (!grub_strcmp (type, "hex"))
+=C2=A0 =C2=A0 return EFI_VAR_HEX;
+
+=C2=A0 if (!grub_strcmp (type, "dump"))
+=C2=A0 =C2=A0 return EFI_VAR_DUMP;=
+
+=C2=A0 return EFI_VAR_INVALID;
+}
+
+static int
+grub_print_ascii (char *str, char c)
+{
+=C2=A0 if (grub_iscntrl (c))
+=C2=A0 {
+=C2=A0 =C2=A0 switch (c)
+=C2=A0 =C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\0':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D '0';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\a':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'a';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\b':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'b';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\f':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'f';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\n':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'n';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\r':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'r';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\t':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 't';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\v':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'v';
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 default:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '.'; /* as in hexdum= p -C */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 1;
+=C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 }
+
+=C2=A0 str[0] =3D c;
+=C2=A0 return 1;
+}
+
+static grub_err_t
+grub_cmd_get_efi_var (struct grub_extcmd_context *ctxt,
+=C2=A0 int argc, char **args)
+{
+=C2=A0 struct grub_arg_list *state =3D ctxt->state;
+=C2=A0 grub_err_t status;
+=C2=A0 void *efi_var =3D NULL;
+=C2=A0 grub_size_t efi_var_size =3D 0;
+=C2=A0 enum efi_var_type efi_type =3D EFI_VAR_HEX;
+=C2=A0 grub_efi_guid_t global =3D GRUB_EFI_GLOBAL_VARIABLE_GUID;
+=C2=A0 char *env_var =3D NULL;
+=C2=A0 grub_size_t i;
+=C2=A0 char *ptr;
+
+=C2=A0 if (1 !=3D argc)
+=C2=A0 =C2=A0 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argum= ent expected"));
+
+=C2=A0 if (state[0].set)
+=C2=A0 =C2=A0 efi_type =3D parse_efi_var_type (state[0].arg);
+
+=C2=A0 if (EFI_VAR_INVALID =3D=3D efi_type)
+=C2=A0 =C2=A0 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid f= ormat specifier"));
+
+=C2=A0 efi_var =3D grub_efi_get_variable (args[0], &global, &efi_v= ar_size);
+=C2=A0 if (!efi_var || !efi_var_size)
+=C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_READ_ERROR, N_("= cannot read variable"));
+=C2=A0 =C2=A0 =C2=A0 goto err;
+=C2=A0 =C2=A0 }
+
+=C2=A0 switch (efi_type)
+=C2=A0 {
+=C2=A0 =C2=A0 case EFI_VAR_ASCII:
+=C2=A0 =C2=A0 =C2=A0 env_var =3D grub_malloc (efi_var_size * 2 + 1);
+=C2=A0 =C2=A0 =C2=A0 if (!env_var)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_OUT_OF_= MEMORY, N_("out of memory"));
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 goto err;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 ptr =3D env_var;
+
+=C2=A0 =C2=A0 =C2=A0 for (i =3D 0; i < efi_var_size; i++)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ptr +=3D grub_print_ascii (ptr, ((const char *= )efi_var)[i]);
+=C2=A0 =C2=A0 =C2=A0 *ptr =3D '\0';
+=C2=A0 =C2=A0 =C2=A0 break;
+
+=C2=A0 =C2=A0 case EFI= _VAR_UINT8:
+=C2=A0 =C2=A0 =C2=A0 env_var =3D grub_malloc (4);
+=C2=A0 =C2=A0 =C2=A0 if (!env_var)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_OUT_OF_= MEMORY, N_("out of memory"));
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 goto err;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 grub_snprintf (env_var, 4, "%u", *((grub_ui= nt8_t *)efi_var));
+=C2=A0 =C2=A0 =C2=A0 break;
+
+=C2=A0 =C2=A0 case EFI_VAR_HEX:
+=C2=A0 =C2=A0 =C2=A0 env_var =3D grub_malloc (efi_var_size * 2 + 1);
+=C2=A0 =C2=A0 =C2=A0 if (!env_var)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_OUT_OF_= MEMORY, N_("out of memory"));
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 goto err;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 for (i =3D 0; i < efi_var_size; i++)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 grub_snprintf (env_var + (i * 2), 3, "%02= x", ((grub_uint8_t
*)efi_var)[i]);
+=C2=A0 =C2=A0 =C2=A0 break;
+
+=C2=A0 =C2=A0 case EFI_VAR_DUMP:
+=C2=A0 =C2=A0 =C2=A0 if (state[1].set)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_BAD_ARGUMENT, = N_("cannot set
variable with dump format specifier"));
+=C2=A0 =C2=A0 =C2=A0 else
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 hexdump (0, (char *)efi_var, efi_var_si= ze);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D GRUB_ERR_NONE;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 break;
+
+=C2=A0 =C2=A0 default:
+=C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_BUG, N_("should = not happen (bug
in module?)"));
+=C2=A0 =C2=A0 =C2=A0 goto err;
+=C2=A0 }
+
+=C2=A0 if (efi_type !=3D EFI_VAR_DUMP)
+=C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 if (state[1].set)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_env_set (state[1].arg, env_var= );
+=C2=A0 =C2=A0 =C2=A0 else
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 grub_printf ("%s\n", (const c= har *)env_var);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D GRUB_ERR_NONE;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 }
+
+err:
+
+=C2=A0 grub_free (env_var);
+=C2=A0 grub_free (efi_var);
+
+=C2=A0 return status;
+}
+
+static grub_extcmd_t cmd =3D NULL;
+
+GRUB_MOD_INIT (efivar)
+{
+=C2=A0 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)
+{
+=C2=A0 if (cmd)
+=C2=A0 =C2=A0 grub_unregister_extcmd (cmd);
+}


On Mon, Dec 14, 2015 at= 11:08 AM, Ignat Korchagin <igna= t@cloudflare.com> wrote:
>> Assuming uint8 remains - should not you check that variable size i= s exactly 1 byte in this case?
> There are reports of a buggy firmware returning 4 bytes size for uint8=
> variables, however did not encounter them myself.
>
>> Do we really need unit8 at all? "hex" already provides e= xactly the same functionality, not? Do you think there are cases when uint8= is really required?
> Well, when checking for SecureBoot variable in grub configuration file=
> hex mode makes it look weird and creates a point of confusion. For
> example to check if SecureBoot (suppose the result of the our command<= br> > is stored in secure_boot env variable in hex mode) is enabled one
> should write:
> if [ secure_boot =3D "01" ]
> ...
> uint8 just allows to do a more straightforward config
> if [ secure_boot =3D 1] - this case would be false for hex mode -
> possible security breach
> ...
>
> Added goto err in the module as pointed, see patch below. I will do a<= br> > follow-up patch for documentation once we get this confirmed.
>
> 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 {
>=C2=A0 };
>
>=C2=A0 module =3D {
> +=C2=A0 name =3D efivar;
> +=C2=A0 efi =3D commands/efi/efivar.c;
> +=C2=A0 enable =3D efi;
> +};
> +
> +module =3D {
>=C2=A0 =C2=A0 name =3D blocklist;
>=C2=A0 =C2=A0 common =3D commands/blocklist.c;
>=C2=A0 };
> diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/= efivar.c
> new file mode 100644
> index 0000000..7f5a957
> --- /dev/null
> +++ b/grub-core/commands/efi/efivar.c
> @@ -0,0 +1,251 @@
> +/* efivar.c - Read EFI global variables. */
> +/*
> + *=C2=A0 GRUB=C2=A0 --=C2=A0 GRand Unified Bootloader
> + *=C2=A0 Copyright (C) 2015 Free Software Foundation, Inc.
> + *=C2=A0 Copyright (C) 2015 CloudFlare, Inc.
> + *
> + *=C2=A0 GRUB is free software: you can redistribute it and/or modify=
> + *=C2=A0 it under the terms of the GNU General Public License as publ= ished by
> + *=C2=A0 the Free Software Foundation, either version 3 of the Licens= e, or
> + *=C2=A0 (at your option) any later version.
> + *
> + *=C2=A0 GRUB is distributed in the hope that it will be useful,
> + *=C2=A0 but WITHOUT ANY WARRANTY; without even the implied warranty = of
> + *=C2=A0 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.=C2=A0 S= ee the
> + *=C2=A0 GNU General Public License for more details.
> + *
> + *=C2=A0 You should have received a copy of the GNU General Public Li= cense
> + *=C2=A0 along with GRUB.=C2=A0 If not, see <http://www.gnu.org= /licenses/>.
> + */
> +
> +#include <grub/types.h>
> +#include <grub/mm.h>
> +#include <grub/misc.h>
> +#include <grub/efi/api.h>
> +#include <grub/efi/efi.h>
> +#include <grub/extcmd.h>
> +#include <grub/env.h>
> +#include <grub/lib/hexdump.h>
> +
> +GRUB_MOD_LICENSE ("GPLv3+");
> +
> +static const struct grub_arg_option options[] =3D {
> +=C2=A0 {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_= ("Parse EFI_VAR in
> specific format (hex, uint8, ascii, raw, dump). Default: hex."),<= br> > N_("FORMAT"), ARG_TYPE_STRING},
> +=C2=A0 {"set", 's', GRUB_ARG_OPTION_OPTIONAL, N_(&q= uot;Save parsed result to
> environment variable (does not work with dump)."), N_("ENV_V= AR"),
> ARG_TYPE_STRING},
> +=C2=A0 {0, 0, 0, 0, 0, 0}
> +};
> +
> +enum efi_var_type
> +=C2=A0 {
> +=C2=A0 =C2=A0 EFI_VAR_ASCII =3D 0,
> +=C2=A0 =C2=A0 EFI_VAR_RAW,
> +=C2=A0 =C2=A0 EFI_VAR_UINT8,
> +=C2=A0 =C2=A0 EFI_VAR_HEX,
> +=C2=A0 =C2=A0 EFI_VAR_DUMP,
> +=C2=A0 =C2=A0 EFI_VAR_INVALID =3D -1
> +=C2=A0 };
> +
> +static enum efi_var_type
> +parse_efi_var_type (const char *type)
> +{
> +=C2=A0 if (!grub_strncmp (type, "ascii", sizeof("ascii= ")))
> +=C2=A0 =C2=A0 return EFI_VAR_ASCII;
> +
> +=C2=A0 if (!grub_strncmp (type, "raw", sizeof("raw&quo= t;)))
> +=C2=A0 =C2=A0 return EFI_VAR_ASCII;
> +
> +=C2=A0 if (!grub_strncmp (type, "uint8", sizeof("uint8= ")))
> +=C2=A0 =C2=A0 return EFI_VAR_UINT8;
> +
> +=C2=A0 if (!grub_strncmp (type, "hex", sizeof("hex&quo= t;)))
> +=C2=A0 =C2=A0 return EFI_VAR_HEX;
> +
> +=C2=A0 if (!grub_strncmp (type, "dump", sizeof("dump&q= uot;)))
> +=C2=A0 =C2=A0 return EFI_VAR_DUMP;
> +
> +=C2=A0 return EFI_VAR_INVALID;
> +}
> +
> +static int
> +grub_print_ascii (char *str, char c)
> +{
> +=C2=A0 if (grub_iscntrl (c))
> +=C2=A0 {
> +=C2=A0 =C2=A0 switch (c)
> +=C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\0':
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D '0';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\a':
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'a';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\b':
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'b';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\f':
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'f';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\n':
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'n';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\r':
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'r';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\t':
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 't';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 case '\v':
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '\\';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[1] =3D 'v';
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 2;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 default:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str[0] =3D '.'; /* as in h= exdump -C */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 1;
> +=C2=A0 =C2=A0 =C2=A0 }
> +=C2=A0 }
> +
> +=C2=A0 str[0] =3D c;
> +=C2=A0 return 1;
> +}
> +
> +static grub_err_t
> +grub_cmd_get_efi_var (struct grub_extcmd_context *ctxt,
> +=C2=A0 int argc, char **args)
> +{
> +=C2=A0 struct grub_arg_list *state =3D ctxt->state;
> +=C2=A0 grub_err_t status;
> +=C2=A0 void *efi_var =3D NULL;
> +=C2=A0 grub_size_t efi_var_size =3D 0;
> +=C2=A0 enum efi_var_type efi_type =3D EFI_VAR_HEX;
> +=C2=A0 grub_efi_guid_t global =3D GRUB_EFI_GLOBAL_VARIABLE_GUID;
> +=C2=A0 char *env_var =3D NULL;
> +=C2=A0 grub_size_t i;
> +=C2=A0 char *ptr;
> +
> +=C2=A0 if (1 !=3D argc)
> +=C2=A0 =C2=A0 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one = argument expected"));
> +
> +=C2=A0 if (state[0].set)
> +=C2=A0 =C2=A0 efi_type =3D parse_efi_var_type (state[0].arg);
> +
> +=C2=A0 if (EFI_VAR_INVALID =3D=3D efi_type)
> +=C2=A0 =C2=A0 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("inva= lid format specifier"));
> +
> +=C2=A0 efi_var =3D grub_efi_get_variable (args[0], &global, &= efi_var_size);
> +=C2=A0 if (!efi_var || !efi_var_size)
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_READ_ERROR, N_(&= quot;cannot read variable"));
> +=C2=A0 =C2=A0 =C2=A0 goto err;
> +=C2=A0 =C2=A0 }
> +
> +=C2=A0 switch (efi_type)
> +=C2=A0 {
> +=C2=A0 =C2=A0 case EFI_VAR_ASCII:
> +=C2=A0 =C2=A0 =C2=A0 env_var =3D grub_malloc (efi_var_size * 2 + 1);<= br> > +=C2=A0 =C2=A0 =C2=A0 if (!env_var)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_OU= T_OF_MEMORY, N_("out of memory"));
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 goto err;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 =C2=A0 ptr =3D env_var;
> +
> +=C2=A0 =C2=A0 =C2=A0 for (i =3D 0; i < efi_var_size; i++)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ptr +=3D grub_print_ascii (ptr, ((const c= har *)efi_var)[i]);
> +=C2=A0 =C2=A0 =C2=A0 *ptr =3D '\0';
> +=C2=A0 =C2=A0 =C2=A0 break;
> +
> +=C2=A0 =C2=A0 case EFI_VAR_RAW:
> +=C2=A0 =C2=A0 =C2=A0 env_var =3D grub_malloc (efi_var_size + 1);
> +=C2=A0 =C2=A0 =C2=A0 if (!env_var)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_OU= T_OF_MEMORY, N_("out of memory"));
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 goto err;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 =C2=A0 grub_memcpy (env_var, efi_var, efi_var_size); > +=C2=A0 =C2=A0 =C2=A0 env_var[efi_var_size] =3D '\0';
> +=C2=A0 =C2=A0 =C2=A0 break;
> +
> +=C2=A0 =C2=A0 case EFI_VAR_UINT8:
> +=C2=A0 =C2=A0 =C2=A0 env_var =3D grub_malloc (4);
> +=C2=A0 =C2=A0 =C2=A0 if (!env_var)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_OU= T_OF_MEMORY, N_("out of memory"));
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 goto err;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 =C2=A0 grub_snprintf (env_var, 4, "%u", *((gr= ub_uint8_t *)efi_var));
> +=C2=A0 =C2=A0 =C2=A0 break;
> +
> +=C2=A0 =C2=A0 case EFI_VAR_HEX:
> +=C2=A0 =C2=A0 =C2=A0 env_var =3D grub_malloc (efi_var_size * 2 + 1);<= br> > +=C2=A0 =C2=A0 =C2=A0 if (!env_var)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_OU= T_OF_MEMORY, N_("out of memory"));
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 goto err;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 =C2=A0 for (i =3D 0; i < efi_var_size; i++)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 grub_snprintf (env_var + (i * 2), 3, &quo= t;%02x", ((grub_uint8_t
> *)efi_var)[i]);
> +=C2=A0 =C2=A0 =C2=A0 break;
> +
> +=C2=A0 =C2=A0 case EFI_VAR_DUMP:
> +=C2=A0 =C2=A0 =C2=A0 if (state[1].set)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_BAD_ARGUM= ENT, N_("cannot set
> variable with dump format specifier"));
> +=C2=A0 =C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 hexdump (0, (char *)efi_var, efi_v= ar_size);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D GRUB_ERR_NONE;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 =C2=A0 break;
> +
> +=C2=A0 =C2=A0 default:
> +=C2=A0 =C2=A0 =C2=A0 status =3D grub_error (GRUB_ERR_BUG, N_("sh= ould not happen (bug
> in module?)"));
> +=C2=A0 =C2=A0 =C2=A0 goto err;
> +=C2=A0 }
> +
> +=C2=A0 if (efi_type !=3D EFI_VAR_DUMP)
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 if (state[1].set)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D grub_env_set (state[1].arg, en= v_var);
> +=C2=A0 =C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 grub_printf ("%s\n", (co= nst char *)env_var);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D GRUB_ERR_NONE;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 }
> +
> +err:
> +
> +=C2=A0 grub_free (env_var);
> +=C2=A0 grub_free (efi_var);
> +
> +=C2=A0 return status;
> +}
> +
> +static grub_extcmd_t cmd =3D NULL;
> +
> +GRUB_MOD_INIT (efivar)
> +{
> +=C2=A0 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)
> +{
> +=C2=A0 if (cmd)
> +=C2=A0 =C2=A0 grub_unregister_extcmd (cmd);
> +}

--001a114f098c988bba052a7b7c7d--