1 // SPDX-License-Identifier: BSD-2-Clause-Patent
3 * test-mok-mirror.c - try to test our mok mirroring code
4 * Copyright Peter Jones <pjones@redhat.com>
8 #include "mock-variables.h"
9 #include "test-data-efivars-1.h"
13 #pragma GCC diagnostic ignored "-Wunused-parameter"
16 start_image(EFI_HANDLE image_handle UNUSED
, CHAR16
*mm
)
18 printf("Attempted to launch %s\n", Str2str(mm
));
22 #define N_TEST_VAR_OPS 40
30 mock_variable_op_t ops
[N_TEST_VAR_OPS
];
31 EFI_STATUS results
[N_TEST_VAR_OPS
];
34 static struct test_var
*test_vars
;
36 struct mock_mok_variable_config_entry
{
39 const unsigned char *data
;
43 setvar_post(CHAR16
*name
, EFI_GUID
*guid
, UINT32 attrs
,
44 UINTN size
, VOID
*data
, EFI_STATUS
*status
,
45 mock_variable_op_t op
, const char * const file
,
46 const int line
, const char * const func
)
51 for (UINTN i
= 0; test_vars
[i
].name
!= NULL
; i
++) {
52 struct test_var
*tv
= &test_vars
[i
];
54 if (CompareGuid(&tv
->guid
, guid
) != 0 ||
55 StrCmp(tv
->name
, name
) != 0)
57 tv
->ops
[tv
->n_ops
] = op
;
58 tv
->results
[tv
->n_ops
] = *status
;
64 getvar_post(CHAR16
*name
, EFI_GUID
*guid
,
65 UINT32
*attrs
, UINTN
*size
,
66 VOID
*data
, EFI_STATUS
*status
,
67 const char * const file
, const int line
, const char * func
)
69 if (EFI_ERROR(*status
) &&
70 (*status
!= EFI_NOT_FOUND
&&
71 *status
!= EFI_BUFFER_TOO_SMALL
)) {
72 printf("%s:%d:%s():Getting "GUID_FMT
"-%s ",
74 GUID_ARGS(*guid
), Str2str(name
));
76 printf("attrs:%s\n", format_var_attrs(*attrs
));
78 printf("attrs:NULL\n");
79 printf("failed:%s\n", efi_strerror(*status
));
85 for (UINTN i
= 0; test_vars
[i
].name
!= NULL
; i
++) {
86 struct test_var
*tv
= &test_vars
[i
];
88 if (CompareGuid(&tv
->guid
, guid
) != 0 ||
89 StrCmp(tv
->name
, name
) != 0)
91 tv
->ops
[tv
->n_ops
] = GET
;
92 tv
->results
[tv
->n_ops
] = *status
;
98 test_mok_mirror_0(void)
100 const char *mok_rt_vars
[n_mok_state_variables
];
102 EFI_GUID guid
= SHIM_LOCK_GUID
;
103 EFI_GUID mok_config_guid
= MOK_VARIABLE_STORE
;
106 struct test_var test_mok_mirror_0_vars
[] = {
107 {.guid
= SHIM_LOCK_GUID
,
109 .must_be_present
= true,
110 .attrs
= EFI_VARIABLE_BOOTSERVICE_ACCESS
|
111 EFI_VARIABLE_NON_VOLATILE
,
114 {.guid
= SHIM_LOCK_GUID
,
115 .name
= L
"MokListRT",
116 .must_be_present
= true,
117 .attrs
= EFI_VARIABLE_BOOTSERVICE_ACCESS
|
118 EFI_VARIABLE_RUNTIME_ACCESS
,
121 {.guid
= SHIM_LOCK_GUID
,
123 .must_be_present
= true,
124 .attrs
= EFI_VARIABLE_BOOTSERVICE_ACCESS
|
125 EFI_VARIABLE_NON_VOLATILE
,
128 {.guid
= SHIM_LOCK_GUID
,
129 .name
= L
"MokListXRT",
130 .must_be_present
= true,
131 .attrs
= EFI_VARIABLE_BOOTSERVICE_ACCESS
|
132 EFI_VARIABLE_RUNTIME_ACCESS
,
135 {.guid
= SHIM_LOCK_GUID
,
136 .name
= L
"SbatLevel",
137 .must_be_present
= true,
138 .attrs
= EFI_VARIABLE_BOOTSERVICE_ACCESS
|
139 EFI_VARIABLE_NON_VOLATILE
,
142 {.guid
= SHIM_LOCK_GUID
,
143 .name
= L
"SbatLevelRT",
144 .must_be_present
= true,
145 .attrs
= EFI_VARIABLE_BOOTSERVICE_ACCESS
|
146 EFI_VARIABLE_RUNTIME_ACCESS
,
149 {.guid
= SHIM_LOCK_GUID
,
150 .name
= L
"MokIgnoreDB",
151 .must_be_absent
= true,
152 .attrs
= EFI_VARIABLE_BOOTSERVICE_ACCESS
|
153 EFI_VARIABLE_RUNTIME_ACCESS
,
156 {.guid
= SHIM_LOCK_GUID
,
157 .name
= L
"MokSBState",
158 .attrs
= EFI_VARIABLE_BOOTSERVICE_ACCESS
|
159 EFI_VARIABLE_NON_VOLATILE
,
162 {.guid
= SHIM_LOCK_GUID
,
163 .name
= L
"MokSBStateRT",
164 .must_be_absent
= true,
165 .attrs
= EFI_VARIABLE_BOOTSERVICE_ACCESS
|
166 EFI_VARIABLE_RUNTIME_ACCESS
,
174 struct mock_mok_variable_config_entry test_mok_config_table
[] = {
175 {.name
= "MokListRT",
176 .data_size
= sizeof(test_data_efivars_1_MokListRT
),
177 .data
= test_data_efivars_1_MokListRT
179 {.name
= "MokListXRT",
180 .data_size
= sizeof(test_data_efivars_1_MokListXRT
),
181 .data
= test_data_efivars_1_MokListXRT
183 {.name
= "SbatLevelRT",
184 .data_size
= sizeof(test_data_efivars_1_SbatLevelRT
),
185 .data
= test_data_efivars_1_SbatLevelRT
187 {.name
= "MokListTrustedRT",
188 .data_size
= sizeof(test_data_efivars_1_MokListTrustedRT
),
189 .data
= test_data_efivars_1_MokListTrustedRT
197 for (size_t i
= 0; i
< n_mok_state_variables
; i
++) {
198 mok_rt_vars
[i
] = mok_state_variables
[i
].rtname8
;
201 mock_load_variables("test-data/efivars-1", mok_rt_vars
, true);
203 mock_set_variable_post_hook
= setvar_post
;
204 mock_get_variable_post_hook
= getvar_post
;
205 test_vars
= &test_mok_mirror_0_vars
[0];
207 import_mok_state(NULL
);
209 for (size_t i
= 0; test_mok_mirror_0_vars
[i
].name
!= NULL
; i
++) {
210 struct test_var
*tv
= &test_mok_mirror_0_vars
[i
];
216 bool present
= false;
218 list_for_each(pos
, &mock_variables
) {
219 struct mock_variable
*var
;
224 var
= list_entry(pos
, struct mock_variable
, list
);
225 if (CompareGuid(&tv
->guid
, &var
->guid
) != 0 ||
226 StrCmp(var
->name
, tv
->name
) != 0)
229 assert_equal_goto(var
->attrs
, tv
->attrs
, err
,
230 "\"%s\": wrong attrs; got %s expected %s\n",
232 format_var_attrs(var
->attrs
),
233 format_var_attrs(tv
->attrs
));
234 for (UINTN j
= 0; j
< N_TEST_VAR_OPS
235 && tv
->ops
[j
] != NONE
; j
++) {
236 switch (tv
->ops
[j
]) {
241 if (tv
->results
[j
] == EFI_SUCCESS
)
245 assert_goto(tv
->results
[j
] != EFI_SUCCESS
, err
,
246 "Tried to delete absent variable \"%s\"\n",
248 assert_goto(created
== false, err
,
249 "Deleted variable \"%s\" was previously created.\n",
253 assert_goto(false, err
,
254 "No append action should have been tested\n");
257 assert_goto(false, err
,
258 "No replace action should have been tested\n");
261 if (tv
->results
[j
] == EFI_SUCCESS
)
266 assert_goto(gets
== 0 || gets
== 1, err
,
267 "Variable should not be read %d times.\n", gets
);
269 if (tv
->must_be_present
) {
270 assert_goto(found
== true, err
,
271 "variable \"%s\" was not found.\n",
275 if (tv
->must_be_absent
) {
276 assert_goto(found
== false, err
,
277 "variable \"%s\" was found.\n",
283 for (size_t i
= 0; i
< ST
->NumberOfTableEntries
; i
++) {
284 EFI_CONFIGURATION_TABLE
*ct
= &ST
->ConfigurationTable
[i
];
286 if (CompareGuid(&ct
->VendorGuid
, &mok_config_guid
) != 0)
289 pos
= (void *)ct
->VendorTable
;
293 assert_nonzero_goto(pos
, err
, "%p != 0\n");
297 struct mock_mok_variable_config_entry
*mock_entry
=
298 &test_mok_config_table
[i
];
299 struct mok_variable_config_entry
*mok_entry
=
300 (struct mok_variable_config_entry
*)pos
;
303 * If the tables are different lengths, this will trigger.
305 assert_equal_goto(mok_entry
->name
[0], mock_entry
->name
[0], err
,
306 "mok.name[0] %ld != test.name[0] %ld\n");
307 if (mock_entry
->name
[0] == 0)
310 assert_nonzero_goto(mok_entry
->name
[0], err
, "%ld != %ld\n");
311 assert_zero_goto(strncmp(mok_entry
->name
, mock_entry
->name
,
312 sizeof(mock_entry
->name
)),
313 err
, "%ld != %ld: strcmp(\"%s\",\"%s\")\n",
314 mok_entry
->name
, mock_entry
->name
);
317 * As of 7501b6bb449f ("mok: fix potential buffer overrun in
318 * import_mok_state"), we should not see any mok config
319 * variables with data_size == 0.
321 assert_nonzero_goto(mok_entry
->data_size
, err
, "%ld != 0\n");
323 assert_equal_goto(mok_entry
->data_size
, mock_entry
->data_size
,
324 err
, "%ld != %ld\n");
325 assert_zero_goto(CompareMem(mok_entry
->data
, mock_entry
->data
,
326 mok_entry
->data_size
),
327 err
, "%ld != %ld\n");
328 pos
+= offsetof(struct mok_variable_config_entry
, data
)
329 + mok_entry
->data_size
;
335 for (UINTN k
= 0; k
< n_mok_state_variables
; k
++) {
336 struct mok_state_variable
*v
=
337 &mok_state_variables
[k
];
338 if (v
->data_size
&& v
->data
) {
346 mock_set_variable_post_hook
= NULL
;
347 mock_get_variable_post_hook
= NULL
;
355 setbuf(stdout
, NULL
);
357 const char *sort_policy_names
[] = {
358 "MOCK_SORT_DESCENDING",
361 "MOCK_SORT_ASCENDING",
362 "MOCK_SORT_MAX_SENTINEL"
365 const char *del_policy_names
[] = {
366 "MOCK_VAR_DELETE_ATTR_ALLOW_ZERO",
367 "MOCK_VAR_DELETE_ATTR_ALOW_MISMATCH",
368 "MOCK_VAR_DELETE_ATTR_ALLOW_ZERO|MOCK_VAR_DELETE_ATTR_ALOW_MISMATCH",
369 "MOCK_VAR_DELETE_ATTR_ALLOW_NONE",
373 int delete_policies
[] = {
374 MOCK_VAR_DELETE_ATTR_ALLOW_ZERO
,
375 MOCK_VAR_DELETE_ATTR_ALOW_MISMATCH
,
376 MOCK_VAR_DELETE_ATTR_ALLOW_ZERO
377 | MOCK_VAR_DELETE_ATTR_ALOW_MISMATCH
,
381 for (int i
= 0; i
< MOCK_SORT_MAX_SENTINEL
; i
++) {
382 mock_variable_sort_policy
= i
;
383 mock_config_table_sort_policy
= i
;
386 printf("%s: setting variable sort policy to %s\n",
387 program_invocation_short_name
, sort_policy_names
[i
]);
389 printf("%s: setting delete policy to %s\n",
390 program_invocation_short_name
,
391 del_policy_names
[j
]);
393 mock_variable_delete_attr_policy
= delete_policies
[j
];
394 test(test_mok_mirror_0
);
395 mock_finalize_vars_and_configs();
397 if (delete_policies
[j
] == 0)
405 // vim:fenc=utf-8:tw=75:noet