diff options
| author | Jan Setje-Eilers <jan.setjeeilers@oracle.com> | 2022-05-18 16:32:05 -0700 |
|---|---|---|
| committer | Peter Jones <pjones@redhat.com> | 2022-05-23 15:54:58 -0400 |
| commit | 759f061e46b4b9b9b74626ad8bb566c49e12e5c1 (patch) | |
| tree | 53ebffe49b06a44c5f742a6ea4d08f00aa534b2b | |
| parent | a78673b19e98b4f000a2d8043e4bfdaab6d83a05 (diff) | |
| download | efi-boot-shim-759f061e46b4b9b9b74626ad8bb566c49e12e5c1.tar.gz efi-boot-shim-759f061e46b4b9b9b74626ad8bb566c49e12e5c1.zip | |
Fix preserve_sbat_uefi_variable() logic
preserve_sbat_uefi_variable() shoud really deal with the sbat
metadata version as a numerical value that could gain more digits.
It also needs to only compare the datestamp since the actual
metadata can grow and shrink
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
| -rw-r--r-- | sbat.c | 49 | ||||
| -rw-r--r-- | test-sbat.c | 71 |
2 files changed, 109 insertions, 11 deletions
@@ -319,16 +319,53 @@ check_sbat_var_attributes(UINT32 attributes) #endif } +static char * +nth_sbat_field(char *str, int n) +{ + char *ret = str; + while (n > 0 && ret != NULL) { + if (ret[0] == ',') + n--; + ret++; + } + return ret; +} + bool 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_ORIGINAL) && - !strcmp(sbatc, SBAT_VAR_SIG SBAT_VAR_VERSION) && - strcmp(sbatc, sbat_var) >= 0; + char *sbatc = (char *)sbat; + char *current_version, *new_version, + *current_datestamp, *new_datestamp; + int current_version_len, new_version_len; + + /* current metadata is not currupt somehow */ + if (!check_sbat_var_attributes(attributes) || + sbatsize < strlen(SBAT_VAR_ORIGINAL) || + strncmp(sbatc, SBAT_VAR_SIG, strlen(SBAT_VAR_SIG))) + return false; + + /* current metadata version not newer */ + current_version = nth_sbat_field(sbatc, 1); + new_version = nth_sbat_field(sbat_var, 1); + current_datestamp = nth_sbat_field(sbatc, 2); + new_datestamp = nth_sbat_field(sbat_var, 2); + + current_version_len = current_datestamp - current_version - 1; + new_version_len = new_datestamp - new_version - 1; + + if (current_version_len > new_version_len || + (current_version_len == new_version_len && + strncmp(current_version, new_version, new_version_len) > 0)) + return true; + + /* current datestamp is not newer or idential */ + if (strncmp(current_datestamp, new_datestamp, + strlen(SBAT_VAR_ORIGINAL_DATE)) >= 0) + return true; + + return false; } EFI_STATUS diff --git a/test-sbat.c b/test-sbat.c index d0ed713f..72bebe7a 100644 --- a/test-sbat.c +++ b/test-sbat.c @@ -970,8 +970,36 @@ err: int test_preserve_sbat_uefi_variable_good(void) { - char sbat[] = "sbat,1,2021030218\ncomponent,2,\n"; - char sbatvar[] = "sbat,1,2021030218\n"; + char sbat[] = "sbat,1,2021030218\ncomponent,2,\n"; + char sbatvar[] = "sbat,1,2021030218\ncomponent,2,\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_version_newer(void) +{ + char sbat[] = "sbat,2,2022030218\ncomponent,2,\n"; + char sbatvar[] = "sbat,1,2021030218\ncomponent,2,\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_version_newerlonger(void) +{ + char sbat[] = "sbat,10,2022030218\ncomponent,2,\n"; + char sbatvar[] = "sbat,2,2021030218\ncomponent,2,\n"; size_t sbat_size = sizeof(sbat); UINT32 attributes = SBAT_VAR_ATTRS; @@ -982,10 +1010,39 @@ test_preserve_sbat_uefi_variable_good(void) } int +test_preserve_sbat_uefi_variable_version_older(void) +{ + char sbat[] = "sbat,1,2021030218\ncomponent,2,\n"; + char sbatvar[] = "sbat,2,2022030218\ncomponent,2,\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_version_olderlonger(void) +{ + char sbat[] = "sbat,2,2021030218\ncomponent,2,\n"; + char sbatvar[] = "sbat,10,2022030218\ncomponent,2,\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_newer(void) { - char sbat[] = "sbat,1,2021030218\ncomponent,2,\n"; - char sbatvar[] = "sbat,1,2025030218\ncomponent,5,\n"; + char sbat[] = "sbat,1,2021030218\ncomponent,2,\n"; + char sbatvar[] = "sbat,1,2025030218\ncomponent,5,\ncomponent,3"; size_t sbat_size = sizeof(sbat); UINT32 attributes = SBAT_VAR_ATTRS; @@ -997,7 +1054,7 @@ test_preserve_sbat_uefi_variable_newer(void) int test_preserve_sbat_uefi_variable_older(void) { - char sbat[] = "sbat,1,2025030218\ncomponent,2,\n"; + char sbat[] = "sbat,1,2025030218\ncomponent,2,\ncomponent,3"; char sbatvar[] = "sbat,1,2020030218\ncomponent,1,\n"; size_t sbat_size = sizeof(sbat); UINT32 attributes = SBAT_VAR_ATTRS; @@ -1093,6 +1150,10 @@ main(void) test(test_preserve_sbat_uefi_variable_bad_sig); test(test_preserve_sbat_uefi_variable_bad_attr); test(test_preserve_sbat_uefi_variable_bad_short); + test(test_preserve_sbat_uefi_variable_version_newer); + test(test_preserve_sbat_uefi_variable_version_newerlonger); + test(test_preserve_sbat_uefi_variable_version_older); + test(test_preserve_sbat_uefi_variable_version_olderlonger); return 0; } |
