From patchwork Mon Jan 8 07:24:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Hu X-Patchwork-Id: 856733 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=fwts-devel-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3zFRbn16Tlz9s7f; Mon, 8 Jan 2018 18:24:21 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1eYRn7-0004nq-Vm; Mon, 08 Jan 2018 07:24:17 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1eYRn5-0004nb-TK for fwts-devel@lists.ubuntu.com; Mon, 08 Jan 2018 07:24:15 +0000 Received: from 112-104-27-88.adsl.dynamic.seed.net.tw ([112.104.27.88] helo=canonical.com) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1eYRn5-0004TA-4l; Mon, 08 Jan 2018 07:24:15 +0000 From: Ivan Hu To: fwts-devel@lists.ubuntu.com Subject: [PATCH 1/2] securebootcert: add checking read-only for the AuditMode and DeployedMode Date: Mon, 8 Jan 2018 15:24:08 +0800 Message-Id: <1515396249-7923-1-git-send-email-ivan.hu@canonical.com> X-Mailer: git-send-email 2.7.4 X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: fwts-devel-bounces@lists.ubuntu.com Sender: "fwts-devel" UEFI spec 2.7 add the update of AuditMode and DeplyedMode variable, these two global variables should be always becomes read-only after ExitBootServices() is called. Add the testing read-only by setting variables, no EFI_SUCCESS return is expected. Signed-off-by: Ivan Hu Acked-by: Alex Hung Acked-by: Colin Ian King --- src/uefi/securebootcert/securebootcert.c | 131 +++++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 7 deletions(-) diff --git a/src/uefi/securebootcert/securebootcert.c b/src/uefi/securebootcert/securebootcert.c index a74c55d..60fc489 100644 --- a/src/uefi/securebootcert/securebootcert.c +++ b/src/uefi/securebootcert/securebootcert.c @@ -22,10 +22,16 @@ #include #include +#include #include "fwts_uefi.h" #include "sbkeydefs.h" +#include "fwts_efi_runtime.h" +#include "fwts_efi_module.h" + +static int fd; + typedef void (*securebootcert_func)(fwts_framework *fw, fwts_uefi_var *var, char *varname); typedef struct { @@ -33,13 +39,6 @@ typedef struct { securebootcert_func func; /* Function to dump this variable */ } securebootcert_info; -typedef struct { - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[8]; -} __attribute__ ((packed)) EFI_GUID; - typedef struct _EFI_SIGNATURE_LIST { EFI_GUID SignatureType; uint32_t SignatureListSize; @@ -70,6 +69,11 @@ static uint8_t var_found; static bool securebooted = false; static bool deployed = false; +static EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; + +static uint16_t varauditmode[] = {'A', 'u', 'd', 'i', 't', 'M', 'o', 'd', 'e', '\0'}; +static uint16_t vardeploymode[] = {'D', 'e', 'p', 'l', 'o', 'y', 'e', 'd', 'M', 'o', 'd', 'e', '\0'}; + static bool compare_guid(EFI_GUID *guid1, uint8_t *guid2) { bool ident = true; @@ -429,6 +433,25 @@ static int securebootcert_init(fwts_framework *fw) return FWTS_ABORTED; } + if (fwts_lib_efi_runtime_load_module(fw) != FWTS_OK) { + fwts_log_info(fw, "Cannot load efi_runtime module. Aborted."); + return FWTS_ABORTED; + } + + fd = fwts_lib_efi_runtime_open(); + if (fd == -1) { + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); + return FWTS_ABORTED; + } + + return FWTS_OK; +} + +static int securebootcert_deinit(fwts_framework *fw) +{ + fwts_lib_efi_runtime_close(fd); + fwts_lib_efi_runtime_unload_module(fw); + return FWTS_OK; } @@ -492,14 +515,108 @@ static int securebootcert_test1(fwts_framework *fw) return FWTS_OK; } +static int securebootcert_setvar( + fwts_framework *fw, + const uint32_t attributes, + uint16_t *varname, + EFI_GUID *guid, + uint8_t *data) +{ + long ioret; + struct efi_setvariable setvariable; + + uint64_t status; + uint64_t datasize = 1; + + setvariable.VariableName = varname; + setvariable.VendorGuid = guid; + setvariable.Attributes = attributes; + setvariable.DataSize = datasize; + setvariable.Data = data; + setvariable.status = &status; + ioret = ioctl(fd, EFI_RUNTIME_SET_VARIABLE, &setvariable); + + if (ioret == -1) { + if (status == EFI_OUT_OF_RESOURCES) { + fwts_uefi_print_status_info(fw, status); + fwts_skipped(fw, + "Run out of resources for SetVariable " + "UEFI runtime interface: cannot test."); + fwts_advice(fw, + "Firmware may reclaim some resources " + "after rebooting. Reboot and test " + "again may be helpful to continue " + "the test."); + return FWTS_SKIP; + } + } + + if (status == EFI_SUCCESS) { + fwts_failed(fw, LOG_LEVEL_HIGH, + "UEFISecurebooCertVar", + "Variable is ready only, return status of setvariable " + "should not EFI_SUCCESS."); + } else + fwts_passed(fw, "Variable read-only test passed."); + return FWTS_OK; +} + +static int securebootcert_test2(fwts_framework *fw) +{ + int ret; + uint8_t data = 0; + static uint32_t attributes = FWTS_UEFI_VAR_NON_VOLATILE | + FWTS_UEFI_VAR_BOOTSERVICE_ACCESS | + FWTS_UEFI_VAR_RUNTIME_ACCESS; + + if (!(var_found & VAR_AUDITMODE_FOUND)) { + fwts_skipped(fw, + "No AuditMode variable found, skip the varaible test."); + return FWTS_SKIP; + } + + fwts_log_info(fw, "AuditMode variable read-only test, set to 0."); + ret = securebootcert_setvar(fw, attributes, varauditmode, &global_guid, &data); + if (ret != FWTS_OK) + return ret; + + data = 1; + fwts_log_info(fw, "AuditMode variable read-only test, set to 1."); + ret = securebootcert_setvar(fw, attributes, varauditmode, &global_guid, &data); + if (ret != FWTS_OK) + return ret; + + if (!(var_found & VAR_AUDITMODE_FOUND)) { + fwts_skipped(fw, + "No DeployedMode variable found, skip the varaible test."); + return FWTS_SKIP; + } + + data = 0; + fwts_log_info(fw, "DeployedMode variable read-only test, set to 0."); + ret = securebootcert_setvar(fw, attributes, vardeploymode, &global_guid, &data); + if (ret != FWTS_OK) + return ret; + + data = 1; + fwts_log_info(fw, "DeployedMode variable read-only test, set to 1."); + ret = securebootcert_setvar(fw, attributes, vardeploymode, &global_guid, &data); + if (ret != FWTS_OK) + return ret; + + return FWTS_OK; +} + static fwts_framework_minor_test securebootcert_tests[] = { { securebootcert_test1, "UEFI secure boot test." }, + { securebootcert_test2, "UEFI secure boot variable test." }, { NULL, NULL } }; static fwts_framework_ops securebootcert_ops = { .description = "UEFI secure boot test.", .init = securebootcert_init, + .deinit = securebootcert_deinit, .minor_tests = securebootcert_tests };