Commit Graph

31 Commits

Author SHA1 Message Date
Lans Zhang
0cc030c2f2 fallback: work around the issue of boot option creation with AMI BIOS
AMI BIOS (e.g, Intel NUC5i3MYHE) may automatically hide and patch BootXXXX
variables with ami_masked_device_path_guid.

Initially, the normal boot option created by fallback looks like this:
00000000  01 00 00 00 5e 00 42 00  6f 00 6f 00 74 00 6c 00  |....^.B.o.o.t.l.|
00000010  6f 00 61 00 64 00 65 00  72 00 20 00 54 00 65 00  |o.a.d.e.r. .T.e.|
00000020  73 00 74 00 20 00 28 00  36 00 34 00 2d 00 62 00  |s.t. .(.6.4.-.b.|
00000030  69 00 74 00 29 00 00 00  04 01 2a 00 01 00 00 00  |i.t.).....*.....|
00000040  00 08 00 00 00 00 00 00  00 00 08 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  01 01 04 04 30 00 5c 00  45 00 46 00 49 00 5c 00  |....0.\.E.F.I.\.|
00000070  42 00 4f 00 4f 00 54 00  5c 00 74 00 65 00 73 00  |B.O.O.T.\.t.e.s.|
00000080  74 00 78 00 36 00 34 00  2e 00 65 00 66 00 69 00  |t.x.6.4...e.f.i.|
00000090  00 00 7f ff 04 00                                 |......|
00000096

after reboot, fallback has to create a new one due to the previous boot
option is hidden and masked by AMI BIOS:
00000000  09 00 00 00 76 00 42 00  6f 00 6f 00 74 00 6c 00  |....v.B.o.o.t.l.|
00000010  6f 00 61 00 64 00 65 00  72 00 20 00 54 00 65 00  |o.a.d.e.r. .T.e.|
00000020  73 00 74 00 20 00 28 00  36 00 34 00 2d 00 62 00  |s.t. .(.6.4.-.b.|
00000030  69 00 74 00 29 00 00 00  01 04 14 00 e7 75 e2 99  |i.t.)........u..|
00000040  a0 75 37 4b a2 e6 c5 38  5e 6c 00 cb 7f ff 04 00  |.u7K...8^l......|
00000050  04 01 2a 00 01 00 00 00  00 08 00 00 00 00 00 00  |..*.............|
00000060  00 00 08 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000070  00 00 00 00 00 00 00 00  01 01 04 04 30 00 5c 00  |............0.\.|
00000080  45 00 46 00 49 00 5c 00  42 00 4f 00 4f 00 54 00  |E.F.I.\.B.O.O.T.|
00000090  5c 00 74 00 65 00 73 00  74 00 78 00 36 00 34 00  |\.t.e.s.t.x.6.4.|
000000a0  2e 00 65 00 66 00 69 00  00 00 7f ff 04 00        |..e.f.i.......|
000000ae

And after several reboot, fallback will have to create more boot options
because AMI BIOS corrupts the previous ones.

We can get the valid device path if just skipping the masked device path and
its next end path.

Signed-off-by: Lans Zhang <jia.zhang@windriver.com>
2017-08-11 14:10:43 -04:00
Lans Zhang
e6f3a6ecc3 fallback: fix double free of dp
If the boot option recorded in csv is not in a media device path, the
corresponding full device path will be referred for creating the boot
variable.

However, the current code logic always frees the full device path
(full_device_path) and the media device path (dp) separately. In order
to resolve this issue, always check whether dp equals to full_device_path
before freeing dp.

Signed-off-by: Lans Zhang <jia.zhang@windriver.com>
2017-08-11 14:10:43 -04:00
Peter Jones
431b8a2e75 Make fallback aware of tpm measurements, and reboot if tpm is used.
Since booting the entry with fallback in the stack of things that got
measured will result in all the wrong PCR values, in the cases where TPM
is present and enabled, use ->Reset() instead of loading the Boot####
variable and executing its target.

