Skip to content

Commit

Permalink
shim: compile time option to bypass the ExitBootServices() check
Browse files Browse the repository at this point in the history
On systems where a second stage bootloader is not used, and the Linux
Kernel is booted directly from shim, shim's ExitBootServices() hook
can cause problems as the kernel never calls the shim's verification
protocol.  In this case calling the shim verification protocol is
unnecessary and redundant as shim has already verified the kernel
when shim loaded the kernel as the second stage loader.

This functionality is disabled by default and must be enabled via the
DISABLE_EBS_PROTECTION macro/define at build time.

Signed-off-by: Paul Moore <[email protected]>
  • Loading branch information
pcmoore authored and vathpela committed Jan 29, 2021
1 parent 1f123ac commit 4b0a61d
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Make.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ ifneq ($(origin REQUIRE_TPM), undefined)
CFLAGS += -DREQUIRE_TPM
endif

ifneq ($(origin DISABLE_EBS_PROTECTION), undefined)
CFLAGS += -DDISABLE_EBS_PROTECTION
endif

LIB_GCC = $(shell $(CC) $(ARCH_CFLAGS) -print-libgcc-file-name)
EFI_LIBS = -lefi -lgnuefi --start-group Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a --end-group $(LIB_GCC)
FORMAT ?= --target efi-app-$(ARCH)
Expand Down
7 changes: 7 additions & 0 deletions replacements.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ replacement_start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 *
return efi_status;
}

#if !defined(DISABLE_EBS_PROTECTION)
static EFI_STATUS EFIAPI
exit_boot_services(EFI_HANDLE image_key, UINTN map_key)
{
Expand All @@ -150,6 +151,7 @@ exit_boot_services(EFI_HANDLE image_key, UINTN map_key)
gRT->ResetSystem(EfiResetShutdown, EFI_SECURITY_VIOLATION, 0, NULL);
return EFI_SECURITY_VIOLATION;
}
#endif /* !defined(DISABLE_EBS_PROTECTION) */

static EFI_STATUS EFIAPI
do_exit(EFI_HANDLE ImageHandle, EFI_STATUS ExitStatus,
Expand Down Expand Up @@ -199,17 +201,22 @@ hook_system_services(EFI_SYSTEM_TABLE *local_systab)
system_start_image = systab->BootServices->StartImage;
systab->BootServices->StartImage = replacement_start_image;

#if !defined(DISABLE_EBS_PROTECTION)
/* we need to hook ExitBootServices() so a) we can enforce the policy
* and b) we can unwrap when we're done. */
system_exit_boot_services = systab->BootServices->ExitBootServices;
systab->BootServices->ExitBootServices = exit_boot_services;
#endif /* defined(DISABLE_EBS_PROTECTION) */
}

void
unhook_exit(void)
{
#if !defined(DISABLE_EBS_PROTECTION)
systab->BootServices->Exit = system_exit;
gBS = systab->BootServices;
#endif /* defined(DISABLE_EBS_PROTECTION) */
return;
}

void
Expand Down

1 comment on commit 4b0a61d

@xnox
Copy link
Contributor

@xnox xnox commented on 4b0a61d Mar 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsetje @vathpela

I wonder if we actually want this enabled by default.

I think this comes from the time when very early Shim+grub integrations did not have signed grub nor kernels. Then later grub & kernels did become signed. But it has become mandatory to have things signed.

These days it should not be necessary to enforce this check any more, as one can choose to chain things that may or may not participate in validation.

Without this option enabled by default we cannot do the following things:

  • chainload new shim, from network loaded shim+grub pair. For example to direct networked boot to boot a linux distro from disk, even if efivariables are missing or are incorrect.
  • chainload signed kernel.efi (Type 2 BootLoaderSpecification)
  • chainloading windows bootmgr from shim, without grub (very odd, but i have seen people try that too)

The above actions result in one out of multiple shim protocols possibly not being used for validation. Whilst actually in fact not compromising lockdown/signing promise.

I would want to enable this option to use by default in Ubuntu UC20 & MAAS

  • to allow chainloading from one ESP to another ESP
  • to allow chainloading from network boot of one distro shim to possibly another Network boot or Local boot to another distro shim.

Please sign in to comment.