From 062663b7ebc91df5b9e35a44351d7c3c86f3439f Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <julian.klode@canonical.com>
Date: Wed, 4 Aug 2021 10:46:45 +0200
Subject: [PATCH] shim: Don't parse load options if invoked from removable
 media path

We see various reports of boot failures because the generated
boot entries contain garbage/tagging that we do not expect, and
that we then parse as a second stage boot loader.
---
 BUILDING      |  6 ++++++
 Make.defaults |  4 ++++
 shim.c        | 11 +++++++++++
 3 files changed, 21 insertions(+)

diff --git a/BUILDING b/BUILDING
index ff1390fa9..2da9b5f04 100644
--- a/BUILDING
+++ b/BUILDING
@@ -45,6 +45,12 @@ Variables you could set to customize the build:
   shim has already verified the kernel when shim loaded the kernel as the
   second stage loader.  In such a case, and only in this case, you should
   use DISABLE_EBS_PROTECTION=y to build.
+- DISABLE_REMOVABLE_LOAD_OPTIONS
+  Do not parse load options when invoked as boot*.efi. This prevents boot
+  failures because of unexpected data in boot entries automatically generated
+  by firmware. It breaks loading non-default second-stage loaders when invoked
+  via that path, and requires using a binary named shim*.efi (or really anything
+  else).
 - REQUIRE_TPM
   if tpm logging or extends return an error code, treat that as a fatal error.
 - ARCH
diff --git a/Make.defaults b/Make.defaults
index 1b929a710..af7a4cd3c 100644
--- a/Make.defaults
+++ b/Make.defaults
@@ -148,6 +148,10 @@ ifneq ($(origin DISABLE_EBS_PROTECTION), undefined)
 	DEFINES  += -DDISABLE_EBS_PROTECTION
 endif
 
+ifneq ($(origin DISABLE_REMOVABLE_LOAD_OPTIONS), undefined)
+	DEFINES  += -DDISABLE_REMOVABLE_LOAD_OPTIONS
+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)
diff --git a/shim.c b/shim.c
index febd27065..290767fb0 100644
--- a/shim.c
+++ b/shim.c
@@ -1177,6 +1177,17 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
 		return efi_status;
 	}
 
+#if defined(DISABLE_REMOVABLE_LOAD_OPTIONS)
+	/*
+	 * boot services build very strange load options, and we might misparse them,
+	 * causing boot failures on removable media.
+	 */
+	if (is_removable_media_path(li)) {
+		dprint("Invoked from removable media path, ignoring boot options");
+		return EFI_SUCCESS;
+	}
+#endif
+
 	efi_status = parse_load_options(li);
 	if (EFI_ERROR(efi_status)) {
 		perror (L"Failed to get load options: %r\n", efi_status);