Signed-off-by: Peter Jones <pjones@redhat.com>
2017-08-03 11:00:58 -04:00
Peter Jones
a8f3dc82be fallback.c: be more correct with device path code.
Rob Clark noticed while, implementing a UEFI like backend on u-boot,
that if a File Handle actually returns a meaningful device path from
DevicePathFromHandle(), we wind up with a horribly wrong device path in
the boot variable.  He's right, normal UEFI doesn't return that, which
means FileDevicePath() in our code currently does nothing at all.

Instead of all that, pass in the device's handle, and it'll do what
we're doing after the fact there.

Here's the log from a current run:

FS0:\> \efi\BOOT\BOOTX64.EFI
System BootOrder not found.  Initializing defaults.
find_boot_options:778:Found directory named "fedora"
try_boot_csv:532:Found file "\EFI\fedora\BOOT.CSV"
try_boot_csv:544:File looks like:
?shim.efi,Fedora,,This is the boot entry for Fedora

populate_stanza:495:CSV data: "shim.efi,Fedora,,This is the boot entry for Fedora"
populate_stanza:501:filename: "shim.efi"
populate_stanza:508:label: "Fedora"
populate_stanza:514:arguments: ""
add_to_boot_list:430:file DP: PciRoot(0)/Pci(0x1F,0x2)/Sata(0x0,0x0,0x0)/HD(Part1,Sig6584272A-D7B9-442A-B8A4-19B5EC4566F4)/\EFI\fedora\shim.efi
FindSubDevicePath:78:input device path: "PciRoot(0)/Pci(0x1F,0x2)/Sata(0x0,0x0,0x0)/HD(Part1,Sig6584272A-D7B9-442A-B8A4-19B5EC4566F4)/\EFI\fedora\shim.efi"
FindSubDevicePath:86:sub-path (4,1): "HD(Part1,Sig6584272A-D7B9-442A-B8A4-19B5EC4566F4)/\EFI\fedora\shim.efi"
add_to_boot_list:452:04 01 2A 00 01 00 00 00 00 08 00 00 00 00 00 00
add_to_boot_list:452:00 40 06 00 00 00 00 00 2A 27 84 65 B9 D7 2A 44
add_to_boot_list:452:B8 A4 19 B5 EC 45 66 F4 02 02 04 04 2E 00 5C 00
add_to_boot_list:452:45 00 46 00 49 00 5C 00 66 00 65 00 64 00 6F 00
add_to_boot_list:452:72 00 61 00 5C 00 73 00 68 00 69 00 6D 00 2E 00
add_to_boot_list:452:65 00 66 00 69 00 00 00 7F FF 04 00
add_to_boot_list:459:device path: "HD(Part1,Sig6584272A-D7B9-442A-B8A4-19B5EC4566F4)/\EFI\fedora\shim.efi"
Creating boot entry "Boot0000" with label "Fedora" for file "\EFI\fedora\shim.efi"
AddOption - Boot0000, then CurrentCount = 0x00000008
update_boot_order:390:nbootorder: 7
BootOrder: 0000 0002 0001 0003 0005 0006 0004

Signed-off-by: Peter Jones <pjones@redhat.com>
2017-08-01 10:17:07 -04:00
Peter Jones
c0f7d13074 Make fallback debug printing be dynamic at runtime.
Signed-off-by: Peter Jones <pjones@redhat.com>
2017-08-01 10:17:07 -04:00
Peter Jones
87c8f07e98 fallback: Minor whitespace cleanup
Signed-off-by: Peter Jones <pjones@redhat.com>
2017-07-31 11:07:06 -04:00
Peter Jones
d89b722ef7 Exit our dir->Read() loop if it says there's 0 bytes of data to read.
When dir->Read() says bs=0, we shouldn't try to allocate a buffer and
read into it. On edk2 this works because there's an implicit (possibly
accidental) minimum size of one pool list entry that can be allocated,
so you wind up getting (I think) 8 bytes.

When Rob Clark tried to run this under uboot's emulated UEFI
environment, dir->Read() returned 0 and when we passed that to
AllocateZeroPool() less good things happened.

So just check for that case and exit appropriately.

