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