diff options
| author | Jan Setje-Eilers <jan.setjeeilers@oracle.com> | 2022-04-22 13:13:20 -0700 |
|---|---|---|
| committer | Peter Jones <pjones@redhat.com> | 2022-05-17 19:01:46 -0400 |
| commit | f81a7cc34e0b1a4f2d3104f44df80f93497eaa9e (patch) | |
| tree | 45dab9092c143ef6fd2fb63aa89137d0cbf884fe | |
| parent | b104fc480aae94eaa8d79717d0b7cf6dcc2253d3 (diff) | |
| download | efi-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.h | 33 | ||||
| -rw-r--r-- | sbat.c | 60 | ||||
| -rw-r--r-- | test-sbat.c | 52 | ||||
| -rw-r--r-- | test.c | 6 |
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; @@ -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); @@ -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) |