Signed-off-by: Peter Jones <pjones@redhat.com>
2017-07-24 14:02:37 -04:00
Peter Jones
47f3a65eda Improve BOOT${ARCH}.CSV support.
Signed-off-by: Peter Jones <pjones@redhat.com>
2016-09-06 14:39:15 -04:00
Peter Jones
6f04092060 Make fallback and mokmanager know about multi-arch.
On baytrail, we've got 32-bit firmware, 32-bit efi utilities, and 64-bit
kernel.  So since most distros will want 32+64 EFI media booting a
64-bit kernel, we have to name them better on the filesystem.

Signed-off-by: Peter Jones <pjones@redhat.com>
2016-09-06 14:39:15 -04:00
Peter Jones
70ce2c4204 Improve our debuginfo path print
Signed-off-by: Peter Jones <pjones@redhat.com>
2015-06-30 14:19:57 -04:00
Peter Jones
a031960750 Add a conditional point for a debugger to attach.
Signed-off-by: Peter Jones <pjones@redhat.com>
2015-06-29 14:41:21 -04:00
Laszlo Ersek
6b2510522f Fix length of allocated buffer for boot option comparison.
The following commit:

  commit 4aac8a1179
  Author: Gary Ching-Pang Lin <glin@suse.com>
  Date:   Thu Mar 6 10:57:02 2014 +0800

    [fallback] Fix the data size for boot option comparison

corrected the data size used for comparison, but also reduced the
allocation so it doesn't include the trailing UTF16LE '\0\0' at the
end of the string, with the result that the trailer of the buffer
containing the string is overwritten, which OVMF detects as memory
corruption.

Increase the size of the storage buffer in a few places to correct
this problem.

Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Gary Ching-Pang Lin <glin@suse.com>
2015-04-13 19:55:25 -04:00
Richard W.M. Jones
90c65f72f8 fallback: Fix comparison between signed and unsigned in debugging code.
fallback.c: In function ‘update_boot_order’:
fallback.c:334:17: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
  for (j = 0 ; j < size / sizeof (CHAR16); j++)
                   ^
