summaryrefslogtreecommitdiff
path: root/fallback.c
AgeCommit message (Collapse)Author
2018-04-05Audit get_variable() calls for correct FreePool() use.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2018-03-12console: Add console_print and console_print_at helpersHans de Goede
This is a preparation commit for removing the setup_console(1) calls from MokManager and shim so that we don't force the EFI console to switch to text-mode. This commit replaces all direct calls to Print / PrintAt with calls to the new helpers (no functional changes) so that we can delay calling setup_console(1) till the first Print call in a follow-up patch. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2018-03-12Don't use uefi_call_wrapper(), ever.Peter Jones
I'm pretty done with typing uefi_call_wrapper() and counting arguments every time. Instead, just make the compiler error if we don't have ms_abi. Also, make it so nothing can use uefi_call_wrapper() directly. Signed-off-by: Peter Jones <pjones@redhat.com>
2018-03-12fallback: find_boot_options(): don't leak a file handle.Peter Jones
If we open it, we have to close it. Signed-off-by: Peter Jones <pjones@redhat.com>
2018-03-12fallback: Use EFI_ERROR() instead of comparing to EFI_SUCCESS everywhere.Peter Jones
Also consistently name our status variable "efi_status" unless there's a good reason not to, such as already having another one of those. Signed-off-by: Peter Jones <pjones@redhat.com>
2018-03-12fallback: find_boot_options(): make the allocation path prettier.Peter Jones
Covscan believes all this stuff: 852 bs = 0; 853 rc = uefi_call_wrapper(fh2->Read, 3, fh2, &bs, NULL); 7. Condition rc == (9223372036854775813UL /* 0x8000000000000000UL | 5 */), taking false branch. 8. Condition rc == 0, taking false branch. 15. Condition rc == (9223372036854775813UL /* 0x8000000000000000UL | 5 */), taking false branch. 16. Condition rc == 0, taking true branch. 17. Condition bs != 0, taking true branch. 30. Condition rc == (9223372036854775813UL /* 0x8000000000000000UL | 5 */), taking false branch. 31. Condition rc == 0, taking false branch. 854 if (rc == EFI_BUFFER_TOO_SMALL || 855 (rc == EFI_SUCCESS && bs != 0)) { 856 buffer = AllocateZeroPool(bs); 18. Condition !buffer, taking false branch. 857 if (!buffer) { 858 Print(L"Could not allocate memory\n"); 859 /* sure, this might work, why not? */ 860 uefi_call_wrapper(fh2->Close, 1, fh2); 861 uefi_call_wrapper(fh->Close, 1, fh); 862 return EFI_OUT_OF_RESOURCES; 863 } 864 865 rc = uefi_call_wrapper(fh2->Read, 3, fh2, &bs, buffer); 866 } 9. Condition bs == 0, taking false branch. 19. Condition bs == 0, taking false branch. 32. Condition bs == 0, taking false branch. 867 if (bs == 0) 868 break; 869 10. Condition (INTN)rc < 0, taking false branch. 20. Condition (INTN)rc < 0, taking false branch. 33. Condition (INTN)rc < 0, taking false branch. 870 if (EFI_ERROR(rc)) { 871 Print(L"Could not read \\EFI\\: %d\n", rc); 872 if (buffer) { 873 FreePool(buffer); 874 buffer = NULL; 875 } 876 uefi_call_wrapper(fh2->Close, 1, fh2); 877 uefi_call_wrapper(fh->Close, 1, fh); 878 return rc; 879 } 34. alias_transfer: Assigning: fi = buffer. 880 EFI_FILE_INFO *fi = buffer; 881 11. Condition !(fi->Attribute & 16), taking false branch. 21. Condition !(fi->Attribute & 16), taking false branch. CID 182858 (#1-3 of 3): Explicit null dereferenced (FORWARD_NULL)35. var_deref_op: Dereferencing null pointer fi. 882 if (!(fi->Attribute & EFI_FILE_DIRECTORY)) { 883 FreePool(buffer); 884 buffer = NULL; 885 continue; 886 } Because it doesn't know that when bs==0, fh2->Read() will return EFI_BUFFER_TOO_SMALL and set bs to the size we need to allocate, so the allocation path is always taken. Instead, handle our exit/error paths directly there, and make the allocation path nonconditional. Signed-off-by: Peter Jones <pjones@redhat.com>
2018-03-12fallback: find_boot_csv(): eliminate dead code.Peter Jones
Covscan sez: 720 FreePool(buffer); assignment: Assigning: buffer = NULL. 721 buffer = NULL; 722 723 CHAR16 *bootcsv=NULL, *bootarchcsv=NULL; 724 725 bs = 0; 726 do { 727 bs = 0; 728 rc = uefi_call_wrapper(fh->Read, 3, fh, &bs, NULL); 729 if (EFI_ERROR(rc) && rc != EFI_BUFFER_TOO_SMALL) { 730 Print(L"Could not read \\EFI\\%s\\: %d\n", dirname, rc); null: At condition buffer, the value of buffer must be NULL. dead_error_condition: The condition buffer cannot be true. 731 if (buffer) CID 182851 (#1 of 1): Logically dead code (DEADCODE)dead_error_line: Execution cannot reach this statement: FreePool(buffer);. 732 FreePool(buffer); 733 return rc; 734 } And it's right; buffer can never be non-NULL there. So just take that out. Signed-off-by: Peter Jones <pjones@redhat.com>
2018-03-12fallback: find_boot_csv(): Print the error from try_boot_csv()Peter Jones
Covscan believes the following: 782 if ((EFI_ERROR(rc) || !bootarchcsv) && bootcsv) { 783 EFI_FILE_HANDLE fh2; 784 rc = uefi_call_wrapper(fh->Open, 5, fh, &fh2, 785 bootcsv, EFI_FILE_READ_ONLY, 0); 786 if (EFI_ERROR(rc) || fh2 == NULL) { 787 Print(L"Couldn't open \\EFI\\%s\\%s: %d\n", 788 dirname, bootcsv, rc); 789 } else { CID 182829 (#1 of 1): Unused value (UNUSED_VALUE)returned_value: Assigning value from try_boot_csv(fh2, dirname, bootcsv) to rc here, but that stored value is overwritten before it can be used. 790 rc = try_boot_csv(fh2, dirname, bootcsv); 791 uefi_call_wrapper(fh2->Close, 1, fh2); 792 } 793 } value_overwrite: Overwriting previous write to rc with value 0UL. 794 rc = EFI_SUCCESS; 795 796 return rc; 797} Which isn't untrue, we just don't happen to be using the return code for anything, before we intentionally return success to our caller. So that's annoying, but whatever. Just print the error as well. Signed-off-by: Peter Jones <pjones@redhat.com>
2018-03-12fallback: read_file(): limit how big the file can be and still be validPeter Jones
Covscan says: 146 UINTN len = 0; 147 CHAR16 *b = NULL; 2. tainted_data_argument: Calling function get_file_size taints argument len. 148 rc = get_file_size(fh2, &len); 3. Condition (INTN)rc < 0, taking false branch. 149 if (EFI_ERROR(rc)) { 150 uefi_call_wrapper(fh2->Close, 1, fh2); 151 return rc; 152 } 153 4. overflow_assign: Assigning overflowed or truncated value (or a value computed from an overflowed or a truncated value) to b. 8. overflow: Add operation overflows on operands len and 2UL. Example value for operand: len = 18446744073709551614. 154 b = AllocateZeroPool(len + 2); Technically we can't handle a file larger than 0xfffffffffffffffd (on x86_64) because when we try to allocate the buffer to hold it with a trailing UCS-2 NUL we overflow to 0. Also our filesystem can't hold a file bigger than 4GB... So this is probably actually broken on 32-bit platforms. This patch limits it to some handy amount like 1024 * PAGE_SIZE, aka 4MB. Note that this doesn't appear to be exploitable (at least on edk2-based firmwares), because AllocateZeroPool() has a minimum granularity of 1 page, so even if you overflow it with a 4GB file, we'll get 1 page out of it and then try to read 1 byte into it, and then it's just going to be a parse error on the CSV. Even if we error on the sentinal UCS-2 NUL we put at the end, it'll still be inside of the zeroed page, and it still won't fault or overwrite any meaningful data. Signed-off-by: Peter Jones <pjones@redhat.com>
2018-03-12fallback: handle buffer allocations for fh->GetInfo() prettier.Peter Jones
At all the places we use fh->GetInfo, covscan can't tell that fh->GetInfo() will return EFI_BUFFER_TOO_SMALL and we'll allocate on the first try. If we just explicitly check for "buffer == NULL" as well, covscan believes we're doing work we don't need to (which is true!) So instead, put an rc test to return error for everything else there, so the allocation isn't in a conditional. Yet another stupid one, but it's easier to nerf it this way than write the false-positive rule, and it also hardens against incorrect UEFI implementations (though we've not seen any yet with the problem this avoids). Signed-off-by: Peter Jones <pjones@redhat.com>
2018-03-12Don't have tons of local guid definitions for no reason at all.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2017-08-11fallback: work around the issue of boot option creation with AMI BIOSLans Zhang
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-11fallback: fix double free of dpLans Zhang
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-03Make fallback aware of tpm measurements, and reboot if tpm is used.Peter Jones
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-01fallback.c: be more correct with device path code.Peter Jones
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-01Make fallback debug printing be dynamic at runtime.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2017-07-31fallback: Minor whitespace cleanupPeter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2017-07-24Exit our dir->Read() loop if it says there's 0 bytes of data to read.Peter Jones
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>
2016-09-06Improve BOOT${ARCH}.CSV support.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2016-09-06Make fallback and mokmanager know about multi-arch.Peter Jones
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>
2015-06-30Improve our debuginfo path printPeter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2015-06-29Add a conditional point for a debugger to attach.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2015-04-13Fix length of allocated buffer for boot option comparison.Laszlo Ersek
The following commit: commit 4aac8a1179e160397d7ef8f1e3232cfb4f3373d6 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-13fallback: Fix comparison between signed and unsigned in debugging code.Richard W.M. Jones
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>
2014-05-13[fallback] Try to boot the first boot option anywayGary Ching-Pang Lin
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[fallback] Fix the data size for boot option comparisonGary Ching-Pang Lin
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
2014-05-13[fallback] Avoid duplicate old BootOrderGary Ching-Pang Lin
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-04-11additional bounds-checking on section sizesKees Cook
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-01-31[fallback] Attempt to re-use existing entries when possible.Peter Jones
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[fallback] For HD() device paths, use just the media node and later.Peter Jones
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.
2013-11-21Rewrite directory traversal allocation path so coverity can grok it.Peter Jones
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-12fallback.c: fix 32-bit compilationAndrew Boie
fh->Read expects pointer to 32-bit int, use UINTN Change-Id: If1a728efd51a9a24dfcd8123e84bf4c0713491fe Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2013-05-15Fix some minor type errors.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2013-05-14Pass parameters correctly when booting.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2013-05-02[fallback] Try to execute the first new boot option.Peter Jones
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-04-30Explain byte order handling better.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2013-04-30Don't update BootOrder until all csv files are processedGary Ching-Pang Lin
2013-04-30Reset the system after restoring the boot entriesGary Ching-Pang Lin
2013-04-30Fix crash due to memory allocationGary Ching-Pang Lin
2013-04-30Get rid of extra "continue".Peter Jones
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-30Fix error checking on AllocateZeroPool() in update_boot_order()Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2013-04-30Add a fallback loader for when shim is invoked as BOOTX64.EFIPeter Jones
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>