@@ -30,3 +30,11 @@ efi_element_handler_t get_handler_for_db(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
@@ -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,32 @@
#include "../integrity.h"
#include "keyring_handler.h"
+/* Apple Macs with T2 Security chip don't support these UEFI variables.
+ * The T2 chip manages the Secure Boot and does not allow Linux to boot
+ * if it is turned on. If turned off, an attempt to get certificates
+ * causes a crash, so we simply return 0 for them in each function.
+ */
+
+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.
@@ -21,12 +48,18 @@
* is set, we should ignore the db variable also and the true return indicates
* this.
*/
+
static __init bool uefi_check_ignore_db(void)
{
efi_status_t status;
unsigned int db = 0;
unsigned long size = sizeof(db);
efi_guid_t guid = EFI_SHIM_LOCK_GUID;
+ const struct dmi_system_id *dmi_id;
+
+ dmi_id = dmi_first_match(uefi_skip_cert);
+ if (dmi_id)
+ return 0;
status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db);
return status == EFI_SUCCESS;
@@ -41,6 +74,11 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
unsigned long lsize = 4;
unsigned long tmpdb[4];
void *db;
+ const struct dmi_system_id *dmi_id;
+
+ dmi_id = dmi_first_match(uefi_skip_cert);
+ if (dmi_id)
+ return 0;
*status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
if (*status == EFI_NOT_FOUND)
@@ -85,6 +123,11 @@ static int __init load_moklist_certs(void)
unsigned long moksize;
efi_status_t status;
int rc;
+ const struct dmi_system_id *dmi_id;
+
+ dmi_id = dmi_first_match(uefi_skip_cert);
+ if (dmi_id)
+ return 0;
/* First try to load certs from the EFI MOKvar config table.
* It's not an error if the MOKvar config table doesn't exist
@@ -138,6 +181,11 @@ 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)
+ return 0;
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
return false;