diff mbox series

[v7] efi: Do not import certificates from UEFI Secure Boot for T2 Macs

Message ID 958B8D22-F11E-4B5D-9F44-6F0626DBCB63@live.com
State Superseded
Headers show
Series [v7] efi: Do not import certificates from UEFI Secure Boot for T2 Macs | expand

Commit Message

Aditya Garg April 15, 2022, 5:02 p.m. UTC
From: Aditya Garg <gargaditya08@live.com>

On Apple T2 Macs, when Linux attempts to read the db and dbx efi variables
at early boot to load UEFI Secure Boot certificates, a page fault occurs
in Apple firmware code and EFI runtime services are disabled with the
following logs:

[Firmware Bug]: Page fault caused by firmware at PA: 0xffffb1edc0068000
WARNING: CPU: 3 PID: 104 at arch/x86/platform/efi/quirks.c:735 efi_crash_gracefully_on_page_fault+0x50/0xf0
(Removed some logs from here)
Call Trace:
 <TASK>
 page_fault_oops+0x4f/0x2c0
 ? search_bpf_extables+0x6b/0x80
 ? search_module_extables+0x50/0x80
 ? search_exception_tables+0x5b/0x60
 kernelmode_fixup_or_oops+0x9e/0x110
 __bad_area_nosemaphore+0x155/0x190
 bad_area_nosemaphore+0x16/0x20
 do_kern_addr_fault+0x8c/0xa0
 exc_page_fault+0xd8/0x180
 asm_exc_page_fault+0x1e/0x30
(Removed some logs from here)
 ? __efi_call+0x28/0x30
 ? switch_mm+0x20/0x30
 ? efi_call_rts+0x19a/0x8e0
 ? process_one_work+0x222/0x3f0
 ? worker_thread+0x4a/0x3d0
 ? kthread+0x17a/0x1a0
 ? process_one_work+0x3f0/0x3f0
 ? set_kthread_struct+0x40/0x40
 ? ret_from_fork+0x22/0x30
 </TASK>
---[ end trace 1f82023595a5927f ]---
efi: Froze efi_rts_wq and disabled EFI Runtime Services
integrity: Couldn't get size: 0x8000000000000015
integrity: MODSIGN: Couldn't get UEFI db list
efi: EFI Runtime Services are disabled!
integrity: Couldn't get size: 0x8000000000000015
integrity: Couldn't get UEFI dbx list
integrity: Couldn't get size: 0x8000000000000015
integrity: Couldn't get mokx list
integrity: Couldn't get size: 0x80000000

So we avoid reading these UEFI variables and thus prevent the crash.

Cc: stable@vger.kernel.org
Signed-off-by: Aditya Garg <gargaditya08@live.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
---
v2 :- Reduce code size of the table.
v3 :- Close the brackets which were left open by mistake.
v4 :- Fix comment style issues, remove blank spaces and limit use of dmi_first_match()
v4 RESEND :- Add stable to cc
v5 :- Rewrite the description
v6 :- Make description more clear
v7 :- Minor changes and add reviewed by
 .../platform_certs/keyring_handler.h          |  8 +++++
 security/integrity/platform_certs/load_uefi.c | 33 +++++++++++++++++++
 2 files changed, 41 insertions(+)

Comments

Mimi Zohar May 13, 2022, 3:24 p.m. UTC | #1
Hi Aditya,

On Fri, 2022-04-15 at 17:02 +0000, Aditya Garg wrote:
> From: Aditya Garg <gargaditya08@live.com>
> 
> On Apple T2 Macs, when Linux attempts to read the db and dbx efi variables
> at early boot to load UEFI Secure Boot certificates, a page fault occurs
> in Apple firmware code and EFI runtime services are disabled with the
> following logs:

Are there directions for installing Linux on a Mac with Apple firmware
code?  Are you dual booting Linux and Mac, or just Linux?  While in
secure boot mode, without being able to read the keys to verify the
kernel image signature, the signature verification should fail.

Has anyone else tested this patch?

thanks,

Mimi
Aditya Garg May 13, 2022, 6:31 p.m. UTC | #2
> Are there directions for installing Linux on a Mac with Apple firmware
> code?  

Well, directions of installing Linux on an Intel based Mac, which includes the T2 Macs is the same as on a normal PC.

