Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2017 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk_internal/cunit.h"
7 : :
8 : : #include "common/lib/test_env.c"
9 : :
10 : : #include "bdev/gpt/gpt.c"
11 : :
12 : : static void
13 : 3 : test_check_mbr(void)
14 : : {
15 : : struct spdk_gpt *gpt;
16 : : struct spdk_mbr *mbr;
17 : 3 : unsigned char a[SPDK_GPT_BUFFER_SIZE];
18 : : int re;
19 : :
20 : : /* Set gpt is NULL */
21 : 3 : re = gpt_parse_mbr(NULL);
22 : 3 : CU_ASSERT(re == -1);
23 : :
24 : : /* Set gpt->buf is NULL */
25 : 3 : gpt = calloc(1, sizeof(*gpt));
26 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(gpt != NULL);
27 : 3 : re = gpt_parse_mbr(gpt);
28 : 3 : CU_ASSERT(re == -1);
29 : :
30 : : /* Set *gpt is "aaa...", all are mismatch include mbr_signature */
31 : 3 : memset(a, 'a', sizeof(a));
32 : 3 : gpt->buf = &a[0];
33 : 3 : re = gpt_check_mbr(gpt);
34 : 3 : CU_ASSERT(re == -1);
35 : :
36 : : /* Set mbr->mbr_signature matched, start lba mismatch */
37 : 3 : mbr = (struct spdk_mbr *)gpt->buf;
38 : 3 : mbr->mbr_signature = 0xAA55;
39 : 3 : re = gpt_check_mbr(gpt);
40 : 3 : CU_ASSERT(re == -1);
41 : :
42 : : /* Set mbr->partitions[0].start lba matched, os_type mismatch */
43 : 3 : mbr->partitions[0].start_lba = 1;
44 : 3 : re = gpt_check_mbr(gpt);
45 : 3 : CU_ASSERT(re == -1);
46 : :
47 : : /* Set mbr->partitions[0].os_type matched, size_lba mismatch */
48 : 3 : mbr->partitions[0].os_type = 0xEE;
49 : 3 : re = gpt_check_mbr(gpt);
50 : 3 : CU_ASSERT(re == -1);
51 : :
52 : : /* Set mbr->partitions[0].size_lba matched, passing case */
53 : 3 : mbr->partitions[0].size_lba = 0xFFFFFFFF;
54 : 3 : re = gpt_check_mbr(gpt);
55 : 3 : CU_ASSERT(re == 0);
56 : :
57 : 3 : free(gpt);
58 : 3 : }
59 : :
60 : : static void
61 : 3 : test_read_header(void)
62 : : {
63 : : struct spdk_gpt *gpt;
64 : : struct spdk_gpt_header *head;
65 : 3 : unsigned char a[SPDK_GPT_BUFFER_SIZE];
66 : : int re;
67 : :
68 : : /* gpt_read_header(NULL) does not exist, NULL is filtered out in gpt_parse_mbr() */
69 : 3 : gpt = calloc(1, sizeof(*gpt));
70 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(gpt != NULL);
71 : 3 : gpt->parse_phase = SPDK_GPT_PARSE_PHASE_PRIMARY;
72 : 3 : gpt->sector_size = 512;
73 : :
74 : : /* Set *gpt is "aaa..." */
75 : 3 : memset(a, 'a', sizeof(a));
76 : 3 : gpt->buf = &a[0];
77 : 3 : gpt->buf_size = sizeof(a);
78 : :
79 : : /* Set header_size mismatch */
80 : 3 : gpt->sector_size = 512;
81 : 3 : head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size);
82 : 3 : to_le32(&head->header_size, 0x258);
83 : 3 : re = gpt_read_header(gpt);
84 : 3 : CU_ASSERT(re == -1);
85 : :
86 : : /* Set head->header_size matched, header_crc32 mismatch */
87 : 3 : head->header_size = sizeof(*head);
88 : 3 : to_le32(&head->header_crc32, 0x22D18C80);
89 : 3 : re = gpt_read_header(gpt);
90 : 3 : CU_ASSERT(re == -1);
91 : :
92 : : /* Set head->header_crc32 matched, gpt_signature mismatch */
93 : 3 : to_le32(&head->header_crc32, 0xC5B2117E);
94 : 3 : re = gpt_read_header(gpt);
95 : 3 : CU_ASSERT(re == -1);
96 : :
97 : : /* Set head->gpt_signature matched, head->my_lba mismatch */
98 : 3 : to_le32(&head->header_crc32, 0xD637335A);
99 : 3 : head->gpt_signature[0] = 'E';
100 : 3 : head->gpt_signature[1] = 'F';
101 : 3 : head->gpt_signature[2] = 'I';
102 : 3 : head->gpt_signature[3] = ' ';
103 : 3 : head->gpt_signature[4] = 'P';
104 : 3 : head->gpt_signature[5] = 'A';
105 : 3 : head->gpt_signature[6] = 'R';
106 : 3 : head->gpt_signature[7] = 'T';
107 : 3 : re = gpt_read_header(gpt);
108 : 3 : CU_ASSERT(re == -1);
109 : :
110 : : /* Set head->my_lba matched, lba_end usable_lba mismatch */
111 : 3 : to_le32(&head->header_crc32, 0xB3CDB2D2);
112 : 3 : to_le64(&head->my_lba, 0x1);
113 : 3 : re = gpt_read_header(gpt);
114 : 3 : CU_ASSERT(re == -1);
115 : :
116 : : /* Set gpt->lba_end usable_lba matched, passing case */
117 : 3 : to_le32(&head->header_crc32, 0x5531F2F0);
118 : 3 : to_le64(&gpt->lba_start, 0x0);
119 : 3 : to_le64(&gpt->lba_end, 0x2E935FFE);
120 : 3 : to_le64(&head->first_usable_lba, 0xA);
121 : 3 : to_le64(&head->last_usable_lba, 0xF4240);
122 : 3 : re = gpt_read_header(gpt);
123 : 3 : CU_ASSERT(re == 0);
124 : :
125 : 3 : free(gpt);
126 : 3 : }
127 : :
128 : : static void
129 : 3 : test_read_partitions(void)
130 : : {
131 : : struct spdk_gpt *gpt;
132 : : struct spdk_gpt_header *head;
133 : 3 : unsigned char a[SPDK_GPT_BUFFER_SIZE];
134 : : int re;
135 : :
136 : : /* gpt_read_partitions(NULL) does not exist, NULL is filtered out in gpt_parse_mbr() */
137 : 3 : gpt = calloc(1, sizeof(*gpt));
138 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(gpt != NULL);
139 : 3 : gpt->parse_phase = SPDK_GPT_PARSE_PHASE_PRIMARY;
140 : 3 : gpt->sector_size = 512;
141 : :
142 : : /* Set *gpt is "aaa..." */
143 : 3 : memset(a, 'a', sizeof(a));
144 : 3 : gpt->buf = &a[0];
145 : 3 : gpt->buf_size = sizeof(a);
146 : :
147 : : /* Set num_partition_entries exceeds Max value of entries GPT supported */
148 : 3 : gpt->sector_size = 512;
149 : 3 : head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size);
150 : 3 : gpt->header = head;
151 : 3 : to_le32(&head->num_partition_entries, 0x100);
152 : 3 : re = gpt_read_partitions(gpt);
153 : 3 : CU_ASSERT(re == -1);
154 : :
155 : : /* Set num_partition_entries within Max value, size_of_partition_entry mismatch */
156 : 3 : to_le32(&head->header_crc32, 0x573857BE);
157 : 3 : to_le32(&head->num_partition_entries, 0x40);
158 : 3 : to_le32(&head->size_of_partition_entry, 0x0);
159 : 3 : re = gpt_read_partitions(gpt);
160 : 3 : CU_ASSERT(re == -1);
161 : :
162 : : /* Set size_of_partition_entry matched, partition_entry_lba mismatch */
163 : 3 : to_le32(&head->header_crc32, 0x5279B712);
164 : 3 : to_le32(&head->size_of_partition_entry, 0x80);
165 : 3 : to_le64(&head->partition_entry_lba, 0x64);
166 : 3 : re = gpt_read_partitions(gpt);
167 : 3 : CU_ASSERT(re == -1);
168 : :
169 : : /* Set partition_entry_lba matched, partition_entry_array_crc32 mismatch */
170 : 3 : to_le32(&head->header_crc32, 0xEC093B43);
171 : 3 : to_le64(&head->partition_entry_lba, 0x20);
172 : 3 : to_le32(&head->partition_entry_array_crc32, 0x0);
173 : 3 : re = gpt_read_partitions(gpt);
174 : 3 : CU_ASSERT(re == -1);
175 : :
176 : : /* Set partition_entry_array_crc32 matched, passing case */
177 : 3 : to_le32(&head->header_crc32, 0xE1A08822);
178 : 3 : to_le32(&head->partition_entry_array_crc32, 0xEBEE44FB);
179 : 3 : to_le32(&head->num_partition_entries, 0x80);
180 : 3 : re = gpt_read_partitions(gpt);
181 : 3 : CU_ASSERT(re == 0);
182 : :
183 : 3 : free(gpt);
184 : 3 : }
185 : :
186 : : static void
187 : 3 : test_parse_mbr_and_primary(void)
188 : : {
189 : : struct spdk_gpt *gpt;
190 : : struct spdk_mbr *mbr;
191 : : struct spdk_gpt_header *head;
192 : 3 : unsigned char a[SPDK_GPT_BUFFER_SIZE];
193 : : int re;
194 : :
195 : : /* Set gpt is NULL */
196 : 3 : re = gpt_parse_mbr(NULL);
197 : 3 : CU_ASSERT(re == -1);
198 : :
199 : : /* Set gpt->buf is NULL */
200 : 3 : gpt = calloc(1, sizeof(*gpt));
201 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(gpt != NULL);
202 : 3 : gpt->parse_phase = SPDK_GPT_PARSE_PHASE_PRIMARY;
203 : 3 : gpt->sector_size = 512;
204 : 3 : re = gpt_parse_mbr(gpt);
205 : 3 : CU_ASSERT(re == -1);
206 : :
207 : : /* Set *gpt is "aaa...", check_mbr failed */
208 : 3 : memset(a, 'a', sizeof(a));
209 : 3 : gpt->buf = &a[0];
210 : 3 : gpt->buf_size = sizeof(a);
211 : 3 : re = gpt_parse_mbr(gpt);
212 : 3 : CU_ASSERT(re == -1);
213 : :
214 : : /* Set check_mbr passed */
215 : 3 : mbr = (struct spdk_mbr *)gpt->buf;
216 : 3 : mbr->mbr_signature = 0xAA55;
217 : 3 : mbr->partitions[0].start_lba = 1;
218 : 3 : mbr->partitions[0].os_type = 0xEE;
219 : 3 : mbr->partitions[0].size_lba = 0xFFFFFFFF;
220 : 3 : re = gpt_parse_mbr(gpt);
221 : 3 : CU_ASSERT(re == 0);
222 : :
223 : : /* Expect read_header failed */
224 : 3 : re = gpt_parse_partition_table(gpt);
225 : 3 : CU_ASSERT(re == -1);
226 : :
227 : : /* Set read_header passed, read_partitions failed */
228 : 3 : head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size);
229 : 3 : head->header_size = sizeof(*head);
230 : 3 : head->gpt_signature[0] = 'E';
231 : 3 : head->gpt_signature[1] = 'F';
232 : 3 : head->gpt_signature[2] = 'I';
233 : 3 : head->gpt_signature[3] = ' ';
234 : 3 : head->gpt_signature[4] = 'P';
235 : 3 : head->gpt_signature[5] = 'A';
236 : 3 : head->gpt_signature[6] = 'R';
237 : 3 : head->gpt_signature[7] = 'T';
238 : 3 : to_le32(&head->header_crc32, 0x5531F2F0);
239 : 3 : to_le64(&head->my_lba, 0x1);
240 : 3 : to_le64(&gpt->lba_start, 0x0);
241 : 3 : to_le64(&gpt->lba_end, 0x2E935FFE);
242 : 3 : to_le64(&head->first_usable_lba, 0xA);
243 : 3 : to_le64(&head->last_usable_lba, 0xF4240);
244 : 3 : re = gpt_parse_partition_table(gpt);
245 : 3 : CU_ASSERT(re == -1);
246 : :
247 : : /* Set read_partitions passed, all passed */
248 : 3 : to_le32(&head->size_of_partition_entry, 0x80);
249 : 3 : to_le64(&head->partition_entry_lba, 0x20);
250 : 3 : to_le32(&head->header_crc32, 0x845A09AA);
251 : 3 : to_le32(&head->partition_entry_array_crc32, 0xEBEE44FB);
252 : 3 : to_le32(&head->num_partition_entries, 0x80);
253 : 3 : re = gpt_parse_partition_table(gpt);
254 : 3 : CU_ASSERT(re == 0);
255 : :
256 : 3 : free(gpt);
257 : 3 : }
258 : :
259 : : static void
260 : 3 : test_parse_secondary(void)
261 : : {
262 : : struct spdk_gpt *gpt;
263 : : struct spdk_gpt_header *head;
264 : 3 : unsigned char a[SPDK_GPT_BUFFER_SIZE];
265 : : int re;
266 : :
267 : : /* gpt_parse_partition_table(NULL) does not exist, NULL is filtered out in gpt_parse_mbr() */
268 : 3 : gpt = calloc(1, sizeof(*gpt));
269 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(gpt != NULL);
270 : 3 : gpt->parse_phase = SPDK_GPT_PARSE_PHASE_SECONDARY;
271 : 3 : gpt->sector_size = 512;
272 : :
273 : : /* Set *gpt is "aaa...", read_header failed */
274 : 3 : memset(a, 'a', sizeof(a));
275 : 3 : gpt->buf = &a[0];
276 : 3 : gpt->buf_size = sizeof(a);
277 : 3 : re = gpt_parse_partition_table(gpt);
278 : 3 : CU_ASSERT(re == -1);
279 : :
280 : : /* Set read_header passed, read_partitions failed */
281 : 3 : head = (struct spdk_gpt_header *)(gpt->buf + gpt->buf_size - gpt->sector_size);
282 : 3 : head->header_size = sizeof(*head);
283 : 3 : head->gpt_signature[0] = 'E';
284 : 3 : head->gpt_signature[1] = 'F';
285 : 3 : head->gpt_signature[2] = 'I';
286 : 3 : head->gpt_signature[3] = ' ';
287 : 3 : head->gpt_signature[4] = 'P';
288 : 3 : head->gpt_signature[5] = 'A';
289 : 3 : head->gpt_signature[6] = 'R';
290 : 3 : head->gpt_signature[7] = 'T';
291 : 3 : to_le32(&head->header_crc32, 0xAA68A167);
292 : 3 : to_le64(&head->my_lba, 0x63FFFFF);
293 : 3 : to_le64(&gpt->lba_start, 0x0);
294 : 3 : to_le64(&gpt->lba_end, 0x63FFFFF);
295 : 3 : to_le64(&gpt->total_sectors, 0x6400000);
296 : 3 : to_le64(&head->first_usable_lba, 0xA);
297 : 3 : to_le64(&head->last_usable_lba, 0x63FFFDE);
298 : 3 : re = gpt_parse_partition_table(gpt);
299 : 3 : CU_ASSERT(re == -1);
300 : :
301 : : /* Set read_partitions passed, all passed */
302 : 3 : to_le32(&head->size_of_partition_entry, 0x80);
303 : 3 : to_le64(&head->partition_entry_lba, 0x63FFFDF);
304 : 3 : to_le32(&head->header_crc32, 0x204129E8);
305 : 3 : to_le32(&head->partition_entry_array_crc32, 0xEBEE44FB);
306 : 3 : to_le32(&head->num_partition_entries, 0x80);
307 : 3 : re = gpt_parse_partition_table(gpt);
308 : 3 : CU_ASSERT(re == 0);
309 : :
310 : 3 : free(gpt);
311 : 3 : }
312 : :
313 : : int
314 : 3 : main(int argc, char **argv)
315 : : {
316 : 3 : CU_pSuite suite = NULL;
317 : : unsigned int num_failures;
318 : :
319 : 3 : CU_initialize_registry();
320 : :
321 : 3 : suite = CU_add_suite("gpt_parse", NULL, NULL);
322 : :
323 : 3 : CU_ADD_TEST(suite, test_parse_mbr_and_primary);
324 : 3 : CU_ADD_TEST(suite, test_parse_secondary);
325 : 3 : CU_ADD_TEST(suite, test_check_mbr);
326 : 3 : CU_ADD_TEST(suite, test_read_header);
327 : 3 : CU_ADD_TEST(suite, test_read_partitions);
328 : :
329 : 3 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
330 : 3 : CU_cleanup_registry();
331 : 3 : return num_failures;
332 : : }
|