summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Setje-Eilers <jan.setjeeilers@oracle.com>2022-04-22 13:13:20 -0700
committerPeter Jones <pjones@redhat.com>2022-05-17 19:01:46 -0400
commitf81a7cc34e0b1a4f2d3104f44df80f93497eaa9e (patch)
tree45dab9092c143ef6fd2fb63aa89137d0cbf884fe
parentb104fc480aae94eaa8d79717d0b7cf6dcc2253d3 (diff)
downloadefi-boot-shim-f81a7cc34e0b1a4f2d3104f44df80f93497eaa9e.tar.gz
efi-boot-shim-f81a7cc34e0b1a4f2d3104f44df80f93497eaa9e.zip
SBAT revocation management
Support for updating SBAT revocations to latest or previous revocations. Allow SBAT revocations to be reset to empty metadata only when UEFI Secure Boot is disabled. Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
-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)