]> git.proxmox.com Git - efi-boot-shim.git/blame - test-sbat.c
Clean up better after build. Closes: #1046268
[efi-boot-shim.git] / test-sbat.c
CommitLineData
031e5cce
SM
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
fd2d9f03 8#include "sbat_var_defs.h"
031e5cce
SM
9#endif
10#include "shim.h"
11
12#include <stdio.h>
13
14#define MAX_SIZE 512
15
16list_t sbat_var;
17
e6ace38a
SM
18BOOLEAN
19secure_mode() {
20 return 1;
21}
22
031e5cce
SM
23#if 0
24/*
25 * Mock test helpers
26 */
27static struct sbat_entry *
28create_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
44void
45free_mock_sbat_entry(struct sbat_entry *entry)
46{
47 if (entry)
48 FreePool(entry);
49}
50
51static struct sbat *
52create_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
72static struct sbat *
73create_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
101void
102free_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
115static struct sbat_var *
116create_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
137static list_t *
138create_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
152static list_t *
153create_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
172void
173free_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 */
fd2d9f03
SM
199int
200test_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
031e5cce
SM
215int
216test_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
230int
231test_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
245int
246test_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
260int
261test_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
275int
276test_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
292int
293test_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
308int
309test_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
324int
325test_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 };
8119f718 344 int rc = -1;
031e5cce
SM
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");
8119f718 367 rc = 0;
031e5cce
SM
368fail:
369 cleanup_sbat_section_entries(n, entries);
8119f718 370 return rc;
031e5cce
SM
371}
372
373/*
374 * parse_sbat_var() tests
375 */
376int
377test_parse_sbat_var_null_list(void)
378{
379 EFI_STATUS status;
380
381 INIT_LIST_HEAD(&sbat_var);
fd2d9f03 382 status = parse_sbat_var(NULL, NULL);
031e5cce
SM
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
389int
390test_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
409int
410test_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
424int
425test_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
439int
440test_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 */
457int
458test_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;
8119f718 465 int rc = -1;
031e5cce
SM
466
467 INIT_LIST_HEAD(&test_sbat_var);
468 status = parse_sbat_var_data(&test_sbat_var, sbat_var_data, sizeof(sbat_var_data));
8119f718 469 assert_equal_goto(status, EFI_SUCCESS, err, "got %#x expected %#x\n");
031e5cce 470
8119f718
SM
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;
474err:
475 cleanup_sbat_var(&test_sbat_var);
476
477 return rc;
031e5cce
SM
478}
479
480#if 0
481int
482test_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
501int
502test_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
536int
537test_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
571int
572test_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
606int
607test_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
650int
651test_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
694int
695test_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
738int
739test_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
782int
783test_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
826int
827test_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
870int
871test_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
915int
916test_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 };
8119f718 933 int rc = -1;
031e5cce
SM
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);
8119f718 972 free(sbat_var_alloced);
031e5cce
SM
973 if (status != EFI_SUCCESS || list_empty(&sbat_var))
974 return -1;
975
976 status = verify_sbat(n_section_entries, section_entries);
8119f718 977 assert_equal_goto(status, EFI_SECURITY_VIOLATION, err, "expected %#x got %#x\n");
031e5cce 978
8119f718
SM
979 rc = 0;
980err:
031e5cce 981 cleanup_sbat_section_entries(n_section_entries, section_entries);
8119f718 982 cleanup_sbat_var(&sbat_var);
031e5cce 983
8119f718
SM
984 return rc;
985}
986
987int
988test_preserve_sbat_uefi_variable_good(void)
989{
e6ace38a
SM
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
1001int
1002test_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
1015int
1016test_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
1029int
1030test_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
1043int
1044test_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
1058int
1059test_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}
1071int
1072test_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";
8119f718
SM
1076 size_t sbat_size = sizeof(sbat);
1077 UINT32 attributes = SBAT_VAR_ATTRS;
1078
e6ace38a 1079 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
8119f718
SM
1080 return 0;
1081 else
1082 return -1;
1083}
1084
1085int
1086test_preserve_sbat_uefi_variable_bad_sig(void)
1087{
e6ace38a
SM
1088 char sbat[] = "bad_sig,1,2021030218\ncomponent,2,\n";
1089 char sbatvar[] = "sbat,1,2021030218\n";
8119f718
SM
1090 size_t sbat_size = sizeof(sbat);
1091 UINT32 attributes = SBAT_VAR_ATTRS;
1092
e6ace38a 1093 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
8119f718
SM
1094 return -1;
1095 else
1096 return 0;
1097}
1098
1099int
1100test_preserve_sbat_uefi_variable_bad_attr(void)
1101{
e6ace38a
SM
1102 char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
1103 char sbatvar[] = "sbat,1,2021030218\n";
8119f718
SM
1104 size_t sbat_size = sizeof(sbat);
1105 UINT32 attributes = 0;
1106
e6ace38a 1107 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
8119f718
SM
1108 return -1;
1109 else
1110 return 0;
1111}
1112
1113int
1114test_preserve_sbat_uefi_variable_bad_short(void)
1115{
1116 char sbat[] = "sba";
e6ace38a 1117 char sbatvar[] = "sbat,1,2021030218\n";
8119f718
SM
1118 size_t sbat_size = sizeof(sbat);
1119 UINT32 attributes = SBAT_VAR_ATTRS;
1120
e6ace38a 1121 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
8119f718
SM
1122 return -1;
1123 else
1124 return 0;
031e5cce
SM
1125}
1126
fd2d9f03
SM
1127static int
1128test_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
031e5cce
SM
1157int
1158main(void)
1159{
1160 int status = 0;
fd2d9f03 1161
031e5cce 1162 // parse_sbat section tests
fd2d9f03 1163 test(test_parse_sbat_tiny);
031e5cce
SM
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
8119f718 1196 test(test_preserve_sbat_uefi_variable_good);
e6ace38a
SM
1197 test(test_preserve_sbat_uefi_variable_newer);
1198 test(test_preserve_sbat_uefi_variable_older);
8119f718
SM
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);
e6ace38a
SM
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);
8119f718 1206
fd2d9f03
SM
1207 test(test_sbat_var_asciz);
1208
1209 return status;
031e5cce
SM
1210}
1211
1212// vim:fenc=utf-8:tw=75:noet