]> git.proxmox.com Git - efi-boot-shim.git/blob - test-load-options.c
Add ubuntu test
[efi-boot-shim.git] / test-load-options.c
1 // SPDX-License-Identifier: BSD-2-Clause-Patent
2 /*
3 * test-argv.c - test our loader_opts parsing
4 */
5 #pragma GCC diagnostic ignored "-Wunused-variable"
6 #pragma GCC diagnostic error "-Wnonnull"
7 #pragma GCC diagnostic error "-Wunused-function"
8
9 #pragma GCC diagnostic warning "-Wcpp"
10
11 #ifndef SHIM_UNIT_TEST
12 #define SHIM_UNIT_TEST
13 #endif
14
15 #include "shim.h"
16
17 #include <execinfo.h>
18 #include <stdio.h>
19 #include <efivar/efivar.h>
20
21 EFI_DEVICE_PATH *
22 make_file_dp(char *filename)
23 {
24 void *filedp = NULL;
25 size_t filedpsz = 0, filedpneeded = 0;
26
27 filedpneeded = efidp_make_file(filedp, filedpneeded, filename);
28 assert_positive_return(filedpneeded, NULL, "\n");
29
30 filedp = calloc(1, filedpneeded + 4);
31 assert_nonzero_return(filedp, NULL, "\n");
32
33 filedpsz = efidp_make_file(filedp, filedpneeded, filename);
34 assert_equal_goto(filedpsz, filedpneeded, err, "got %zu expected %zu\n");
35
36 efidp_make_end_entire((uint8_t *)filedp + filedpneeded, 4);
37
38 return filedp;
39 err:
40 free(filedp);
41 return NULL;
42 }
43
44 int
45 test_parse_load_options(char *load_option_data,
46 size_t load_option_data_size,
47 char *file_path,
48 CHAR16 *target_second_stage,
49 char *target_remaining,
50 size_t target_remaining_size)
51 {
52 EFI_STATUS status = EFI_SUCCESS;
53 EFI_LOADED_IMAGE li = {
54 .LoadOptions = load_option_data,
55 .LoadOptionsSize = load_option_data_size,
56 .FilePath = make_file_dp(file_path),
57 };
58 CHAR16 *dummy_second_stage = calloc(1, 8);
59 int rc = -1;
60
61 assert_nonzero_goto(li.FilePath, err, "\n");
62 assert_nonzero_goto(dummy_second_stage, err, "\n");
63
64 StrCat(dummy_second_stage, L"foo");
65 second_stage = dummy_second_stage;
66
67 status = parse_load_options(&li);
68 assert_false_goto(EFI_ERROR(status), err, "\n");
69
70 assert_nonzero_goto(second_stage, err, "\n");
71 assert_not_equal_goto(second_stage, dummy_second_stage, err, "%p == %p\n");
72 assert_zero_goto(StrnCmp(second_stage, target_second_stage, 90),
73 err_print_second_stage, "%d != 0\n");
74
75 assert_equal_goto(load_options_size, target_remaining_size, err_remaining, "%zu != %zu\n");
76 assert_equal_goto(load_options, target_remaining, err_remaining, "%p != %p\n");
77 assert_zero_goto(memcmp(load_options, target_remaining, load_options_size), err_remaining, "\n");
78
79 rc = 0;
80 err_remaining:
81 if (rc != 0) {
82 printf("expected remaining:%p\n", target_remaining);
83 for (size_t i = 0; i < target_remaining_size; i++)
84 printf("0x%02hhx ", target_remaining[i]);
85 printf("\n");
86 printf("actual remaining:%p\n", load_options);
87 for (size_t i = 0; i < load_options_size; i++)
88 printf("0x%02hhx ", ((char *)load_options)[i]);
89 printf("\n");
90 }
91 err_print_second_stage:
92 if (rc != 0) {
93 printf("second stage:\"");
94 for(int i = 0; second_stage[i] != 0; i++)
95 printf("%c", second_stage[i]);
96 printf("\"\nexpected:\"");
97 for(int i = 0; target_second_stage[i] != 0; i++)
98 printf("%c", target_second_stage[i]);
99 printf("\"\n");
100 }
101 err:
102 if (rc != 0) {
103 print_traceback(0);
104 }
105 if (li.FilePath) {
106 free(li.FilePath);
107 }
108 if (dummy_second_stage && dummy_second_stage != second_stage) {
109 free(dummy_second_stage);
110 }
111 second_stage = NULL;
112
113 return rc;
114 }
115
116 int __attribute__((__flatten__))
117 test_efi_shell_0(void)
118 {
119 /*
120 00000000 5c 00 45 00 46 00 49 00 5c 00 66 00 65 00 64 00 |\.E.F.I.\.f.e.d.|
121 00000010 6f 00 72 00 61 00 5c 00 73 00 68 00 69 00 6d 00 |o.r.a.\.s.h.i.m.|
122 00000020 78 00 36 00 34 00 2e 00 65 00 66 00 69 00 20 00 |x.6.4...e.f.i. .|
123 00000030 5c 00 45 00 46 00 49 00 5c 00 66 00 65 00 64 00 |\.E.F.I.\.f.e.d.|
124 00000040 6f 00 72 00 61 00 5c 00 66 00 77 00 75 00 70 00 |o.r.a.\.f.w.u.p.|
125 00000050 64 00 61 00 74 00 65 00 2e 00 65 00 66 00 69 00 |d.a.t.e...e.f.i.|
126 00000060 20 00 00 00 66 00 73 00 30 00 3a 00 5c 00 00 00 | ...f.s.0.:.\...|
127 */
128
129 char load_option_data[] = {
130 0x5c, 0x00, 0x45, 0x00, 0x46, 0x00, 0x49, 0x00,
131 0x5c, 0x00, 0x66, 0x00, 0x65, 0x00, 0x64, 0x00,
132 0x6f, 0x00, 0x72, 0x00, 0x61, 0x00, 0x5c, 0x00,
133 0x73, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6d, 0x00,
134 0x78, 0x00, 0x36, 0x00, 0x34, 0x00, 0x2e, 0x00,
135 0x65, 0x00, 0x66, 0x00, 0x69, 0x00, 0x20, 0x00,
136 0x5c, 0x00, 0x45, 0x00, 0x46, 0x00, 0x49, 0x00,
137 0x5c, 0x00, 0x66, 0x00, 0x65, 0x00, 0x64, 0x00,
138 0x6f, 0x00, 0x72, 0x00, 0x61, 0x00, 0x5c, 0x00,
139 0x66, 0x00, 0x77, 0x00, 0x75, 0x00, 0x70, 0x00,
140 0x64, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00,
141 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00,
142 0x20, 0x00, 0x00, 0x00, 0x66, 0x00, 0x73, 0x00,
143 0x30, 0x00, 0x3a, 0x00, 0x5c, 0x00, 0x00, 0x00,
144 };
145 size_t load_option_data_size = sizeof(load_option_data);
146 char *remaining = &load_option_data[sizeof(load_option_data)-14];
147 size_t remaining_size = 14;
148
149 return test_parse_load_options(load_option_data,
150 load_option_data_size,
151 "\\EFI\\fedora\\shimx64.efi",
152 L"\\EFI\\fedora\\fwupdate.efi",
153 remaining, remaining_size);
154 }
155
156 int __attribute__((__flatten__))
157 test_bds_0(void)
158 {
159 /*
160 00000000 01 00 00 00 62 00 4c 00 69 00 6e 00 75 00 78 00 |....b.L.i.n.u.x.|
161 00000010 20 00 46 00 69 00 72 00 6d 00 77 00 61 00 72 00 | .F.i.r.m.w.a.r.|
162 00000020 65 00 20 00 55 00 70 00 64 00 61 00 74 00 65 00 |e. .U.p.d.a.t.e.|
163 00000030 72 00 00 00 40 01 2a 00 01 00 00 00 00 08 00 00 |r.....*.........|
164 00000040 00 00 00 00 00 40 06 00 00 00 00 00 1a 9e 55 bf |.....@........U.|
165 00000050 04 57 f2 4f b4 4a ed 26 4a 40 6a 94 02 02 04 04 |.W.O.:.&J@j.....|
166 00000060 34 00 5c 00 45 00 46 00 49 00 5c 00 66 00 65 00 |4.\.E.F.I.\.f.e.|
167 00000070 64 00 6f 00 72 00 61 00 5c 00 73 00 68 00 69 00 |d.o.r.a.\.s.h.i.|
168 00000080 6d 00 78 00 36 00 34 00 2e 00 65 00 66 00 69 00 |m.x.6.4...e.f.i.|
169 00000090 00 00 7f ff 04 00 20 00 5c 00 66 00 77 00 75 00 |...... .\.f.w.u.|
170 000000a0 70 00 78 00 36 00 34 00 2e 00 65 00 66 00 69 00 |p.x.6.4...e.f.i.|
171 000000b0 00 00 |..|
172 */
173 char load_option_data [] = {
174 0x01, 0x00, 0x00, 0x00, 0x62, 0x00, 0x4c, 0x00,
175 0x69, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x78, 0x00,
176 0x20, 0x00, 0x46, 0x00, 0x69, 0x00, 0x72, 0x00,
177 0x6d, 0x00, 0x77, 0x00, 0x61, 0x00, 0x72, 0x00,
178 0x65, 0x00, 0x20, 0x00, 0x55, 0x00, 0x70, 0x00,
179 0x64, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00,
180 0x72, 0x00, 0x00, 0x00, 0x40, 0x01, 0x2a, 0x00,
181 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x1a, 0x9e, 0x55, 0xbf,
184 0x04, 0x57, 0xf2, 0x4f, 0xb4, 0x4a, 0xed, 0x26,
185 0x4a, 0x40, 0x6a, 0x94, 0x02, 0x02, 0x04, 0x04,
186 0x34, 0x00, 0x5c, 0x00, 0x45, 0x00, 0x46, 0x00,
187 0x49, 0x00, 0x5c, 0x00, 0x66, 0x00, 0x65, 0x00,
188 0x64, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x61, 0x00,
189 0x5c, 0x00, 0x73, 0x00, 0x68, 0x00, 0x69, 0x00,
190 0x6d, 0x00, 0x78, 0x00, 0x36, 0x00, 0x34, 0x00,
191 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00,
192 0x00, 0x00, 0x7f, 0xff, 0x04, 0x00, 0x20, 0x00,
193 0x5c, 0x00, 0x66, 0x00, 0x77, 0x00, 0x75, 0x00,
194 0x70, 0x00, 0x78, 0x00, 0x36, 0x00, 0x34, 0x00,
195 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00,
196 0x00, 0x00
197 };
198 size_t load_option_data_size = sizeof(load_option_data);
199
200 return test_parse_load_options(load_option_data,
201 load_option_data_size,
202 "\\EFI\\fedora\\shimx64.efi",
203 L"\\fwupx64.efi",
204 NULL, 0);
205 }
206
207 int __attribute__((__flatten__))
208 test_bds_1(void)
209 {
210 /*
211 00000000 5c 00 66 00 77 00 75 00 70 00 78 00 36 00 34 00 |\.f.w.u.p.x.6.4.|
212 00000010 2e 00 65 00 66 00 69 00 00 00 |..e.f.i...|
213 0000001a
214 */
215 char load_option_data [] = {
216 0x5c, 0x00, 0x66, 0x00, 0x77, 0x00, 0x75, 0x00,
217 0x70, 0x00, 0x78, 0x00, 0x36, 0x00, 0x34, 0x00,
218 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00,
219 0x00, 0x00
220 };
221 size_t load_option_data_size = sizeof(load_option_data);
222
223 return test_parse_load_options(load_option_data,
224 load_option_data_size,
225 "\\EFI\\fedora\\shimx64.efi",
226 L"\\fwupx64.efi",
227 NULL, 0);
228 }
229
230 int
231 test_bds_2(void)
232 {
233 /*
234 00000000 74 00 65 00 73 00 74 00 2E 00 65 00 66 00 69 00 |t.e.s.t...e.f.i.|
235 00000010 20 00 6F 00 6E 00 65 00 20 00 74 00 77 00 6F 00 |..o.n.e...t.w.o.|
236 00000020 20 00 74 00 68 00 72 00 65 00 65 00 00 00 |..t.h.r.e.e...|
237 */
238 char load_option_data [] = {
239 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
240 0x2E, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00,
241 0x20, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x65, 0x00,
242 0x20, 0x00, 0x74, 0x00, 0x77, 0x00, 0x6F, 0x00,
243 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x72, 0x00,
244 0x65, 0x00, 0x65, 0x00, 0x00, 0x00
245 };
246 size_t load_option_data_size = sizeof(load_option_data);
247 char *target_remaining = &load_option_data[26];
248 size_t target_remaining_size = 20;
249
250 return test_parse_load_options(load_option_data,
251 load_option_data_size,
252 "test.efi",
253 L"one",
254 target_remaining,
255 target_remaining_size);
256 }
257
258 int
259 main(void)
260 {
261 int status = 0;
262 test(test_efi_shell_0);
263 test(test_bds_0);
264 test(test_bds_1);
265 test(test_bds_2);
266 return status;
267 }
268
269 // vim:fenc=utf-8:tw=75:noet