[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