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