summaryrefslogtreecommitdiff
path: root/shim.c
AgeCommit message (Collapse)Author
2017-03-27shim: disambiguate our global image handle.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2017-02-28Use EfiLoaderCode memory for loading PE/COFF executablesArd Biesheuvel
Under a strict memory protection policy, UEFI may give out EfiLoaderData memory with the XN attribute set. So use EfiLoaderCode explicitly. At the same time, use a page based allocation rather than a pool allocation, which is more appropriate when loading PE/COFF images. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2017-02-06Also just check for access denied anyway.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2017-02-06Ensure all of the SB verification returns the same error code.Peter Jones
Previously we were returning EFI_ACCESS_DENIED at some places and EFI_SECURITY_VIOLATION at others. When we're checking whether to run MokManager, we're checking EFI_SECURITY_VIOLATION, which is more or less analogous with what the spec says StartImage() returns. So we should always have that as the return code. I believe this will fix github issue #44. Signed-off-by: Peter Jones <pjones@redhat.com>
2017-02-06shim: fix the mirroring MokSBState failIvan Hu
Some machines have already embedded MokSBStateRT varaible with EFI_VARIABLE_NON_VOLATILE attribute, and some users might disable shim vailidation manually by creating MokSBStateRT. It causes mirroring MokSBState fail because the variable cannot be set with different attribute again, and gets error massage every time when booting. Fix it with checking the MokSBStateRT existence and deleting it before mirroring it. Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
2017-02-06generate_hash(): make check_size() set an error, and verify SecDir size.Peter Jones
Currently generate_hash() attempts to include any trailing data at the end of the binary in the resulting digest, but it won't include such data if the size computed is wrong because context->SecDir->Size is invalid. In this case the return code is EFI_SUCCESS, and the hash will match any a binary as if the Attribute Certificate Table and anything after it are missing. This is wrong. Signed-off-by: Peter Jones <pjones@redhat.com>
2016-09-21shim: verify Extended Key Usage flagsMathieu Trudel-Lapierre
For starters; don't allow the "module signing" OID; which ought to only ever be used for signing kernel modules, not signing EFI binaries. Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
2016-09-09Fix up a merge error in 467878f3e0.Peter Jones
In the branch I wrote the code on, "size" was a thing. On this branch it isn't. Signed-off-by: Peter Jones <pjones@redhat.com>
2016-09-09verify_buffer: check that the value of cert->Hdr.dwLength is reasonablePeter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2016-09-06Minor formatting fixPeter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2016-09-06Use authenticode signature length from WIN_CERTIFICATE structure.Sachin Agrawal
Authenticode Certificate length is available in Certificate Table (inside PE header) and also in signature header(WIN_CERTIFICATE) itself. Code in 'check_backlist()' method uses length from signature header, whereas, AuthenticodeVerify() call inside 'verify_buffer()' method uses the length in signature header. This causes a security vulnerability issue : Good Scenario : Assume shim1.crt is used for signing grub.efi and shim1.crt is embedded inside shim.efi. Also, assume shim1.crt got compromised and therefore it was added in 'dbx' database. Now, when shim.efi will attempt to load grub.efi, it will fail loading with log message "Binary is blacklisted" because 'check_blacklist' call will detect the presence of 'shim1.crt' in 'dbx'. Vulnerable Scenario : Similar as above. Add 'shim1.crt' in dbx database. Also, tamper the earlier signed grub.efi file by placing 0x0000 in the WIN_CERTIFICATE.dwLength. (Open grub.efi/vmlinuz signed binary with hex editor. Go to 0x128 address and read out the address from 0x128 until 0x12B in little Indian order from right to left. Jump to the address from 0x128 address area. First 8bytes are the signature header area which consist of signature size(4bytes), revision(2bytes) and type(2bytes). So tamper the first 4 bytes for signature size and save the binary. ) With this tampered grub.efi, shim.efi loads it successfully because 'check_blacklist()' call fails to detect the presence of shim1.crt in 'dbx' database. Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
2016-09-06Don't close file twice in should_use_fallback error pathBenjamin Antin
When fallback.efi is not present, the should_use_fallback error path attempts to close a file that has already been closed, resulting in a hang. This issue only affects certain systems. This is a regression from version 0.8 and was introduced by commit 4794822. Signed-off-by: Benjamin Antin <ben.antin@endlessm.com>
2016-09-06shim: remove unused variableGary Lin
Fix the compilation error from gcc: shim.c: In function ‘handle_image’: shim.c:1121:15: error: unused variable ‘size’ [-Werror=unused-variable] unsigned int size; ^~~~ Signed-off-by: Gary Lin <glin@suse.com>
2016-09-06Fix the size of MokDBStateLans Zhang
MokDBState is a 8-bit unsigned integer. Looks like a typo here. Signed-off-by: Lans Zhang <jia.zhang@windriver.com>
2016-09-06Add the optional HTTPBoot supportGary Ching-Pang Lin
This commit adds the basic support for HTTPBoot, i.e. to fetch the next stage loader with the HTTP protocol. It requires gnu-efi >= 3.0.3 to support the URI device path and Ip4Config2 or Ip6Config protocol support in the UEFI implementation. To build shim.efi with HTTPBoot support: make ENABLE_HTTPBOOT=1 shim.efi Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
2016-09-06read_header/handle_image: treat uninitialized file alignment as PAGE_SIZEPeter Jones
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>
2016-06-09shim: make the PE loader less overzealous on rejectionsPeter Jones
2016-05-11Measure state and second stage into TPMMatthew Garrett
Add support for measuring the MOK database and secure boot state into a TPM, and do the same for the second stage loader. This avoids a hole in TPM measurement between the firmware and the second stage loader.
2016-05-11shim: dealing with only one string on loadoptionIvan Hu
The second stage set is not working after commit 3322257e611e2000f79726d295bb4845bbe449e7 for those which load option only have one string. Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
2016-03-22shim: mirror MokSBState in runtime so the kernel can make use of it.Mathieu Trudel-Lapierre
Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
2015-11-17shim: check for EFI\BOOT\BOOT${ARCH}.EFI as well as the leading \ versionPeter Jones
I found a machine whose BDS gives us relative paths, yay! The rest of the code still works without that leading slash, so just make it one more item we let through our StrnCaseCmp() filter. Signed-off-by: Peter Jones <pjones@redhat.com>
2015-11-17shim: fix resource leak on should_use_fallback() error pathPeter Jones
ExitBootServices() and Exit() should both clean these up anyway, but we should do the right thing nonetheless. Signed-off-by: Peter Jones <pjones@redhat.com>
2015-11-17shim: if generate_path() gets a full path, just return it.Peter Jones
We decide if it's a full path by if it starts with \\EFI\\. That's quite lazy, but we can't just check \\ like you'd hope, because we need to stay compatible with what we've set as DEFAULT_LOADER in the past, and I don't feel like writing the full path traversal file test. Signed-off-by: Peter Jones <pjones@redhat.com>
2015-11-17shim: fix a wrong-abi call to Stall() and ResetSystem()Peter Jones
Woops. The net outcome of these is going to be a sleep of unknown duration, followed by either a) ResetSystem() with some random selection of warm/cold boot, or b) ResetSystem() returning an error and shim returning error from efi_main(). Signed-off-by: Peter Jones <pjones@redhat.com>
2015-11-17shim: handle BDS's li->LoadOptions and Shell's li->LoadOptions .Peter Jones
Load options are a giant pain in the ass, because the shell is a giant piece of junk. If we're invoked from the EFI shell, we get something like this: 00000000 5c 00 45 00 36 00 49 00 5c 00 66 00 65 00 64 00 |\.E.F.I.\.f.e.d.| 00000010 6f 00 72 00 61 00 5c 00 73 00 68 00 69 00 6d 00 |o.r.a.\.s.h.i.m.| 00000020 78 00 36 00 34 00 2e 00 64 00 66 00 69 00 20 00 |x.6.4...e.f.i. .| 00000030 5c 00 45 00 46 00 49 00 5c 00 66 00 65 00 64 00 |\.E.F.I.\.f.e.d.| 00000040 6f 00 72 00 61 00 5c 00 66 00 77 00 75 00 70 00 |o.r.a.\.f.w.u.p.| 00000050 64 00 61 00 74 00 65 00 2e 00 65 00 66 00 20 00 |d.a.t.e.e.f.i. .| 00000060 00 00 66 00 73 00 30 00 3a 00 5c 00 00 00 |..f.s.0.:.\...| which is just some paths rammed together separated by a UCS-2 NUL. But if we're invoked from BDS, we get something more like: 00000000 01 00 00 00 62 00 4c 00 69 00 6e 00 75 00 78 00 |....b.L.i.n.u.x.| 00000010 20 00 46 00 69 00 72 00 6d 00 77 00 61 00 72 00 | .F.i.r.m.w.a.r.| 00000020 65 00 20 00 55 00 70 00 64 00 61 00 74 00 65 00 |e. .U.p.d.a.t.e.| 00000030 72 00 00 00 40 01 2a 00 01 00 00 00 00 08 00 00 |r.....*.........| 00000040 00 00 00 00 00 40 06 00 00 00 00 00 1a 9e 55 bf |.....@........U.| 00000050 04 57 f2 4f b4 4a ed 26 4a 40 6a 94 02 02 04 04 |.W.O.:.&J@j.....| 00000060 34 00 5c 00 45 00 46 00 49 00 5c 00 66 00 65 00 |4.\.E.F.I.f.e.d.| 00000070 64 00 6f 00 72 00 61 00 5c 00 73 00 68 00 69 00 |o.r.a.\.s.h.i.m.| 00000080 6d 00 78 00 36 00 34 00 2e 00 65 00 66 00 69 00 |x.6.4...e.f.i...| 00000090 00 00 7f ff 40 00 20 00 5c 00 66 00 77 00 75 00 |...... .\.f.w.u.| 000000a0 70 00 78 00 36 00 34 00 2e 00 65 00 66 00 69 00 |p.x.6.4...e.f.i.| 000000b0 00 00 |..| which is clearly an EFI_LOAD_OPTION filled in halfway reasonably. In short, the UEFI shell is still a useless piece of junk. So anyway, try to determine which one we've got and handle it appropriately. Signed-off-by: Peter Jones <pjones@redhat.com>
2015-11-17Fix unsigned int overflow on our i386 debug hook test.Peter Jones
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-29Only be verbose the first time secure_mode() is called.Peter Jones
It's annoying to find out we're not in SB mode over and over. Really it is. 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-06-29Don't print anything or delay when start_image() succeeds.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2015-06-16Make shim to check MokXAuth for MOKX resetGary Ching-Pang Lin
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
2015-06-16Verify the EFI images with MOK blacklistGary Ching-Pang Lin
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
2015-06-16Copy the MOK blacklist to a RT variableGary Ching-Pang Lin
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
2015-06-16Support MOK blacklistGary Ching-Pang Lin
The new blacklist, MokListX, stores the keys and hashes that are banned. Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
2015-06-11Ensure that apps launched by shim get correct BS->Exit() behaviorPeter Jones
Right now applications run by shim get our wrapper for Exit(), but it doesn't do as much cleanup as it should - shim itself also exits, but currently is not doing all the cleanup it should be doing. This changes it so all of shim's cleanup is also performed. Based on a patch and lots of review from Gary Lin. Signed-off-by: Peter Jones <pjones@redhat.com>
2015-06-11Don't leave in_protocol==1 when shim_verify() isn't enforcing.Peter Jones
Right now if shim_verify() sees secure_mode()==0, it exits with EFI_SUCCESS, but accidentally leaves in_protocol=1. This means any other call will have supressed error/warning messages. That's wrong, so don't do it. Signed-off-by: Peter Jones <pjones@redhat.com>
2015-06-04Only run MokManager if asked or a security violation occurs.Peter Jones
Don't run MokManager on any random error from start_image(second_stage); only try it if it /is/ the second stage, or if start_image gave us EFI_SECURITY_VIOLATION. Signed-off-by: Peter Jones <pjones@redhat.com>
2015-04-13Don't install our protocols if we're not in secure mode.Peter Jones
System services haven't been hooked if we're not in secure mode, so do_exit() will never be called. In this case shim never gets control once grub exits, which means if booting fails and the firmware tries another boot option, it'll attempt to talk to the shim protocol we installed. This is wrong, because it is allowed to have been cleared from ram at this time, since the task it's under has exited. So just don't install the protocols when we're not enforcing. This version also has a message and a 2-second stall after calling start_image(), so that we can tell if we are on the expected return path of our execution flow.
2015-04-13Align the sections we're loading, and check for validity /after/ discarding.Peter Jones
Turns out a) the codegen on aarch64 generates code that has real alignment needs, and b) if we check the length of discardable sections before discarding them, we error for no reason. So do the error checking in the right order, and always enforce some alignment because we know we have to. Signed-off-by: Peter Jones <pjones@redhat.com>
2014-10-02Don't verify images with the empty build keyGary Ching-Pang Lin
We replaced the build key with an empty file while compiling shim for our distro. Skip the verification with the empty build key since this makes no sense. Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
2014-10-02Don't append an empty cert list to MokListRT if vendor_cert_size is 0.Peter Jones
Signed-off-by: Peter Jones <pjones@redhat.com>
2014-09-30Actually find the relocations correctly and process them that way.Peter Jones
Find the relocations based on the *file* address in the old binary, because it's only the same as the virtual address some of the time. Also perform some extra validation before processing it, and don't bail out in /error/ if both ReloceBase and RelocEnd are null - that condition is fine. Signed-off-by: Peter Jones <pjones@redhat.com>
2014-09-21Fix our "in_protocol" printing.Peter Jones
When I merged 4bfb13d and fixed the conflicts, I managed to make the in_protocol test exactly backwards, so that's why we don't currently see error messages. Signed-off-by: Peter Jones <pjones@redhat.com>
2014-09-21Don't call AuthenticodeVerify if vendor_cert_size is 0.Peter Jones
Actually check the size of our vendor cert quite early, so that there's no confusion as to what's going on. This isn't strictly necessary, in that in all cases if vendor_cert_size is 0, then AuthenticodeVerify -> Pkcs7Verify() -> d2i_X509() will result in a NULL "Cert", and it will return FALSE, and we'll reject the signature, but better to avoid all that code in the first place. Belt and suspenders and whatnot. Based on a patch from https://github.com/TBOpen . Signed-off-by: Peter Jones <pjones@redhat.com>
2014-09-21Validate computed hash bases/hash sizes more thoroughly.Peter Jones
I screwed one of these up when working on 750584c, and it's a real pain to figure out, so that means we should be validating them. Signed-off-by: Peter Jones <pjones@redhat.com>
2014-09-21Make 64-on-32 maybe work on x86_64.Peter Jones
This is mostly based on a patch (https://github.com/mjg59/shim/issues/30) from https://github.com/TBOpen , which refactors our __LP64__ tests to be tests of the header magic instead. I've simplified things by using what we've pre-loaded into "context" and making some helper functions so the conditionals in most of the code say what they do, instead of how they work. Note that we're only allowing that from in_protocol's loader - that is, we'll let 64-bit grub load a 32-bit kernel or 32-bit grub load a 64-bit kernel, but 32-bit shim isn't loading a 64-bit grub. Signed-off-by: Peter Jones <pjones@redhat.com>
2014-09-19Actually refer to the base relocation table of our loaded image.Peter Jones
Currently when we process base relocations, we get the correct Data Directory pointer from the headers (context->RelocDir), and that header has been copied into our pristine allocated image when we copied up to SizeOfHeaders. But the data it points to has not been mirrored in to the new image, so it is whatever data AllocPool() gave us. This patch changes relocate_coff() to refer to the base relocation table from the image we loaded from disk, but apply the fixups to the new copy. I have no idea how x86_64 worked without this, but I can't make aarch64 work without it. I also don't know how Ard or Leif have seen aarch64 work. Maybe they haven't? Leif indicated on irc that they may have only tested shim with simple "hello world" applications from gnu-efi; they are certainly much less complex than grub.efi, and are generated through a different linking process. My only theory is that we're getting recycled data there pretty reliably that just makes us /not/ process any relocations, but since our ImageBase is 0, and I don't think we ever load grub with 0 as its base virtual address, that doesn't follow. I'm open to any other ideas anybody has. I do know that on x86_64 (and presumably aarch64 as well), we don't actually start seeing *symptoms* of this bug until the first chunk[0] of 94c9a77f is applied[1]. Once that is applied, relocate_coff() starts seeing zero[2] for both RelocBase->VirtualAddress and RelocBase->SizeOfBlock, because RelocBase is a (generated, relative) pointer that only makes sense in the context of the original binary, not our partial copy. Since RelocBase->SizeOfBlock is tested first, relocate_base() gives us "Reloc block size is invalid"[3] and returns EFI_UNSUPPORTED. At that point shim exits with an error. [0] The second chunk of 94c9a77f patch makes no difference on this issue. [1] I don't see why at all. [2] Which could really be any value since it's AllocatePool() and not AllocateZeroPool() results, but 0 is all I've observed; I think AllocatePool() has simply never recycled any memory in my test cases. [3] which is silent because perror() tries to avoid talking because that has caused much crashing in the past; work needs to go in to 0.9 for this. Signed-off-by: Peter Jones <pjones@redhat.com>
2014-08-27Make sure we don't try to load a binary from a different arch.Peter Jones
Since in theory you could, for example, get an x86_64 binary signed that also behaves as an ARM executable, we should be checking this before people build on other architectures. Signed-off-by: Peter Jones <pjones@redhat.com>
2014-08-27Handle empty .reloc section in PE/COFF loaderArd Biesheuvel
On archs where no EFI aware objcopy is available, the generated PE/COFF header contains a .reloc section which is completely empty. Handle this by - returning early from relocate_coff() with EFI_SUCCESS, - ignoring discardable sections in the section loader. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>