From patchwork Mon Sep 27 15:58:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dimitri John Ledkov X-Patchwork-Id: 1533440 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=SGFk0MC8; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HJ6lC16H8z9tk7 for ; Tue, 28 Sep 2021 01:59:19 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mUt26-0007Ak-1Z; Mon, 27 Sep 2021 15:59:10 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mUt1z-000755-2I for kernel-team@lists.ubuntu.com; Mon, 27 Sep 2021 15:59:03 +0000 Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id AFC5C3F4B9 for ; Mon, 27 Sep 2021 15:59:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1632758342; bh=qHaaFKNySUxGp6i527ZRYdQNVg9ZEuqFjTCuTW8nNN0=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=SGFk0MC8fFHAX5O7GNeUCGMnaZoMrV5zzJgmN0GoRchPiSPsqZfrt1i7SlvNorT0G FCwTL6EmjZK/+ULebtpI0AH1eQ2PmaLfr7DZHetRdtrLbl0TP/pQeFZkzQ3HZVjSs7 oux8orEs7t20E+ncObf9TWecitxRm6IJO/oPlC+vT951tdvmu0/JpC7Qnwlfl5fQrx FIsGDR++XTCSOTEeUui7/ID9Y0J6AhsmrlLgQ+2LMlqA5PVLT8j7wuBgjU1ATZjNMK 8ThNzYYkR1uGw2jBOYvTxw3xAolNEaNnrLYW1Jlv6qGPP2xM+DuS2v+24GEDqLOKCZ IX63dMGXgUSkQ== Received: by mail-wr1-f70.google.com with SMTP id c15-20020a5d4ccf000000b0015dff622f39so14218202wrt.21 for ; Mon, 27 Sep 2021 08:59:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qHaaFKNySUxGp6i527ZRYdQNVg9ZEuqFjTCuTW8nNN0=; b=FZ50DO8NYCllvUhGlsy6+WU5USe7pjV4KleYQWvB2R7iu0MdjF2pN/uKEl1U8LP5Bl +kcxdwkFKqjfKxBmsV8eVf037crT/1ujjmrEEthRPBZeqogjqrnt4ecb4icEbKStxIJS w0GGhqBx4+Fj6ze8U06hz2vPCPo9R9dIPN/ZbU8kzop1+NDONrKvoW3ny9UKg66g3qu2 uGih36iqo6qzXMX617WvSiKBjWmGgAGmA7MtLn6C3gMQRiDaa1wl/jijMduKFYD+S74q 3XBbL0ZH2wG9aTFEaJw9baWM75GiMWJgzXqce2WzNDk/V2x0r8Ej8FiwB4q9JM48WQHg AoVA== X-Gm-Message-State: AOAM5310hQng1tgTsoVRJdJZtFUzooIXnGxsA2t/xmvvybe4NZkoRnjq ZY5GNyR/tkBd855TjPOFtLhsfZGEacZOMQbANZuXkq3DqPfIotA4pbhGceXi4N5eYjQSp3VuOlD aSjrJao/pZa9VuxrfyNVXeHbEwSS6rqIEUU3CgnVdnw== X-Received: by 2002:adf:f687:: with SMTP id v7mr647174wrp.347.1632758342071; Mon, 27 Sep 2021 08:59:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJydLG/Xv4neHE7d+Q79R4M+dBWffCv8Sx+9IEHXYjz6VmpgOh1PZyPyRrsV9n4NCjnDXptkVg== X-Received: by 2002:adf:f687:: with SMTP id v7mr647144wrp.347.1632758341727; Mon, 27 Sep 2021 08:59:01 -0700 (PDT) Received: from localhost ([2a01:4b00:85fd:d700:86ad:7d9c:de94:eed0]) by smtp.gmail.com with ESMTPSA id z12sm8818153wmf.21.2021.09.27.08.59.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 08:59:01 -0700 (PDT) From: Dimitri John Ledkov To: kernel-team@lists.ubuntu.com Subject: [SRU][F/hwe-5.8][PATCH 13/18] UBUNTU: SAUCE: integrity: Load mokx certs from the EFI MOK config table Date: Mon, 27 Sep 2021 16:58:32 +0100 Message-Id: <20210927155837.164674-8-dimitri.ledkov@canonical.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210927155837.164674-1-dimitri.ledkov@canonical.com> References: <20210927155712.164337-1-dimitri.ledkov@canonical.com> <20210927155837.164674-1-dimitri.ledkov@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" Refactor load_moklist_certs() to load either MokListRT into db, or MokListXRT into dbx. Call load_moklist_certs() twice - first to load mokx certs into dbx, then mok certs into db. This thus now attempts to load mokx certs via the EFI MOKvar config table first, and if that fails, via the EFI variable. Previously mokx certs were only loaded via the EFI variable. Which fails when MokListXRT is large. Instead of large MokListXRT variable, only MokListXRT{1,2,3} are available which are not loaded. This is the case with Ubuntu's 15.4 based shim. This patch is required to address CVE-2020-26541 when certificates are revoked via MokListXRT. Fixes: ebd9c2ae369a ("integrity: Load mokx variables into the blacklist keyring") BugLink: https://bugs.launchpad.net/bugs/1928679 Signed-off-by: Dimitri John Ledkov Acked-by: Krzysztof Kozlowski Signed-off-by: Seth Forshee (cherry picked from commit a9e3aae16235d6af12509a64f1337da4485ccbae) (xnox: cherry-pick is from impish:linux SAUCE) Signed-off-by: Dimitri John Ledkov --- security/integrity/platform_certs/load_uefi.c | 74 ++++++++++--------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c index d3e7ae04f5..b010b4ab5d 100644 --- a/security/integrity/platform_certs/load_uefi.c +++ b/security/integrity/platform_certs/load_uefi.c @@ -68,17 +68,18 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, } /* - * load_moklist_certs() - Load MokList certs + * load_moklist_certs() - Load Mok(X)List certs + * @load_db: Load MokListRT into db when true; MokListXRT into dbx when false * - * Load the certs contained in the UEFI MokListRT database into the - * platform trusted keyring. + * Load the certs contained in the UEFI MokList(X)RT database into the + * platform trusted/denied keyring. * * This routine checks the EFI MOK config table first. If and only if - * that fails, this routine uses the MokListRT ordinary UEFI variable. + * that fails, this routine uses the MokList(X)RT ordinary UEFI variable. * * Return: Status */ -static int __init load_moklist_certs(void) +static int __init load_moklist_certs(const bool load_db) { struct efi_mokvar_table_entry *mokvar_entry; efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; @@ -86,41 +87,55 @@ static int __init load_moklist_certs(void) unsigned long moksize; efi_status_t status; int rc; + const char *mokvar_name = "MokListRT"; + /* Should be const, but get_cert_list() doesn't have it as const yet */ + efi_char16_t *efivar_name = L"MokListRT"; + const char *parse_mokvar_name = "UEFI:MokListRT (MOKvar table)"; + const char *parse_efivar_name = "UEFI:MokListRT"; + efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *) = get_handler_for_db; + + if (!load_db) { + mokvar_name = "MokListXRT"; + efivar_name = L"MokListXRT"; + parse_mokvar_name = "UEFI:MokListXRT (MOKvar table)"; + parse_efivar_name = "UEFI:MokListXRT"; + get_handler_for_guid = get_handler_for_dbx; + } /* 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. */ - mokvar_entry = efi_mokvar_entry_find("MokListRT"); + mokvar_entry = efi_mokvar_entry_find(mokvar_name); if (mokvar_entry) { - rc = parse_efi_signature_list("UEFI:MokListRT (MOKvar table)", + rc = parse_efi_signature_list(parse_mokvar_name, mokvar_entry->data, mokvar_entry->data_size, - get_handler_for_db); + get_handler_for_guid); /* 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", + mokvar_name, rc); } /* Get MokListRT. 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(efivar_name, &mok_var, &moksize, &status); if (mok) { - rc = parse_efi_signature_list("UEFI:MokListRT", - mok, moksize, get_handler_for_db); + rc = parse_efi_signature_list(parse_efivar_name, + mok, moksize, get_handler_for_guid); kfree(mok); if (rc) - pr_err("Couldn't parse MokListRT signatures: %d\n", rc); + pr_err("Couldn't parse %s signatures: %d\n", mokvar_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", mokvar_name); else - pr_info("Couldn't get UEFI MokListRT\n"); + pr_info("Couldn't get UEFI %s\n", mokvar_name); return 0; } @@ -134,9 +149,8 @@ static int __init load_moklist_certs(void) static int __init load_uefi_certs(void) { efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; - efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; - void *db = NULL, *dbx = NULL, *mokx = NULL; - unsigned long dbsize = 0, dbxsize = 0, mokxsize = 0; + void *db = NULL, *dbx = NULL; + unsigned long dbsize = 0, dbxsize = 0; efi_status_t status; int rc = 0; @@ -178,23 +192,15 @@ 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); - } + /* Load the MokListXRT certs */ + rc = load_moklist_certs(false); + if (rc) + pr_err("Couldn't parse mokx signatures: %d\n", rc); /* Load the MokListRT certs */ - rc = load_moklist_certs(); + rc = load_moklist_certs(true); + if (rc) + pr_err("Couldn't parse mok signatures: %d\n", rc); return rc; }