fallback.c: In function ‘add_to_boot_list’:
fallback.c:402:16: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
  for (i = 0; i < s; i++) {
                  ^

Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
2015-04-13 19:55:25 -04:00
Gary Ching-Pang Lin
0ba09477af [fallback] Try to boot the first boot option anyway
Some UEFI implementations never care the boot options, so the
restored boot options could be just ignored and this results in
endless reboot. To avoid this situation, this commit makes
fallback.efi to load the first matched boot option even if there
is no boot option to be restored. It may not be perfect, but at
least the bootloader is loaded...

Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
2014-05-13 13:30:07 -04:00
Gary Ching-Pang Lin
4aac8a1179 [fallback] Fix the data size for boot option comparison
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
2014-05-13 13:24:12 -04:00
Gary Ching-Pang Lin
382a0b66e6 [fallback] Avoid duplicate old BootOrder
set_boot_order() already copies the old BootOrder to the variable,
bootorder. Besides, we can adjust BootOrder when adding the newly
generated boot option. So, we don't have to copy the old one again
in update_boot_order(). This avoid the duplicate entries in BootOrder.

Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
2014-05-13 13:23:41 -04:00
Kees Cook
5495694c04 additional bounds-checking on section sizes
This adds additional bounds-checking on the section sizes. Also adds
-Wsign-compare to the Makefile and replaces some signed variables with
unsigned counteparts for robustness.

Signed-off-by: Kees Cook <kees@ubuntu.com>
2014-04-11 14:41:22 -04:00
Peter Jones
894a2738d6 [fallback] Attempt to re-use existing entries when possible.
Some firmwares seem to ignore our boot entries and put their fallback
entries back on top.  Right now that results in a lot of boot entries
for our stuff, a la https://bugzilla.redhat.com/show_bug.cgi?id=995834 .

Instead of that happening, if we simply find existing entries that match
the entry we would create and move them to the top of the boot order,
the machine will continue to operate in failure mode (which we can't
avoid), but at least we won't create thousands of extra entries.

Signed-off-by: Peter Jones <pjones@redhat.com>
2014-01-31 10:31:10 -05:00
Peter Jones
dfd6c73a21 [fallback] For HD() device paths, use just the media node and later.
UEFI 2.x section 3.1.2 provides for "short-form device path", where the
first element specified is a "hard drive media device path", so that you
can move a disk around on different buses without invalidating your
device path.  Fallback has not been using this option, though in most
cases efibootmgr has.

Note that we still keep the full device path, because LoadImage()
isn't necessarily the layer where HD() works - one some systems BDS is
responsible for resolving the full path and passes that to LoadImage()
instead.  So we have to do LoadImage() with the full path.
2014-01-31 10:30:36 -05:00
Peter Jones
3a7feeff6c Rewrite directory traversal allocation path so coverity can grok it.
The things we do for our tools.  In this case, make the AllocatePool()
happen outside of a conditional, even though that conditional will
always bee satisfied.  This way coverity won't think we're setting fi
to NULL and passing it to StrCaseCmp.

Signed-off-by: Peter Jones <pjones@redhat.com>
2013-11-21 11:48:24 -05:00
Andrew Boie
d74ab697f7 fallback.c: fix 32-bit compilation
fh->Read expects pointer to 32-bit int, use UINTN

Change-Id: If1a728efd51a9a24dfcd8123e84bf4c0713491fe
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2013-11-12 10:30:02 -05:00
Peter Jones
073f3b3caf Fix some minor type errors.
Signed-off-by: Peter Jones <pjones@redhat.com>
2013-05-15 13:37:15 -04:00
Peter Jones
a41306e8f4 Pass parameters correctly when booting.
Signed-off-by: Peter Jones <pjones@redhat.com>
2013-05-14 13:10:52 -04:00
Peter Jones
3fa9a53425 [fallback] Try to execute the first new boot option.
I'm told rebooting is sometimes unreliable when called here, and we'll
get bootx64.efi loaded anyway.  I'll just assume that's true and try to
load the first option, since it's clearly what we'd prefer happens next.

Signed-off-by: Peter Jones <pjones@redhat.com>
2013-05-02 14:58:44 -04:00
Peter Jones
f0e4df7d5f Explain byte order handling better.
Signed-off-by: Peter Jones <pjones@redhat.com>
2013-04-30 14:21:41 -04:00
Gary Ching-Pang Lin
8adfd201fe Don't update BootOrder until all csv files are processed 2013-04-30 09:46:23 -04:00
Gary Ching-Pang Lin
f7fbcdce36 Reset the system after restoring the boot entries 2013-04-30 09:46:23 -04:00
Gary Ching-Pang Lin
4665fcab62 Fix crash due to memory allocation 2013-04-30 09:46:23 -04:00
Peter Jones
82a9c9fdb6 Get rid of extra "continue".
It's confusing, and it doesn't actually accomplish anything when applied
to *either* loop.

Signed-off-by: Peter Jones <pjones@redhat.com>
2013-04-30 09:46:22 -04:00
Peter Jones
1a75bb9fc2 Fix error checking on AllocateZeroPool() in update_boot_order()
Signed-off-by: Peter Jones <pjones@redhat.com>
2013-04-30 09:46:22 -04:00
Peter Jones
3ce517fdbb Add a fallback loader for when shim is invoked as BOOTX64.EFI
If shim is invoked as \EFI\BOOT\BOOT*.EFI and a file exists named
\EFI\BOOT\FALLBACK.EFI, try it instead of our second stage.  So don't
put fallback.efi on your install media in \EFI\BOOT, because that won't
do whatever it is you're hoping for, unless you're hoping not to start
the installer.

So here's the process for using this:
in /EFI/fedora/ (or whichever directory you happen to own), you put:
  shim.efi
  grub.efi
  boot.csv - format is: shim.efi,Nice Label,cmdline arguments,comments
           - filenames refer only to files in this directory, with no
	     leading characters such as L"./" or L"/EFI/fedora/"
           - note that while this is CSV, the character encoding is
	     UCS-2

and if /EFI/BOOT/BOOTX64.EFI doesn't already exist, then in /EFI/BOOT:
  shim.efi as BOOTX64.EFI
  fallback.efi

Signed-off-by: Peter Jones <pjones@redhat.com>
2013-04-30 09:46:22 -04:00