diff options
| author | Peter Jones <pjones@redhat.com> | 2021-09-20 17:25:10 -0400 |
|---|---|---|
| committer | Peter Jones <pjones@redhat.com> | 2025-01-17 17:17:20 -0500 |
| commit | 67efdfc41a2d9212e4c641fa0722b61db2654982 (patch) | |
| tree | 75fe9d2dd06fde5d7090c581fca3fac803042706 /test-mok-mirror.c | |
| parent | f7e1d7226de8b9fc005257b8fede70093c547ad5 (diff) | |
| download | efi-boot-shim-67efdfc41a2d9212e4c641fa0722b61db2654982.tar.gz efi-boot-shim-67efdfc41a2d9212e4c641fa0722b61db2654982.zip | |
test-mok-mirror: refactor the validation of test_mok_mirror_0
This makes a generic test_mok_mirror() which can validate the result of
(hopefully) any run of any result of import_mok_state(), and changes
test_mok_mirror_0() to use it, and also documents what's being tested
and the results it expects to see.
Signed-off-by: Peter Jones <pjones@redhat.com>
Diffstat (limited to 'test-mok-mirror.c')
| -rw-r--r-- | test-mok-mirror.c | 357 |
1 files changed, 225 insertions, 132 deletions
diff --git a/test-mok-mirror.c b/test-mok-mirror.c index f34f62a9..d11e0f5e 100644 --- a/test-mok-mirror.c +++ b/test-mok-mirror.c @@ -21,21 +21,51 @@ start_image(EFI_HANDLE image_handle UNUSED, CHAR16 *mm) #define N_TEST_VAR_OPS 40 struct test_var { + /* + * The GUID, name, and attributes of the variables + */ EFI_GUID guid; CHAR16 *name; UINT32 attrs; - UINTN n_ops; + /* + * If the variable is required to be present, with the attributes + * specified above, for a test to pass + */ bool must_be_present; + /* + * If the variable is required to be absent, no matter what the + * attributes, for a test to pass + */ bool must_be_absent; + /* + * The number of operations on this variable that we've seen + */ + UINTN n_ops; + /* + * the operations that have occurred on this variable + */ mock_variable_op_t ops[N_TEST_VAR_OPS]; + /* + * the result codes of those operations + */ EFI_STATUS results[N_TEST_VAR_OPS]; }; static struct test_var *test_vars; struct mock_mok_variable_config_entry { + /* + * The name of an entry we expect to see in the MokVars + * configuration table + */ CHAR8 name[256]; + /* + * The size of its data + */ UINT64 data_size; + /* + * A pointer to what the data should be + */ const unsigned char *data; }; @@ -94,120 +124,11 @@ getvar_post(CHAR16 *name, EFI_GUID *guid, } } -static int -test_mok_mirror_0(void) +static EFI_STATUS +check_variables(struct test_var *vars) { - const char *mok_rt_vars[n_mok_state_variables]; - EFI_STATUS status; - EFI_GUID guid = SHIM_LOCK_GUID; - EFI_GUID mok_config_guid = MOK_VARIABLE_STORE; - int ret = -1; - - struct test_var test_mok_mirror_0_vars[] = { - {.guid = SHIM_LOCK_GUID, - .name = L"MokList", - .must_be_present = true, - .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_NON_VOLATILE, - .ops = { NONE, }, - }, - {.guid = SHIM_LOCK_GUID, - .name = L"MokListRT", - .must_be_present = true, - .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - .ops = { NONE, }, - }, - {.guid = SHIM_LOCK_GUID, - .name = L"MokListX", - .must_be_present = true, - .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_NON_VOLATILE, - .ops = { NONE, }, - }, - {.guid = SHIM_LOCK_GUID, - .name = L"MokListXRT", - .must_be_present = true, - .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - .ops = { NONE, }, - }, - {.guid = SHIM_LOCK_GUID, - .name = L"SbatLevel", - .must_be_present = true, - .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_NON_VOLATILE, - .ops = { NONE, }, - }, - {.guid = SHIM_LOCK_GUID, - .name = L"SbatLevelRT", - .must_be_present = true, - .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - .ops = { NONE, }, - }, - {.guid = SHIM_LOCK_GUID, - .name = L"MokIgnoreDB", - .must_be_absent = true, - .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - .ops = { NONE, }, - }, - {.guid = SHIM_LOCK_GUID, - .name = L"MokSBState", - .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_NON_VOLATILE, - .ops = { NONE, }, - }, - {.guid = SHIM_LOCK_GUID, - .name = L"MokSBStateRT", - .must_be_absent = true, - .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - .ops = { NONE, }, - }, - {.guid = { 0, }, - .name = NULL, - } - }; - - struct mock_mok_variable_config_entry test_mok_config_table[] = { - {.name = "MokListRT", - .data_size = sizeof(test_data_efivars_1_MokListRT), - .data = test_data_efivars_1_MokListRT - }, - {.name = "MokListXRT", - .data_size = sizeof(test_data_efivars_1_MokListXRT), - .data = test_data_efivars_1_MokListXRT - }, - {.name = "SbatLevelRT", - .data_size = sizeof(test_data_efivars_1_SbatLevelRT), - .data = test_data_efivars_1_SbatLevelRT - }, - {.name = "MokListTrustedRT", - .data_size = sizeof(test_data_efivars_1_MokListTrustedRT), - .data = test_data_efivars_1_MokListTrustedRT - }, - {.name = { 0, }, - .data_size = 0, - .data = NULL, - } - }; - - for (size_t i = 0; i < n_mok_state_variables; i++) { - mok_rt_vars[i] = mok_state_variables[i].rtname8; - } - - mock_load_variables("test-data/efivars-1", mok_rt_vars, true); - - mock_set_variable_post_hook = setvar_post; - mock_get_variable_post_hook = getvar_post; - test_vars = &test_mok_mirror_0_vars[0]; - - import_mok_state(NULL); - - for (size_t i = 0; test_mok_mirror_0_vars[i].name != NULL; i++) { - struct test_var *tv = &test_mok_mirror_0_vars[i]; + for (size_t i = 0; vars[i].name != NULL; i++) { + struct test_var *tv = &vars[i]; list_t *pos = NULL; bool found = false; char buf[1]; @@ -267,37 +188,42 @@ test_mok_mirror_0(void) "Variable should not be read %d times.\n", gets); } if (tv->must_be_present) { + /* + * This asserts if it isn't present, and if that's + * the case, then the attributes are already + * validated in the search loop + */ assert_goto(found == true, err, "variable \"%s\" was not found.\n", Str2str(tv->name)); } if (tv->must_be_absent) { + /* + * deliberately does not check the attributes at + * this time. + */ assert_goto(found == false, err, "variable \"%s\" was found.\n", Str2str(tv->name)); } } - uint8_t *pos = NULL; - for (size_t i = 0; i < ST->NumberOfTableEntries; i++) { - EFI_CONFIGURATION_TABLE *ct = &ST->ConfigurationTable[i]; - - if (CompareGuid(&ct->VendorGuid, &mok_config_guid) != 0) - continue; - - pos = (void *)ct->VendorTable; - break; - } - - assert_nonzero_goto(pos, err, "%p != 0\n"); + return EFI_SUCCESS; +err: + return EFI_INVALID_PARAMETER; +} +static EFI_STATUS +check_config_table(struct mock_mok_variable_config_entry *test_configs, + uint8_t *config_pos) +{ size_t i = 0; - while (pos) { + while (config_pos) { struct mock_mok_variable_config_entry *mock_entry = - &test_mok_config_table[i]; + &test_configs[i]; struct mok_variable_config_entry *mok_entry = - (struct mok_variable_config_entry *)pos; + (struct mok_variable_config_entry *)config_pos; /* * If the tables are different lengths, this will trigger. @@ -325,11 +251,53 @@ test_mok_mirror_0(void) assert_zero_goto(CompareMem(mok_entry->data, mock_entry->data, mok_entry->data_size), err, "%ld != %ld\n"); - pos += offsetof(struct mok_variable_config_entry, data) - + mok_entry->data_size; + config_pos += offsetof(struct mok_variable_config_entry, data) + + mok_entry->data_size; i += 1; } + return EFI_SUCCESS; +err: + return EFI_INVALID_PARAMETER; +} + +static int +test_mok_mirror(struct test_var *vars, + struct mock_mok_variable_config_entry *configs, + EFI_STATUS expected_status) +{ + EFI_STATUS status; + EFI_GUID mok_config_guid = MOK_VARIABLE_STORE; + int ret = -1; + + status = import_mok_state(NULL); + assert_equal_goto(status, expected_status, err, + "got 0x%016lx, expected 0x%016lx\n", + expected_status); + + test_vars = vars; + + status = check_variables(vars); + if (EFI_ERROR(status)) + goto err; + + uint8_t *pos = NULL; + for (size_t i = 0; i < ST->NumberOfTableEntries; i++) { + EFI_CONFIGURATION_TABLE *ct = &ST->ConfigurationTable[i]; + + if (CompareGuid(&ct->VendorGuid, &mok_config_guid) != 0) + continue; + + pos = (void *)ct->VendorTable; + break; + } + + assert_nonzero_goto(pos, err, "%p != 0\n"); + + status = check_config_table(configs, pos); + if (EFI_ERROR(status)) + goto err; + ret = 0; err: for (UINTN k = 0; k < n_mok_state_variables; k++) { @@ -343,6 +311,131 @@ err: } test_vars = NULL; + + return ret; +} + +/* + * This tests mirroring of mok variables on fairly optimistic conditions: + * there's enough space for everything, and so we expect to see all the + * RT variables for which we have data mirrored + */ +static int +test_mok_mirror_with_enough_space(void) +{ + const char *mok_rt_vars[n_mok_state_variables]; + EFI_STATUS status; + EFI_GUID guid = SHIM_LOCK_GUID; + int ret = -1; + + struct test_var test_mok_mirror_with_enough_space_vars[] = { + {.guid = SHIM_LOCK_GUID, + .name = L"MokList", + .must_be_present = true, + .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_NON_VOLATILE, + .ops = { NONE, }, + }, + {.guid = SHIM_LOCK_GUID, + .name = L"MokListRT", + .must_be_present = true, + .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + .ops = { NONE, }, + }, + {.guid = SHIM_LOCK_GUID, + .name = L"MokListX", + .must_be_present = true, + .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_NON_VOLATILE, + .ops = { NONE, }, + }, + {.guid = SHIM_LOCK_GUID, + .name = L"MokListXRT", + .must_be_present = true, + .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + .ops = { NONE, }, + }, + {.guid = SHIM_LOCK_GUID, + .name = L"SbatLevel", + .must_be_present = true, + .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_NON_VOLATILE, + .ops = { NONE, }, + }, + {.guid = SHIM_LOCK_GUID, + .name = L"SbatLevelRT", + .must_be_present = true, + .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + .ops = { NONE, }, + }, + {.guid = SHIM_LOCK_GUID, + .name = L"MokIgnoreDB", + .must_be_absent = true, + .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + .ops = { NONE, }, + }, + {.guid = SHIM_LOCK_GUID, + .name = L"MokSBState", + .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_NON_VOLATILE, + .ops = { NONE, }, + }, + {.guid = SHIM_LOCK_GUID, + .name = L"MokSBStateRT", + .must_be_absent = true, + .attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + .ops = { NONE, }, + }, + {.guid = { 0, }, + .name = NULL, + } + }; + + /* + * We must see the supplied values of MokListRT, MokListXRT, and + * SbatLevelRT in the config table + */ + struct mock_mok_variable_config_entry test_mok_config_table[] = { + {.name = "MokListRT", + .data_size = sizeof(test_data_efivars_1_MokListRT), + .data = test_data_efivars_1_MokListRT + }, + {.name = "MokListXRT", + .data_size = sizeof(test_data_efivars_1_MokListXRT), + .data = test_data_efivars_1_MokListXRT + }, + {.name = "SbatLevelRT", + .data_size = sizeof(test_data_efivars_1_SbatLevelRT), + .data = test_data_efivars_1_SbatLevelRT + }, + {.name = "MokListTrustedRT", + .data_size = sizeof(test_data_efivars_1_MokListTrustedRT), + .data = test_data_efivars_1_MokListTrustedRT + }, + {.name = { 0, }, + .data_size = 0, + .data = NULL, + } + }; + + for (size_t i = 0; i < n_mok_state_variables; i++) { + mok_rt_vars[i] = mok_state_variables[i].rtname8; + } + + mock_load_variables("test-data/efivars-1", mok_rt_vars, true); + + mock_set_variable_post_hook = setvar_post; + mock_get_variable_post_hook = getvar_post; + + ret = test_mok_mirror(&test_mok_mirror_with_enough_space_vars[0], + test_mok_config_table, + EFI_SUCCESS); + mock_set_variable_post_hook = NULL; mock_get_variable_post_hook = NULL; return ret; @@ -391,7 +484,7 @@ main(void) del_policy_names[j]); mock_variable_delete_attr_policy = delete_policies[j]; - test(test_mok_mirror_0); + test(test_mok_mirror_with_enough_space); mock_finalize_vars_and_configs(); if (delete_policies[j] == 0) |
