summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sbat.h33
-rw-r--r--sbat.c60
-rw-r--r--test-sbat.c52
-rw-r--r--test.c6
4 files changed, 132 insertions, 19 deletions
diff --git a/include/sbat.h b/include/sbat.h
index 8551b74a..f2ae93a5 100644
--- a/include/sbat.h
+++ b/include/sbat.h
@@ -8,8 +8,31 @@
#define SBAT_VAR_SIG "sbat,"
#define SBAT_VAR_VERSION "1,"
-#define SBAT_VAR_DATE "2021030218"
-#define SBAT_VAR SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_DATE "\n"
+#define SBAT_VAR_ORIGINAL_DATE "2021030218"
+#define SBAT_VAR_ORIGINAL SBAT_VAR_SIG SBAT_VAR_VERSION \
+ SBAT_VAR_ORIGINAL_DATE "\n"
+
+#if defined(ENABLE_SHIM_DEVEL)
+#define SBAT_VAR_PREVIOUS_DATE "2022020101"
+#define SBAT_VAR_PREVIOUS_REVOCATIONS "component,2\n"
+#define SBAT_VAR_PREVIOUS SBAT_VAR_SIG SBAT_VAR_VERSION \
+ SBAT_VAR_PREVIOUS_DATE "\n" SBAT_VAR_PREVIOUS_REVOCATIONS
+
+#define SBAT_VAR_LATEST_DATE "2022050100"
+#define SBAT_VAR_LATEST_REVOCATIONS "component,2\nothercomponent,2\n"
+#define SBAT_VAR_LATEST SBAT_VAR_SIG SBAT_VAR_VERSION \
+ SBAT_VAR_LATEST_DATE "\n" SBAT_VAR_LATEST_REVOCATIONS
+#else /* !ENABLE_SHIM_DEVEL */
+#define SBAT_VAR_PREVIOUS_DATE SBAT_VAR_ORIGINAL_DATE
+#define SBAT_VAR_PREVIOUS_REVOCATIONS
+#define SBAT_VAR_PREVIOUS SBAT_VAR_SIG SBAT_VAR_VERSION \
+ SBAT_VAR_PREVIOUS_DATE "\n" SBAT_VAR_PREVIOUS_REVOCATIONS
+
+#define SBAT_VAR_LATEST_DATE SBAT_VAR_ORIGINAL_DATE
+#define SBAT_VAR_LATEST_REVOCATIONS
+#define SBAT_VAR_LATEST SBAT_VAR_SIG SBAT_VAR_VERSION \
+ SBAT_VAR_LATEST_DATE "\n" SBAT_VAR_LATEST_REVOCATIONS
+#endif /* ENABLE_SHIM_DEVEL */
#define UEFI_VAR_NV_BS \
(EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)
@@ -33,6 +56,9 @@
#define SBAT_VAR_ATTRS UEFI_VAR_NV_BS
#endif
+#define SBAT_POLICY L"SbatPolicy"
+#define SBAT_POLICY8 "SbatPolicy"
+
extern UINTN _sbat, _esbat;
struct sbat_var_entry {
@@ -51,7 +77,8 @@ extern list_t sbat_var;
EFI_STATUS parse_sbat_var(list_t *entries);
void cleanup_sbat_var(list_t *entries);
EFI_STATUS set_sbat_uefi_variable(void);
-bool preserve_sbat_uefi_variable(UINT8 *sbat, UINTN sbatsize, UINT32 attributes);
+bool preserve_sbat_uefi_variable(UINT8 *sbat, UINTN sbatsize,
+ UINT32 attributes, char *sbar_var);
struct sbat_section_entry {
const CHAR8 *component_name;
diff --git a/sbat.c b/sbat.c
index 76c9d2c0..461d4859 100644
--- a/sbat.c
+++ b/sbat.c
@@ -320,11 +320,15 @@ check_sbat_var_attributes(UINT32 attributes)
}
bool
-preserve_sbat_uefi_variable(UINT8 *sbat, UINTN sbatsize, UINT32 attributes)
+preserve_sbat_uefi_variable(UINT8 *sbat, UINTN sbatsize, UINT32 attributes,
+ char *sbat_var)
{
+ const char *sbatc = (const char *)sbat;
+
return check_sbat_var_attributes(attributes) &&
- sbatsize >= strlen(SBAT_VAR_SIG "1") &&
- !strncmp((const char *)sbat, SBAT_VAR_SIG, strlen(SBAT_VAR_SIG));
+ sbatsize >= strlen(SBAT_VAR_ORIGINAL) &&
+ !strcmp(sbatc, SBAT_VAR_SIG SBAT_VAR_VERSION) &&
+ strcmp(sbatc, sbat_var) >= 0;
}
EFI_STATUS
@@ -334,7 +338,44 @@ set_sbat_uefi_variable(void)
UINT32 attributes = 0;
UINT8 *sbat = NULL;
+ UINT8 *sbat_policy = NULL;
UINTN sbatsize = 0;
+ UINTN sbat_policysize = 0;
+
+ char *sbat_var = NULL;
+ bool reset_sbat = false;
+
+ efi_status = get_variable_attr(SBAT_POLICY, &sbat_policy,
+ &sbat_policysize, SHIM_LOCK_GUID,
+ &attributes);
+ if (EFI_ERROR(efi_status)) {
+ dprint("Default sbat policy: previous\n");
+ sbat_var = SBAT_VAR_PREVIOUS;
+ } else {
+ switch (*sbat_policy) {
+ case 1:
+ dprint("Custom sbat policy: latest\n");
+ sbat_var = SBAT_VAR_LATEST;
+ break;
+ case 2:
+ dprint("Custom sbat policy: previous\n");
+ sbat_var = SBAT_VAR_PREVIOUS;
+ break;
+ case 3:
+ if (secure_mode()) {
+ console_print(L"Cannot reset SBAT policy: Secure Boot is enabled.\n");
+ sbat_var = SBAT_VAR_PREVIOUS;
+ } else {
+ dprint(L"Custom SBAT policy: reset OK\n");
+ reset_sbat = true;
+ sbat_var = SBAT_VAR_ORIGINAL;
+ }
+ efi_status = del_variable(SBAT_POLICY, SHIM_LOCK_GUID);
+ if (EFI_ERROR(efi_status))
+ console_error(L"Could not reset SBAT Policy",
+ efi_status);
+ }
+ }
efi_status = get_variable_attr(SBAT_VAR_NAME, &sbat, &sbatsize,
SHIM_LOCK_GUID, &attributes);
@@ -346,8 +387,9 @@ set_sbat_uefi_variable(void)
*/
if (EFI_ERROR(efi_status)) {
dprint(L"SBAT read failed %r\n", efi_status);
- } else if (preserve_sbat_uefi_variable(sbat, sbatsize, attributes)) {
- dprint(L"%s variable is %d bytes, attributes are 0x%08x\n",
+ } else if (preserve_sbat_uefi_variable(sbat, sbatsize, attributes, sbat_var)
+ && !reset_sbat) {
+ dprint(L"preserving %s variable it is %d bytes, attributes are 0x%08x\n",
SBAT_VAR_NAME, sbatsize, attributes);
FreePool(sbat);
return EFI_SUCCESS;
@@ -369,7 +411,7 @@ set_sbat_uefi_variable(void)
/* set variable */
efi_status = set_variable(SBAT_VAR_NAME, SHIM_LOCK_GUID, SBAT_VAR_ATTRS,
- sizeof(SBAT_VAR)-1, SBAT_VAR);
+ strlen(sbat_var), sbat_var);
if (EFI_ERROR(efi_status)) {
dprint(L"%s variable writing failed %r\n", SBAT_VAR_NAME,
efi_status);
@@ -384,10 +426,10 @@ set_sbat_uefi_variable(void)
return efi_status;
}
- if (sbatsize != strlen(SBAT_VAR) ||
- strncmp((const char *)sbat, SBAT_VAR, strlen(SBAT_VAR)) != 0) {
+ if (sbatsize != strlen(sbat_var) ||
+ strncmp((const char *)sbat, sbat_var, strlen(sbat_var)) != 0) {
dprint("new sbatsize is %d, expected %d\n", sbatsize,
- strlen(SBAT_VAR));
+ strlen(sbat_var));
efi_status = EFI_INVALID_PARAMETER;
} else {
dprint(L"%s variable initialization succeeded\n", SBAT_VAR_NAME);
diff --git a/test-sbat.c b/test-sbat.c
index b64aa1e9..d0ed713f 100644
--- a/test-sbat.c
+++ b/test-sbat.c
@@ -14,6 +14,11 @@
list_t sbat_var;
+BOOLEAN
+secure_mode() {
+ return 1;
+}
+
#if 0
/*
* Mock test helpers
@@ -965,11 +970,39 @@ err:
int
test_preserve_sbat_uefi_variable_good(void)
{
- char sbat[] = "sbat,1,\ncomponent,2,\n";
+ char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
+ char sbatvar[] = "sbat,1,2021030218\n";
+ size_t sbat_size = sizeof(sbat);
+ UINT32 attributes = SBAT_VAR_ATTRS;
+
+ if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
+ return 0;
+ else
+ return -1;
+}
+
+int
+test_preserve_sbat_uefi_variable_newer(void)
+{
+ char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
+ char sbatvar[] = "sbat,1,2025030218\ncomponent,5,\n";
+ size_t sbat_size = sizeof(sbat);
+ UINT32 attributes = SBAT_VAR_ATTRS;
+
+ if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
+ return -1;
+ else
+ return 0;
+}
+int
+test_preserve_sbat_uefi_variable_older(void)
+{
+ char sbat[] = "sbat,1,2025030218\ncomponent,2,\n";
+ char sbatvar[] = "sbat,1,2020030218\ncomponent,1,\n";
size_t sbat_size = sizeof(sbat);
UINT32 attributes = SBAT_VAR_ATTRS;
- if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes))
+ if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
return 0;
else
return -1;
@@ -978,11 +1011,12 @@ test_preserve_sbat_uefi_variable_good(void)
int
test_preserve_sbat_uefi_variable_bad_sig(void)
{
- char sbat[] = "bad_sig,1,\ncomponent,2,\n";
+ char sbat[] = "bad_sig,1,2021030218\ncomponent,2,\n";
+ char sbatvar[] = "sbat,1,2021030218\n";
size_t sbat_size = sizeof(sbat);
UINT32 attributes = SBAT_VAR_ATTRS;
- if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes))
+ if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
return -1;
else
return 0;
@@ -991,11 +1025,12 @@ test_preserve_sbat_uefi_variable_bad_sig(void)
int
test_preserve_sbat_uefi_variable_bad_attr(void)
{
- char sbat[] = "sbat,1,\ncomponent,2,\n";
+ char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
+ char sbatvar[] = "sbat,1,2021030218\n";
size_t sbat_size = sizeof(sbat);
UINT32 attributes = 0;
- if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes))
+ if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
return -1;
else
return 0;
@@ -1005,10 +1040,11 @@ int
test_preserve_sbat_uefi_variable_bad_short(void)
{
char sbat[] = "sba";
+ char sbatvar[] = "sbat,1,2021030218\n";
size_t sbat_size = sizeof(sbat);
UINT32 attributes = SBAT_VAR_ATTRS;
- if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes))
+ if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
return -1;
else
return 0;
@@ -1052,6 +1088,8 @@ main(void)
test(test_parse_and_verify);
test(test_preserve_sbat_uefi_variable_good);
+ test(test_preserve_sbat_uefi_variable_newer);
+ test(test_preserve_sbat_uefi_variable_older);
test(test_preserve_sbat_uefi_variable_bad_sig);
test(test_preserve_sbat_uefi_variable_bad_attr);
test(test_preserve_sbat_uefi_variable_bad_short);
diff --git a/test.c b/test.c
index 46cab533..c7978fa2 100644
--- a/test.c
+++ b/test.c
@@ -259,6 +259,12 @@ console_print(const CHAR16 *fmt, ...)
return 0;
}
+void
+console_error(CHAR16 *err, EFI_STATUS efi_status)
+{
+ return;
+}
+
#ifndef HAVE_START_IMAGE
EFI_STATUS
start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)