[PATCH 1/2] securebootcert: add checking read-only for the AuditMode and DeployedMode
Ivan Hu
ivan.hu at canonical.com
Mon Jan 8 07:24:08 UTC 2018
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 <ivan.hu at canonical.com>
---
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 <stddef.h>
#include <inttypes.h>
+#include <sys/ioctl.h>
#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
};
--
2.7.4
More information about the fwts-devel
mailing list