MODSIGN: load blacklist from MOKx
authorBen Hutchings <benh@debian.org>
Sun, 15 Nov 2020 01:01:03 +0000 (01:01 +0000)
committerSalvatore Bonaccorso <carnil@debian.org>
Thu, 30 Sep 2021 19:36:41 +0000 (20:36 +0100)
Loosely based on a patch by "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
at <https://lore.kernel.org/patchwork/patch/933177/> which was later
rebased by Luca Boccassi.

This patch adds the logic to load the blacklisted hash and
certificates from MOKx which is maintained by shim bootloader.

Since MOK list loading became more complicated in 5.10 and was moved
to load_moklist_certs(), add parameters to that and call it once for
each of MokListRT and MokListXRT.

Signed-off-by: Ben Hutchings <benh@debian.org>
[Salvatore Bonaccorso: Forward-port to 5.10.47: Drop upstream hunk to get the
MokListXRT certificates as we do load via load_moklist_certs().]

Gbp-Pq: Topic features/all/db-mok-keyring
Gbp-Pq: Name 0002-MODSIGN-load-blacklist-from-MOKx.patch

security/integrity/platform_certs/load_uefi.c

index 2969927e6aadde0aa6beeb338705abd7ca124355..632115312d427397981b1098fae2529268eadd6c 100644 (file)
@@ -76,49 +76,59 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
  *
  * Return:     Status
  */
-static int __init load_moklist_certs(void)
+static int __init
+load_moklist_certs(const char *list_name, efi_char16_t *list_name_w,
+                  efi_element_handler_t (*get_handler)(const efi_guid_t *))
 {
        struct efi_mokvar_table_entry *mokvar_entry;
        efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
        void *mok;
        unsigned long moksize;
        efi_status_t status;
+       char mokvar_list_desc[40];
+       char efivar_list_desc[20];
        int rc;
 
+       snprintf(mokvar_list_desc, sizeof(mokvar_list_desc),
+                "UEFI:%s (MOKvar table)", list_name);
+       snprintf(efivar_list_desc, sizeof(efivar_list_desc),
+                "UEFI:%s", list_name);
+
        /* First try to load certs from the EFI MOKvar config table.
         * It's not an error if the MOKvar config table doesn't exist
-        * or the MokListRT entry is not found in it.
+        * or the MokList(X)RT entry is not found in it.
         */
-       mokvar_entry = efi_mokvar_entry_find("MokListRT");
+       mokvar_entry = efi_mokvar_entry_find(list_name);
        if (mokvar_entry) {
-               rc = parse_efi_signature_list("UEFI:MokListRT (MOKvar table)",
+               rc = parse_efi_signature_list(mokvar_list_desc,
                                              mokvar_entry->data,
                                              mokvar_entry->data_size,
-                                             get_handler_for_db);
+                                             get_handler);
                /* All done if that worked. */
                if (!rc)
                        return rc;
 
-               pr_err("Couldn't parse MokListRT signatures from EFI MOKvar config table: %d\n",
-                      rc);
+               pr_err("Couldn't parse %s signatures from EFI MOKvar config table: %d\n",
+                      list_name, rc);
        }
 
-       /* Get MokListRT. It might not exist, so it isn't an error
+       /* Get MokList(X)RT. It might not exist, so it isn't an error
         * if we can't get it.
         */
-       mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status);
+       mok = get_cert_list(list_name_w, &mok_var, &moksize, &status);
        if (mok) {
-               rc = parse_efi_signature_list("UEFI:MokListRT",
-                                             mok, moksize, get_handler_for_db);
+               rc = parse_efi_signature_list(efivar_list_desc,
+                                             mok, moksize, get_handler);
                kfree(mok);
                if (rc)
-                       pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
+                       pr_err("Couldn't parse %s signatures: %d\n",
+                              list_name, rc);
                return rc;
        }
        if (status == EFI_NOT_FOUND)
-               pr_debug("MokListRT variable wasn't found\n");
+               pr_debug("%s variable wasn't found\n", list_name);
        else
-               pr_info("Couldn't get UEFI MokListRT\n");
+               pr_info("Couldn't get UEFI %s\n", list_name);
        return 0;
 }
 
@@ -176,27 +186,17 @@ static int __init load_uefi_certs(void)
                kfree(dbx);
        }
 
-       mokx = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &status);
-       if (!mokx) {
-               if (status == EFI_NOT_FOUND)
-                       pr_debug("mokx variable wasn't found\n");
-               else
-                       pr_info("Couldn't get mokx list\n");
-       } else {
-               rc = parse_efi_signature_list("UEFI:MokListXRT",
-                                             mokx, mokxsize,
-                                             get_handler_for_dbx);
-               if (rc)
-                       pr_err("Couldn't parse mokx signatures %d\n", rc);
-               kfree(mokx);
-       }
-
-       /* the MOK can not be trusted when secure boot is disabled */
+       /* the MOK and MOKx can not be trusted when secure boot is disabled */
        if (!efi_enabled(EFI_SECURE_BOOT))
                return 0;
 
        /* Load the MokListRT certs */
-       rc = load_moklist_certs();
+       rc = load_moklist_certs("MokListRT", L"MokListRT",
+                               get_handler_for_db);
+       if (rc)
+               return rc;
+       rc = load_moklist_certs("MokListXRT", L"MokListXRT",
+                               get_handler_for_dbx);
 
        return rc;
 }