Though, in case of T2 Macs, we for now need to use customised ISOs, since some drivers and patches to support T2 Macs are yet to be upstreamed.

An example of installing Ubuntu can be read here on https://wiki.t2linux.org/distributions/ubuntu/installation/

Talking about the official ISOs, for many distros, since CONFIG_LOAD_UEFI_KEYS is not enabled in their kernel config, we can install Linux using them, but they still lack many drivers required, since they are yet to be upstreamed. So the installation doesn’t work efficiently and we have to manually install custom kernels having those patches.

In some distros like Ubuntu, they have CONFIG_LOAD_UEFI_KEYS enabled in their kernel config. In this case the crash as mentioned in the patch description occurs and EFI Runtime Services get disabled. Since installing GRUB requires access to NVRAM, the installation fails with official ISOs in this case. Thus, a custom ISO, with this patch incorporated in being used for now for users interested in Ubuntu on T2 Macs.

> Are you dual booting Linux and Mac, or just Linux?

I don’t think it actually matters, though in most of the cases, we dual boot macOS and Linux, but I do have seen cases who wipe out their macOS completely. But this doesn't affect the Secure Boot policy of these machines.

>  While in
> secure boot mode, without being able to read the keys to verify the
> kernel image signature, the signature verification should fail.

If I enable secure boot in the BIOS settings (macOS Recovery), Apple’s firmware won't allow even the boot loader like GRUB, rEFInd to boot. It shall only allow Windows and macOS to Boot. You could see https://support.apple.com/en-in/HT208198 for more details.

> 
> Has anyone else tested this patch?

I work as a maintainer for Ubuntu for T2 Linux community and I have this patch incorporated in the kernels used for Ubuntu ISOs customised for T2 Macs, and thus have many users who have used the ISO and have a successful installation. Thus, there are many users who have tested this patch and are actually using it right now.
We also need the have the NVRAM writes enabled so as to unlock the iGPU in Macs with both Intel and AMD GPU, and with this patch, we have been successfully able to unlock it,

I hope I could answer your questions

Regards
Aditya
diff mbox series

Patch

diff --git a/security/integrity/platform_certs/keyring_handler.h b/security/integrity/platform_certs/keyring_handler.h
index 284558f30..212d894a8 100644
--- a/security/integrity/platform_certs/keyring_handler.h
+++ b/security/integrity/platform_certs/keyring_handler.h
@@ -35,3 +35,11 @@  efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type);
 efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type);
 
 #endif
+
+#ifndef UEFI_QUIRK_SKIP_CERT
+#define UEFI_QUIRK_SKIP_CERT(vendor, product) \
+		 .matches = { \
+			DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
+			DMI_MATCH(DMI_PRODUCT_NAME, product), \
+		},
+#endif
diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
index 5f45c3c07..1a7e7d597 100644
--- a/security/integrity/platform_certs/load_uefi.c
+++ b/security/integrity/platform_certs/load_uefi.c
@@ -3,6 +3,7 @@ 
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/cred.h>
+#include <linux/dmi.h>
 #include <linux/err.h>
 #include <linux/efi.h>
 #include <linux/slab.h>
@@ -12,6 +13,31 @@ 
 #include "../integrity.h"
 #include "keyring_handler.h"
 
+/*
+ * On T2 Macs reading the db and dbx efi variables to load UEFI Secure Boot
+ * certificates causes occurrence of a page fault in Apple's firmware and
+ * a crash disabling EFI runtime services. The following quirk skips reading
+ * these variables.
+ */
+static const struct dmi_system_id uefi_skip_cert[] = {
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,1") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,2") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,3") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,4") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,1") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,2") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,3") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,4") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,1") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,2") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir9,1") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacMini8,1") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") },
+	{ }
+};
+
 /*
  * Look to see if a UEFI variable called MokIgnoreDB exists and return true if
  * it does.
@@ -138,6 +164,13 @@  static int __init load_uefi_certs(void)
 	unsigned long dbsize = 0, dbxsize = 0, mokxsize = 0;
 	efi_status_t status;
 	int rc = 0;
+	const struct dmi_system_id *dmi_id;
+
+	dmi_id = dmi_first_match(uefi_skip_cert);
+	if (dmi_id) {
+		pr_err("Reading UEFI Secure Boot Certs is not supported on T2 Macs.\n");
+		return false;
+	}
 
 	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
 		return false;