]> git.proxmox.com Git - efi-boot-shim.git/blob - test-sbat.c
bump version to 15.8-1+pmx1
[efi-boot-shim.git] / test-sbat.c
1 // SPDX-License-Identifier: BSD-2-Clause-Patent
2 /*
3 * test-sbat.c - test our sbat functions.
4 */
5
6 #ifndef SHIM_UNIT_TEST
7 #define SHIM_UNIT_TEST
8 #include "sbat_var_defs.h"
9 #endif
10 #include "shim.h"
11
12 #include <stdio.h>
13
14 #define MAX_SIZE 512
15
16 list_t sbat_var;
17
18 BOOLEAN
19 secure_mode() {
20 return 1;
21 }
22
23 #if 0
24 /*
25 * Mock test helpers
26 */
27 static struct sbat_entry *
28 create_mock_sbat_entry(const char* comp_name, const char* comp_gen,
29 const char* vend_name, const char* vend_pkg_name,
30 const char* vend_ver, const char* vend_url)
31 {
32 struct sbat_entry *new_entry = AllocatePool(sizeof(*new_entry));
33 if (!new_entry)
34 return NULL;
35 new_entry->component_name = comp_name;
36 new_entry->component_generation = comp_gen;
37 new_entry->vendor_name = vend_name;
38 new_entry->vendor_package_name = vend_pkg_name;
39 new_entry->vendor_version = vend_ver;
40 new_entry->vendor_url = vend_url;
41 return new_entry;
42 }
43
44 void
45 free_mock_sbat_entry(struct sbat_entry *entry)
46 {
47 if (entry)
48 FreePool(entry);
49 }
50
51 static struct sbat *
52 create_mock_sbat_one_entry(char* comp_name, char* comp_gen, char* vend_name,
53 char* vend_pkg_name, char* vend_ver, char* vend_url)
54 {
55 struct sbat *new_entry = AllocatePool(sizeof(*new_entry));
56 if (!new_entry)
57 return NULL;
58 struct sbat_entry *test_entry;
59 struct sbat_entry **entries = AllocatePool(sizeof(*entries));
60 if (!entries)
61 return NULL;
62 test_entry = create_mock_sbat_entry(comp_name, comp_gen, vend_name,
63 vend_pkg_name, vend_ver, vend_url);
64 if (!test_entry)
65 return NULL;
66 entries[0] = test_entry;
67 new_entry->size = 1;
68 new_entry->entries = entries;
69 return new_entry;
70 }
71
72 static struct sbat *
73 create_mock_sbat_multiple_entries(struct sbat_entry *entry_array,
74 size_t num_elem)
75 {
76 unsigned int i;
77 struct sbat *new_entry = AllocatePool(sizeof(*new_entry));
78 if (!new_entry)
79 return NULL;
80 struct sbat_entry *test_entry;
81 struct sbat_entry **entries = AllocatePool(num_elem * sizeof(*entries));
82 if (!entries)
83 return NULL;
84 for (i = 0; i < num_elem; i++) {
85 test_entry = create_mock_sbat_entry(entry_array[i].component_name,
86 entry_array[i].component_generation,
87 entry_array[i].vendor_name,
88 entry_array[i].vendor_package_name,
89 entry_array[i].vendor_version,
90 entry_array[i].vendor_url);
91 if (!test_entry)
92 return NULL;
93 entries[i] = test_entry;
94 }
95 new_entry->size = num_elem;
96 new_entry->entries = entries;
97
98 return new_entry;
99 }
100
101 void
102 free_mock_sbat(struct sbat *sbat)
103 {
104 unsigned int i;
105 if (sbat) {
106 for (i = 0; i < sbat->size; i++) {
107 if (sbat->entries[i]) {
108 FreePool(sbat->entries[i]);
109 }
110 }
111 FreePool(sbat);
112 }
113 }
114
115 static struct sbat_var *
116 create_mock_sbat_var_entry(const char* comp_name, const char* comp_gen)
117 {
118 struct sbat_var *new_entry = AllocatePool(sizeof(*new_entry));
119 if (!new_entry)
120 return NULL;
121 INIT_LIST_HEAD(&new_entry->list);
122 int comp_name_size = strlen(comp_name) + 1;
123 CHAR8 *alloc_comp_name = AllocatePool(comp_name_size * sizeof(*alloc_comp_name));
124 if (!alloc_comp_name)
125 return NULL;
126 int comp_gen_size = strlen(comp_gen) + 1;
127 CHAR8 *alloc_comp_gen = AllocatePool(comp_gen_size * sizeof(*alloc_comp_gen));
128 if (!alloc_comp_gen)
129 return NULL;
130 CopyMem(alloc_comp_name, comp_name, comp_name_size);
131 CopyMem(alloc_comp_gen, comp_gen, comp_gen_size);
132 new_entry->component_name = alloc_comp_name;
133 new_entry->component_generation = alloc_comp_gen;
134 return new_entry;
135 }
136
137 static list_t *
138 create_mock_sbat_entries_one_entry(char* name, char* gen)
139 {
140 list_t *test_sbat_entries = AllocatePool(sizeof(*test_sbat_entries));
141 if (!test_sbat_entries)
142 return NULL;
143 INIT_LIST_HEAD(test_sbat_entries);
144 struct sbat_var *test_entry;
145 test_entry = create_mock_sbat_var_entry(name, gen);
146 if (!test_entry)
147 return NULL;
148 list_add(&test_entry->list, test_sbat_entries);
149 return test_sbat_entries;
150 }
151
152 static list_t *
153 create_mock_sbat_entries_multiple_entries(struct sbat_var *var_array,
154 size_t num_elem)
155 {
156 unsigned int i;
157 list_t *test_sbat_entries = AllocatePool(sizeof(*test_sbat_entries));
158 if (!test_sbat_entries)
159 return NULL;
160 INIT_LIST_HEAD(test_sbat_entries);
161 struct sbat_var *test_entry;
162 for (i = 0; i < num_elem; i++) {
163 test_entry = create_mock_sbat_var_entry(var_array[i].component_name,
164 var_array[i].component_generation);
165 if (!test_entry)
166 return NULL;
167 list_add(&test_entry->list, test_sbat_entries);
168 }
169 return test_sbat_entries;
170 }
171
172 void
173 free_mock_sbat_entries(list_t *entries)
174 {
175 list_t *pos = NULL;
176 list_t *n = NULL;
177 struct sbat_var *entry;
178
179 if (entries)
180 {
181 list_for_each_safe(pos, n, entries)
182 {
183 entry = list_entry(pos, struct sbat_var, list);
184 list_del(&entry->list);
185 if (entry->component_name)
186 FreePool((CHAR8 *)entry->component_name);
187 if (entry->component_generation)
188 FreePool((CHAR8 *)entry->component_generation);
189 FreePool(entry);
190 }
191 FreePool(entries);
192 }
193 }
194 #endif
195
196 /*
197 * parse_sbat_section() tests
198 */
199 int
200 test_parse_sbat_tiny(void)
201 {
202 char section_base[] = "\0a\00";
203 size_t section_size = 2;
204 struct sbat_section_entry **entries;
205 size_t n = 0;
206 EFI_STATUS status;
207
208 status = parse_sbat_section(section_base, section_size, &n, &entries);
209 assert_equal_return(status, EFI_SUCCESS, -1, "got %#hhx expected %#hhx\n");
210 assert_equal_return(n, 0, -1, "got %#hhx expected %#hhx\n");
211
212 return 0;
213 }
214
215 int
216 test_parse_sbat_section_null_sbat_base(void)
217 {
218 char *section_base = NULL;
219 size_t section_size = 20;
220 struct sbat_section_entry **entries;
221 size_t n = 0;
222 EFI_STATUS status;
223
224 status = parse_sbat_section(section_base, section_size, &n, &entries);
225 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
226
227 return 0;
228 }
229
230 int
231 test_parse_sbat_section_zero_sbat_size(void)
232 {
233 char section_base[] = "test1,1,SBAT test1,acme,1,testURL\n";
234 size_t section_size = 0;
235 struct sbat_section_entry **entries;
236 size_t n = 0;
237 EFI_STATUS status;
238
239 status = parse_sbat_section(section_base, section_size, &n, &entries);
240 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
241
242 return 0;
243 }
244
245 int
246 test_parse_sbat_section_null_entries(void)
247 {
248 char section_base[] = "test1,1,SBAT test1,acme,1,testURL\n";
249 /* intentionally not NUL terminated */
250 size_t section_size = sizeof(section_base) - 1;
251 size_t n = 0;
252 EFI_STATUS status;
253
254 status = parse_sbat_section(section_base, section_size, &n, NULL);
255 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
256
257 return 0;
258 }
259
260 int
261 test_parse_sbat_section_null_count(void)
262 {
263 char section_base[] = "test1,1,SBAT test1,acme,1,testURL\n";
264 /* intentionally not NUL terminated */
265 size_t section_size = sizeof(section_base) - 1;
266 struct sbat_section_entry **entries;
267 EFI_STATUS status;
268
269 status = parse_sbat_section(section_base, section_size, NULL, &entries);
270 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
271
272 return 0;
273 }
274
275 int
276 test_parse_sbat_section_no_newline(void)
277 {
278 char section_base[] = "test1,1,SBAT test1,acme,1,testURL";
279 /* intentionally not NUL terminated */
280 size_t section_size = sizeof(section_base) - 1;
281 struct sbat_section_entry **entries;
282 size_t n = 0;
283 EFI_STATUS status;
284
285 status = parse_sbat_section(section_base, section_size, &n, &entries);
286 cleanup_sbat_section_entries(n, entries);
287 assert_equal_return(status, EFI_SUCCESS, -1, "got %#hhx expected %#hhx\n");
288
289 return 0;
290 }
291
292 int
293 test_parse_sbat_section_no_commas(void)
294 {
295 char section_base[] = "test1";
296 /* intentionally not NUL terminated */
297 size_t section_size = sizeof(section_base) - 1;
298 struct sbat_section_entry **entries;
299 size_t n = 0;
300 EFI_STATUS status;
301
302 status = parse_sbat_section(section_base, section_size, &n, &entries);
303 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
304
305 return 0;
306 }
307
308 int
309 test_parse_sbat_section_too_few_elem(void)
310 {
311 char section_base[] = "test1,1,acme";
312 /* intentionally not NUL terminated */
313 size_t section_size = sizeof(section_base) - 1;
314 struct sbat_section_entry **entries;
315 size_t n = 0;
316 EFI_STATUS status;
317
318 status = parse_sbat_section(section_base, section_size, &n, &entries);
319 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
320
321 return 0;
322 }
323
324 int
325 test_parse_sbat_section_too_many_elem(void)
326 {
327 char section_base[] = "test1,1,SBAT test1,acme1,1,testURL1,other1,stuff,is,here\n"
328 "test2,2,SBAT test2,acme2,2,testURL2,other2";
329 /* intentionally not NUL terminated */
330 size_t section_size = sizeof(section_base) - 1;
331 struct sbat_section_entry **entries;
332 size_t n = 0, i;
333 list_t *pos = NULL;
334 EFI_STATUS status;
335 struct sbat_section_entry test_section_entry1 = {
336 "test1", "1", "SBAT test1", "acme1", "1", "testURL1"
337 };
338 struct sbat_section_entry test_section_entry2 = {
339 "test2", "2", "SBAT test2", "acme2", "2", "testURL2"
340 };
341 struct sbat_section_entry *test_entries[] = {
342 &test_section_entry1, &test_section_entry2,
343 };
344 int rc = -1;
345
346 status = parse_sbat_section(section_base, section_size, &n, &entries);
347 assert_equal_return(status, EFI_SUCCESS, -1, "got %#hhx expected %#hhx\n");
348
349 for (i = 0; i < n; i++) {
350 struct sbat_section_entry *entry = entries[i];
351 struct sbat_section_entry *test_entry = test_entries[i];
352
353 #define mkassert(a) \
354 assert_equal_goto(strcmp(entry-> a, test_entry-> a), 0, fail, \
355 "got %zu expected %d\n")
356
357 mkassert(component_name);
358 mkassert(component_generation);
359 mkassert(vendor_name);
360 mkassert(vendor_package_name);
361 mkassert(vendor_version);
362 mkassert(vendor_url);
363
364 #undef mkassert
365 }
366 assert_equal_goto(n, 2, fail, "got %zu expected %d\n");
367 rc = 0;
368 fail:
369 cleanup_sbat_section_entries(n, entries);
370 return rc;
371 }
372
373 /*
374 * parse_sbat_var() tests
375 */
376 int
377 test_parse_sbat_var_null_list(void)
378 {
379 EFI_STATUS status;
380
381 INIT_LIST_HEAD(&sbat_var);
382 status = parse_sbat_var(NULL, NULL);
383 cleanup_sbat_var(&sbat_var);
384 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
385
386 return 0;
387 }
388
389 int
390 test_parse_sbat_var_data_null_list(void)
391 {
392 char sbat_var_data[] = "test1,1,2021022400";
393 /*
394 * intentionally including the NUL termination, because
395 * get_variable() will always include it.
396 */
397 size_t sbat_var_data_size = sizeof(sbat_var_data);
398 EFI_STATUS status;
399
400 INIT_LIST_HEAD(&sbat_var);
401 status = parse_sbat_var_data(NULL, sbat_var_data, sbat_var_data_size);
402 cleanup_sbat_var(&sbat_var);
403
404 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
405
406 return 0;
407 }
408
409 int
410 test_parse_sbat_var_data_null_data(void)
411 {
412 size_t sbat_var_data_size = 4;
413 EFI_STATUS status;
414
415 INIT_LIST_HEAD(&sbat_var);
416 status = parse_sbat_var_data(&sbat_var, NULL, sbat_var_data_size);
417 cleanup_sbat_var(&sbat_var);
418
419 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
420
421 return 0;
422 }
423
424 int
425 test_parse_sbat_var_data_zero_size(void)
426 {
427 char sbat_var_data[] = "test1,1,2021022400";
428 EFI_STATUS status;
429
430 INIT_LIST_HEAD(&sbat_var);
431 status = parse_sbat_var_data(&sbat_var, sbat_var_data, 0);
432 cleanup_sbat_var(&sbat_var);
433
434 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
435
436 return 0;
437 }
438
439 int
440 test_parse_sbat_var_data(void)
441 {
442 char sbat_var_data[] = "test1,1,2021022400";
443 EFI_STATUS status;
444
445 INIT_LIST_HEAD(&sbat_var);
446 status = parse_sbat_var_data(&sbat_var, sbat_var_data, 0);
447
448 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
449
450 return 0;
451 }
452
453 /*
454 * verify_sbat() tests
455 * Note: verify_sbat also frees the underlying "sbat_entries" memory.
456 */
457 int
458 test_verify_sbat_null_sbat_section(void)
459 {
460 char sbat_var_data[] = "test1,1";
461 EFI_STATUS status;
462 list_t test_sbat_var;
463 size_t n = 0;
464 struct sbat_section_entry **entries = NULL;
465 int rc = -1;
466
467 INIT_LIST_HEAD(&test_sbat_var);
468 status = parse_sbat_var_data(&test_sbat_var, sbat_var_data, sizeof(sbat_var_data));
469 assert_equal_goto(status, EFI_SUCCESS, err, "got %#x expected %#x\n");
470
471 status = verify_sbat_helper(&test_sbat_var, n, entries);
472 assert_equal_goto(status, EFI_SUCCESS, err, "got %#x expected %#x\n");
473 rc = 0;
474 err:
475 cleanup_sbat_var(&test_sbat_var);
476
477 return rc;
478 }
479
480 #if 0
481 int
482 test_verify_sbat_null_sbat_entries(void)
483 {
484 struct sbat *test_sbat;
485 test_sbat = create_mock_sbat_one_entry("test1","1","SBAT test1",
486 "acme","1","testURL");
487 if (!test_sbat)
488 return -1;
489
490 list_t sbat_entries;
491 INIT_LIST_HEAD(&sbat_entries);
492 EFI_STATUS status;
493
494 status = verify_sbat(test_sbat, &sbat_entries);
495
496 assert(status == EFI_INVALID_PARAMETER);
497 free_mock_sbat(test_sbat);
498 return 0;
499 }
500
501 int
502 test_verify_sbat_match_one_exact(void)
503 {
504 struct sbat *test_sbat;
505 struct sbat_entry sbat_entry_array[2];
506 sbat_entry_array[0].component_name = "test1";
507 sbat_entry_array[0].component_generation = "1";
508 sbat_entry_array[0].vendor_name = "SBAT test1";
509 sbat_entry_array[0].vendor_package_name = "acme";
510 sbat_entry_array[0].vendor_version = "1";
511 sbat_entry_array[0].vendor_url = "testURL";
512 sbat_entry_array[1].component_name = "test2";
513 sbat_entry_array[1].component_generation = "2";
514 sbat_entry_array[1].vendor_name = "SBAT test2";
515 sbat_entry_array[1].vendor_package_name = "acme2";
516 sbat_entry_array[1].vendor_version = "2";
517 sbat_entry_array[1].vendor_url = "testURL2";
518 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array, 2);
519 if (!test_sbat)
520 return -1;
521
522 list_t *test_sbat_entries;
523 test_sbat_entries = create_mock_sbat_entries_one_entry("test1", "1");
524 if (!test_sbat_entries)
525 return -1;
526 EFI_STATUS status;
527
528 status = verify_sbat(test_sbat, test_sbat_entries);
529
530 assert(status == EFI_SUCCESS);
531 free_mock_sbat(test_sbat);
532 free_mock_sbat_entries(test_sbat_entries);
533 return 0;
534 }
535
536 int
537 test_verify_sbat_match_one_higher(void)
538 {
539 struct sbat *test_sbat;
540 struct sbat_entry sbat_entry_array[2];
541 sbat_entry_array[0].component_name = "test1";
542 sbat_entry_array[0].component_generation = "1";
543 sbat_entry_array[0].vendor_name = "SBAT test1";
544 sbat_entry_array[0].vendor_package_name = "acme";
545 sbat_entry_array[0].vendor_version = "1";
546 sbat_entry_array[0].vendor_url = "testURL";
547 sbat_entry_array[1].component_name = "test2";
548 sbat_entry_array[1].component_generation = "2";
549 sbat_entry_array[1].vendor_name = "SBAT test2";
550 sbat_entry_array[1].vendor_package_name = "acme2";
551 sbat_entry_array[1].vendor_version = "2";
552 sbat_entry_array[1].vendor_url = "testURL2";
553 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array, 2);
554 if (!test_sbat)
555 return -1;
556
557 list_t *test_sbat_entries;
558 test_sbat_entries = create_mock_sbat_entries_one_entry("test2", "1");
559 if (!test_sbat_entries)
560 return -1;
561 EFI_STATUS status;
562
563 status = verify_sbat(test_sbat, test_sbat_entries);
564
565 assert(status == EFI_SUCCESS);
566 free_mock_sbat(test_sbat);
567 free_mock_sbat_entries(test_sbat_entries);
568 return 0;
569 }
570
571 int
572 test_verify_sbat_reject_one(void)
573 {
574 struct sbat *test_sbat;
575 struct sbat_entry sbat_entry_array[2];
576 sbat_entry_array[0].component_name = "test1";
577 sbat_entry_array[0].component_generation = "1";
578 sbat_entry_array[0].vendor_name = "SBAT test1";
579 sbat_entry_array[0].vendor_package_name = "acme";
580 sbat_entry_array[0].vendor_version = "1";
581 sbat_entry_array[0].vendor_url = "testURL";
582 sbat_entry_array[1].component_name = "test2";
583 sbat_entry_array[1].component_generation = "2";
584 sbat_entry_array[1].vendor_name = "SBAT test2";
585 sbat_entry_array[1].vendor_package_name = "acme2";
586 sbat_entry_array[1].vendor_version = "2";
587 sbat_entry_array[1].vendor_url = "testURL2";
588 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array, 2);
589 if (!test_sbat)
590 return -1;
591
592 list_t *test_sbat_entries;
593 test_sbat_entries = create_mock_sbat_entries_one_entry("test2", "3");
594 if (!test_sbat_entries)
595 return -1;
596 EFI_STATUS status;
597
598 status = verify_sbat(test_sbat, test_sbat_entries);
599
600 assert(status == EFI_SECURITY_VIOLATION);
601 free_mock_sbat(test_sbat);
602 free_mock_sbat_entries(test_sbat_entries);
603 return 0;
604 }
605
606 int
607 test_verify_sbat_reject_many(void)
608 {
609 struct sbat *test_sbat;
610 unsigned int sbat_entry_array_size = 2;
611 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
612 sbat_entry_array[0].component_name = "test1";
613 sbat_entry_array[0].component_generation = "1";
614 sbat_entry_array[0].vendor_name = "SBAT test1";
615 sbat_entry_array[0].vendor_package_name = "acme";
616 sbat_entry_array[0].vendor_version = "1";
617 sbat_entry_array[0].vendor_url = "testURL";
618 sbat_entry_array[1].component_name = "test2";
619 sbat_entry_array[1].component_generation = "2";
620 sbat_entry_array[1].vendor_name = "SBAT test2";
621 sbat_entry_array[1].vendor_package_name = "acme2";
622 sbat_entry_array[1].vendor_version = "2";
623 sbat_entry_array[1].vendor_url = "testURL2";
624 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
625 sbat_entry_array_size);
626 if (!test_sbat)
627 return -1;
628
629 list_t *test_sbat_entries;
630 unsigned int sbat_var_array_size = 2;
631 struct sbat_var sbat_var_array[sbat_var_array_size];
632 sbat_var_array[0].component_name = "test1";
633 sbat_var_array[0].component_generation = "1";
634 sbat_var_array[1].component_name = "test2";
635 sbat_var_array[1].component_generation = "3";
636 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
637 sbat_var_array_size);
638 if (!test_sbat_entries)
639 return -1;
640 EFI_STATUS status;
641
642 status = verify_sbat(test_sbat, test_sbat_entries);
643
644 assert(status == EFI_SECURITY_VIOLATION);
645 free_mock_sbat(test_sbat);
646 free_mock_sbat_entries(test_sbat_entries);
647 return 0;
648 }
649
650 int
651 test_verify_sbat_match_many_higher(void)
652 {
653 struct sbat *test_sbat;
654 unsigned int sbat_entry_array_size = 2;
655 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
656 sbat_entry_array[0].component_name = "test1";
657 sbat_entry_array[0].component_generation = "3";
658 sbat_entry_array[0].vendor_name = "SBAT test1";
659 sbat_entry_array[0].vendor_package_name = "acme";
660 sbat_entry_array[0].vendor_version = "1";
661 sbat_entry_array[0].vendor_url = "testURL";
662 sbat_entry_array[1].component_name = "test2";
663 sbat_entry_array[1].component_generation = "5";
664 sbat_entry_array[1].vendor_name = "SBAT test2";
665 sbat_entry_array[1].vendor_package_name = "acme2";
666 sbat_entry_array[1].vendor_version = "2";
667 sbat_entry_array[1].vendor_url = "testURL2";
668 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
669 sbat_entry_array_size);
670 if (!test_sbat)
671 return -1;
672
673 list_t *test_sbat_entries;
674 unsigned int sbat_var_array_size = 2;
675 struct sbat_var sbat_var_array[sbat_var_array_size];
676 sbat_var_array[0].component_name = "test1";
677 sbat_var_array[0].component_generation = "1";
678 sbat_var_array[1].component_name = "test2";
679 sbat_var_array[1].component_generation = "2";
680 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
681 sbat_var_array_size);
682 if (!test_sbat_entries)
683 return -1;
684 EFI_STATUS status;
685
686 status = verify_sbat(test_sbat, test_sbat_entries);
687
688 assert(status == EFI_SUCCESS);
689 free_mock_sbat(test_sbat);
690 free_mock_sbat_entries(test_sbat_entries);
691 return 0;
692 }
693
694 int
695 test_verify_sbat_match_many_exact(void)
696 {
697 struct sbat *test_sbat;
698 unsigned int sbat_entry_array_size = 2;
699 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
700 sbat_entry_array[0].component_name = "test1";
701 sbat_entry_array[0].component_generation = "1";
702 sbat_entry_array[0].vendor_name = "SBAT test1";
703 sbat_entry_array[0].vendor_package_name = "acme";
704 sbat_entry_array[0].vendor_version = "1";
705 sbat_entry_array[0].vendor_url = "testURL";
706 sbat_entry_array[1].component_name = "test2";
707 sbat_entry_array[1].component_generation = "2";
708 sbat_entry_array[1].vendor_name = "SBAT test2";
709 sbat_entry_array[1].vendor_package_name = "acme2";
710 sbat_entry_array[1].vendor_version = "2";
711 sbat_entry_array[1].vendor_url = "testURL2";
712 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
713 sbat_entry_array_size);
714 if (!test_sbat)
715 return -1;
716
717 list_t *test_sbat_entries;
718 unsigned int sbat_var_array_size = 2;
719 struct sbat_var sbat_var_array[sbat_var_array_size];
720 sbat_var_array[0].component_name = "test1";
721 sbat_var_array[0].component_generation = "1";
722 sbat_var_array[1].component_name = "test2";
723 sbat_var_array[1].component_generation = "2";
724 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
725 sbat_var_array_size);
726 if (!test_sbat_entries)
727 return -1;
728 EFI_STATUS status;
729
730 status = verify_sbat(test_sbat, test_sbat_entries);
731
732 assert(status == EFI_SUCCESS);
733 free_mock_sbat(test_sbat);
734 free_mock_sbat_entries(test_sbat_entries);
735 return 0;
736 }
737
738 int
739 test_verify_sbat_reject_many_all(void)
740 {
741 struct sbat *test_sbat;
742 unsigned int sbat_entry_array_size = 2;
743 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
744 sbat_entry_array[0].component_name = "test1";
745 sbat_entry_array[0].component_generation = "1";
746 sbat_entry_array[0].vendor_name = "SBAT test1";
747 sbat_entry_array[0].vendor_package_name = "acme";
748 sbat_entry_array[0].vendor_version = "1";
749 sbat_entry_array[0].vendor_url = "testURL";
750 sbat_entry_array[1].component_name = "test2";
751 sbat_entry_array[1].component_generation = "2";
752 sbat_entry_array[1].vendor_name = "SBAT test2";
753 sbat_entry_array[1].vendor_package_name = "acme2";
754 sbat_entry_array[1].vendor_version = "2";
755 sbat_entry_array[1].vendor_url = "testURL2";
756 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
757 sbat_entry_array_size);
758 if (!test_sbat)
759 return -1;
760
761 list_t *test_sbat_entries;
762 unsigned int sbat_var_array_size = 2;
763 struct sbat_var sbat_var_array[sbat_var_array_size];
764 sbat_var_array[0].component_name = "test1";
765 sbat_var_array[0].component_generation = "3";
766 sbat_var_array[1].component_name = "test2";
767 sbat_var_array[1].component_generation = "5";
768 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
769 sbat_var_array_size);
770 if (!test_sbat_entries)
771 return -1;
772 EFI_STATUS status;
773
774 status = verify_sbat(test_sbat, test_sbat_entries);
775
776 assert(status == EFI_SECURITY_VIOLATION);
777 free_mock_sbat(test_sbat);
778 free_mock_sbat_entries(test_sbat_entries);
779 return 0;
780 }
781
782 int
783 test_verify_sbat_match_diff_name(void)
784 {
785 struct sbat *test_sbat;
786 unsigned int sbat_entry_array_size = 2;
787 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
788 sbat_entry_array[0].component_name = "test1";
789 sbat_entry_array[0].component_generation = "1";
790 sbat_entry_array[0].vendor_name = "SBAT test1";
791 sbat_entry_array[0].vendor_package_name = "acme";
792 sbat_entry_array[0].vendor_version = "1";
793 sbat_entry_array[0].vendor_url = "testURL";
794 sbat_entry_array[1].component_name = "test2";
795 sbat_entry_array[1].component_generation = "2";
796 sbat_entry_array[1].vendor_name = "SBAT test2";
797 sbat_entry_array[1].vendor_package_name = "acme2";
798 sbat_entry_array[1].vendor_version = "2";
799 sbat_entry_array[1].vendor_url = "testURL2";
800 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
801 sbat_entry_array_size);
802 if (!test_sbat)
803 return -1;
804
805 list_t *test_sbat_entries;
806 unsigned int sbat_var_array_size = 2;
807 struct sbat_var sbat_var_array[sbat_var_array_size];
808 sbat_var_array[0].component_name = "foo";
809 sbat_var_array[0].component_generation = "5";
810 sbat_var_array[1].component_name = "bar";
811 sbat_var_array[1].component_generation = "2";
812 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
813 sbat_var_array_size);
814 if (!test_sbat_entries)
815 return -1;
816 EFI_STATUS status;
817
818 status = verify_sbat(test_sbat, test_sbat_entries);
819
820 assert(status == EFI_SUCCESS);
821 free_mock_sbat(test_sbat);
822 free_mock_sbat_entries(test_sbat_entries);
823 return 0;
824 }
825
826 int
827 test_verify_sbat_match_diff_name_mixed(void)
828 {
829 struct sbat *test_sbat;
830 unsigned int sbat_entry_array_size = 2;
831 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
832 sbat_entry_array[0].component_name = "test1";
833 sbat_entry_array[0].component_generation = "1";
834 sbat_entry_array[0].vendor_name = "SBAT test1";
835 sbat_entry_array[0].vendor_package_name = "acme";
836 sbat_entry_array[0].vendor_version = "1";
837 sbat_entry_array[0].vendor_url = "testURL";
838 sbat_entry_array[1].component_name = "test2";
839 sbat_entry_array[1].component_generation = "2";
840 sbat_entry_array[1].vendor_name = "SBAT test2";
841 sbat_entry_array[1].vendor_package_name = "acme2";
842 sbat_entry_array[1].vendor_version = "2";
843 sbat_entry_array[1].vendor_url = "testURL2";
844 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
845 sbat_entry_array_size);
846 if (!test_sbat)
847 return -1;
848
849 list_t *test_sbat_entries;
850 unsigned int sbat_var_array_size = 2;
851 struct sbat_var sbat_var_array[sbat_var_array_size];
852 sbat_var_array[0].component_name = "test1";
853 sbat_var_array[0].component_generation = "1";
854 sbat_var_array[1].component_name = "bar";
855 sbat_var_array[1].component_generation = "2";
856 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
857 sbat_var_array_size);
858 if (!test_sbat_entries)
859 return -1;
860 EFI_STATUS status;
861
862 status = verify_sbat(test_sbat, test_sbat_entries);
863
864 assert(status == EFI_SUCCESS);
865 free_mock_sbat(test_sbat);
866 free_mock_sbat_entries(test_sbat_entries);
867 return 0;
868 }
869
870 int
871 test_verify_sbat_reject_diff_name_mixed(void)
872 {
873 struct sbat *test_sbat;
874 unsigned int sbat_entry_array_size = 2;
875 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
876 sbat_entry_array[0].component_name = "test1";
877 sbat_entry_array[0].component_generation = "1";
878 sbat_entry_array[0].vendor_name = "SBAT test1";
879 sbat_entry_array[0].vendor_package_name = "acme";
880 sbat_entry_array[0].vendor_version = "1";
881 sbat_entry_array[0].vendor_url = "testURL";
882 sbat_entry_array[1].component_name = "test2";
883 sbat_entry_array[1].component_generation = "2";
884 sbat_entry_array[1].vendor_name = "SBAT test2";
885 sbat_entry_array[1].vendor_package_name = "acme2";
886 sbat_entry_array[1].vendor_version = "2";
887 sbat_entry_array[1].vendor_url = "testURL2";
888 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
889 sbat_entry_array_size);
890 if (!test_sbat)
891 return -1;
892
893 list_t *test_sbat_entries;
894 unsigned int sbat_var_array_size = 2;
895 struct sbat_var sbat_var_array[sbat_var_array_size];
896 sbat_var_array[0].component_name = "test1";
897 sbat_var_array[0].component_generation = "5";
898 sbat_var_array[1].component_name = "bar";
899 sbat_var_array[1].component_generation = "2";
900 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
901 sbat_var_array_size);
902 if (!test_sbat_entries)
903 return -1;
904 EFI_STATUS status;
905
906 status = verify_sbat(test_sbat, test_sbat_entries);
907
908 assert(status == EFI_SECURITY_VIOLATION);
909 free_mock_sbat(test_sbat);
910 free_mock_sbat_entries(test_sbat_entries);
911 return 0;
912 }
913 #endif
914
915 int
916 test_parse_and_verify(void)
917 {
918 EFI_STATUS status;
919 char sbat_section[] =
920 "test1,1,SBAT test1,acme1,1,testURL1\n"
921 "test2,2,SBAT test2,acme2,2,testURL2\n";
922 struct sbat_section_entry **section_entries = NULL;
923 size_t n_section_entries = 0, i;
924 struct sbat_section_entry test_section_entry1 = {
925 "test1", "1", "SBAT test1", "acme1", "1", "testURL1"
926 };
927 struct sbat_section_entry test_section_entry2 = {
928 "test2", "2", "SBAT test2", "acme2", "2", "testURL2"
929 };
930 struct sbat_section_entry *test_entries[] = {
931 &test_section_entry1, &test_section_entry2,
932 };
933 int rc = -1;
934
935 status = parse_sbat_section(sbat_section, sizeof(sbat_section)-1,
936 &n_section_entries, &section_entries);
937 eassert(status == EFI_SUCCESS, "expected %d got %d\n",
938 EFI_SUCCESS, status);
939 eassert(section_entries != NULL, "expected non-NULL got NULL\n");
940
941 for (i = 0; i < n_section_entries; i++) {
942 struct sbat_section_entry *entry = section_entries[i];
943 struct sbat_section_entry *test_entry = test_entries[i];
944
945 #define mkassert(a) \
946 eassert(strcmp(entry-> a, test_entry-> a) == 0, \
947 "expected \"%s\" got \"%s\"\n", \
948 test_entry-> a, entry-> a )
949
950 mkassert(component_name);
951 mkassert(component_generation);
952 mkassert(vendor_name);
953 mkassert(vendor_package_name);
954 mkassert(vendor_version);
955 mkassert(vendor_url);
956
957 #undef mkassert
958 }
959
960 eassert(n_section_entries == 2, "expected %d got %d\n",
961 2, n_section_entries);
962
963 char sbat_var_data[] = "test1,5\nbar,2\n";
964 size_t sbat_var_data_size = sizeof(sbat_var_data);
965 char *sbat_var_alloced = calloc(1, sbat_var_data_size);
966 if (!sbat_var_alloced)
967 return -1;
968 memcpy(sbat_var_alloced, sbat_var_data, sbat_var_data_size);
969
970 INIT_LIST_HEAD(&sbat_var);
971 status = parse_sbat_var_data(&sbat_var, sbat_var_alloced, sbat_var_data_size);
972 free(sbat_var_alloced);
973 if (status != EFI_SUCCESS || list_empty(&sbat_var))
974 return -1;
975
976 status = verify_sbat(n_section_entries, section_entries);
977 assert_equal_goto(status, EFI_SECURITY_VIOLATION, err, "expected %#x got %#x\n");
978
979 rc = 0;
980 err:
981 cleanup_sbat_section_entries(n_section_entries, section_entries);
982 cleanup_sbat_var(&sbat_var);
983
984 return rc;
985 }
986
987 int
988 test_preserve_sbat_uefi_variable_good(void)
989 {
990 char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
991 char sbatvar[] = "sbat,1,2021030218\ncomponent,2,\n";
992 size_t sbat_size = sizeof(sbat);
993 UINT32 attributes = SBAT_VAR_ATTRS;
994
995 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
996 return 0;
997 else
998 return -1;
999 }
1000
1001 int
1002 test_preserve_sbat_uefi_variable_version_newer(void)
1003 {
1004 char sbat[] = "sbat,2,2022030218\ncomponent,2,\n";
1005 char sbatvar[] = "sbat,1,2021030218\ncomponent,2,\n";
1006 size_t sbat_size = sizeof(sbat);
1007 UINT32 attributes = SBAT_VAR_ATTRS;
1008
1009 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1010 return 0;
1011 else
1012 return -1;
1013 }
1014
1015 int
1016 test_preserve_sbat_uefi_variable_version_newerlonger(void)
1017 {
1018 char sbat[] = "sbat,10,2022030218\ncomponent,2,\n";
1019 char sbatvar[] = "sbat,2,2021030218\ncomponent,2,\n";
1020 size_t sbat_size = sizeof(sbat);
1021 UINT32 attributes = SBAT_VAR_ATTRS;
1022
1023 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1024 return 0;
1025 else
1026 return -1;
1027 }
1028
1029 int
1030 test_preserve_sbat_uefi_variable_version_older(void)
1031 {
1032 char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
1033 char sbatvar[] = "sbat,2,2022030218\ncomponent,2,\n";
1034 size_t sbat_size = sizeof(sbat);
1035 UINT32 attributes = SBAT_VAR_ATTRS;
1036
1037 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1038 return -1;
1039 else
1040 return 0;
1041 }
1042
1043 int
1044 test_preserve_sbat_uefi_variable_version_olderlonger(void)
1045 {
1046 char sbat[] = "sbat,2,2021030218\ncomponent,2,\n";
1047 char sbatvar[] = "sbat,10,2022030218\ncomponent,2,\n";
1048 size_t sbat_size = sizeof(sbat);
1049 UINT32 attributes = SBAT_VAR_ATTRS;
1050
1051 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1052 return -1;
1053 else
1054 return 0;
1055 }
1056
1057
1058 int
1059 test_preserve_sbat_uefi_variable_newer(void)
1060 {
1061 char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
1062 char sbatvar[] = "sbat,1,2025030218\ncomponent,5,\ncomponent,3";
1063 size_t sbat_size = sizeof(sbat);
1064 UINT32 attributes = SBAT_VAR_ATTRS;
1065
1066 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1067 return -1;
1068 else
1069 return 0;
1070 }
1071 int
1072 test_preserve_sbat_uefi_variable_older(void)
1073 {
1074 char sbat[] = "sbat,1,2025030218\ncomponent,2,\ncomponent,3";
1075 char sbatvar[] = "sbat,1,2020030218\ncomponent,1,\n";
1076 size_t sbat_size = sizeof(sbat);
1077 UINT32 attributes = SBAT_VAR_ATTRS;
1078
1079 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1080 return 0;
1081 else
1082 return -1;
1083 }
1084
1085 int
1086 test_preserve_sbat_uefi_variable_bad_sig(void)
1087 {
1088 char sbat[] = "bad_sig,1,2021030218\ncomponent,2,\n";
1089 char sbatvar[] = "sbat,1,2021030218\n";
1090 size_t sbat_size = sizeof(sbat);
1091 UINT32 attributes = SBAT_VAR_ATTRS;
1092
1093 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1094 return -1;
1095 else
1096 return 0;
1097 }
1098
1099 int
1100 test_preserve_sbat_uefi_variable_bad_attr(void)
1101 {
1102 char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
1103 char sbatvar[] = "sbat,1,2021030218\n";
1104 size_t sbat_size = sizeof(sbat);
1105 UINT32 attributes = 0;
1106
1107 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1108 return -1;
1109 else
1110 return 0;
1111 }
1112
1113 int
1114 test_preserve_sbat_uefi_variable_bad_short(void)
1115 {
1116 char sbat[] = "sba";
1117 char sbatvar[] = "sbat,1,2021030218\n";
1118 size_t sbat_size = sizeof(sbat);
1119 UINT32 attributes = SBAT_VAR_ATTRS;
1120
1121 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1122 return -1;
1123 else
1124 return 0;
1125 }
1126
1127 static int
1128 test_sbat_var_asciz(void)
1129 {
1130 EFI_STATUS status;
1131 char buf[1024] = "";
1132 UINT32 attrs = 0;
1133 UINTN size = sizeof(buf);
1134 char expected[] = SBAT_VAR_AUTOMATIC;
1135
1136 status = set_sbat_uefi_variable(SBAT_VAR_AUTOMATIC, SBAT_VAR_AUTOMATIC);
1137 if (status != EFI_SUCCESS)
1138 return -1;
1139
1140 status = RT->GetVariable(SBAT_VAR_NAME, &SHIM_LOCK_GUID, &attrs, &size, buf);
1141 if (status != EFI_SUCCESS)
1142 return -1;
1143
1144 /*
1145 * this should be enough to get past "sbat,", which handles the
1146 * first error.
1147 */
1148 if (size < (strlen(SBAT_VAR_SIG) + 2) || size != strlen(expected))
1149 return -1;
1150
1151 if (strncmp(expected, buf, size) != 0)
1152 return -1;
1153
1154 return 0;
1155 }
1156
1157 int
1158 main(void)
1159 {
1160 int status = 0;
1161
1162 // parse_sbat section tests
1163 test(test_parse_sbat_tiny);
1164 test(test_parse_sbat_section_null_sbat_base);
1165 test(test_parse_sbat_section_zero_sbat_size);
1166 test(test_parse_sbat_section_null_entries);
1167 test(test_parse_sbat_section_null_count);
1168 test(test_parse_sbat_section_no_newline);
1169 test(test_parse_sbat_section_no_commas);
1170 test(test_parse_sbat_section_too_few_elem);
1171 test(test_parse_sbat_section_too_many_elem);
1172
1173 // parse_sbat_var tests
1174 test(test_parse_sbat_var_null_list);
1175 test(test_parse_sbat_var_data_null_list);
1176 test(test_parse_sbat_var_data_null_data);
1177 test(test_parse_sbat_var_data_zero_size);
1178
1179 // verify_sbat tests
1180 test(test_verify_sbat_null_sbat_section);
1181 #if 0
1182 test(test_verify_sbat_null_sbat_entries);
1183 test(test_verify_sbat_match_one_exact);
1184 test(test_verify_sbat_match_one_higher);
1185 test(test_verify_sbat_reject_one);
1186 test(test_verify_sbat_reject_many);
1187 test(test_verify_sbat_match_many_higher);
1188 test(test_verify_sbat_match_many_exact);
1189 test(test_verify_sbat_reject_many_all);
1190 test(test_verify_sbat_match_diff_name);
1191 test(test_verify_sbat_match_diff_name_mixed);
1192 test(test_verify_sbat_reject_diff_name_mixed);
1193 #endif
1194 test(test_parse_and_verify);
1195
1196 test(test_preserve_sbat_uefi_variable_good);
1197 test(test_preserve_sbat_uefi_variable_newer);
1198 test(test_preserve_sbat_uefi_variable_older);
1199 test(test_preserve_sbat_uefi_variable_bad_sig);
1200 test(test_preserve_sbat_uefi_variable_bad_attr);
1201 test(test_preserve_sbat_uefi_variable_bad_short);
1202 test(test_preserve_sbat_uefi_variable_version_newer);
1203 test(test_preserve_sbat_uefi_variable_version_newerlonger);
1204 test(test_preserve_sbat_uefi_variable_version_older);
1205 test(test_preserve_sbat_uefi_variable_version_olderlonger);
1206
1207 test(test_sbat_var_asciz);
1208
1209 return status;
1210 }
1211
1212 // vim:fenc=utf-8:tw=75:noet