]>
Commit | Line | Data |
---|---|---|
8529e0f7 SM |
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 |