1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of the copyright holder nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk_cunit.h" 35 36 #include "common/lib/test_env.c" 37 38 #include "bdev/gpt/gpt.c" 39 40 static void 41 test_check_mbr(void) 42 { 43 struct spdk_gpt *gpt; 44 struct spdk_mbr *mbr; 45 unsigned char a[SPDK_GPT_BUFFER_SIZE]; 46 int re; 47 48 /* spdk_gpt_check_mbr(NULL) does not exist, NULL is filtered out in spdk_gpt_parse() */ 49 gpt = calloc(1, sizeof(*gpt)); 50 SPDK_CU_ASSERT_FATAL(gpt != NULL); 51 52 /* Set *gpt is "aaa...", all are mismatch include mbr_signature */ 53 memset(a, 'a', sizeof(a)); 54 gpt->buf = &a[0]; 55 re = spdk_gpt_check_mbr(gpt); 56 CU_ASSERT(re == -1); 57 58 /* Set mbr->mbr_signature matched, start lba mismatch */ 59 mbr = (struct spdk_mbr *)gpt->buf; 60 mbr->mbr_signature = 0xAA55; 61 re = spdk_gpt_check_mbr(gpt); 62 CU_ASSERT(re == -1); 63 64 /* Set mbr->partitions[0].start lba matched, os_type mismatch */ 65 mbr->partitions[0].start_lba = 1; 66 re = spdk_gpt_check_mbr(gpt); 67 CU_ASSERT(re == -1); 68 69 /* Set mbr->partitions[0].os_type matched, size_lba mismatch */ 70 mbr->partitions[0].os_type = 0xEE; 71 re = spdk_gpt_check_mbr(gpt); 72 CU_ASSERT(re == -1); 73 74 /* Set mbr->partitions[0].size_lba matched, passing case */ 75 mbr->partitions[0].size_lba = 0xFFFFFFFF; 76 re = spdk_gpt_check_mbr(gpt); 77 CU_ASSERT(re == 0); 78 79 free(gpt); 80 } 81 82 static void 83 test_read_header(void) 84 { 85 struct spdk_gpt *gpt; 86 struct spdk_gpt_header *head; 87 unsigned char a[SPDK_GPT_BUFFER_SIZE]; 88 int re; 89 90 /* spdk_gpt_read_header(NULL) does not exist, NULL is filtered out in spdk_gpt_parse() */ 91 gpt = calloc(1, sizeof(*gpt)); 92 SPDK_CU_ASSERT_FATAL(gpt != NULL); 93 94 /* Set *gpt is "aaa..." */ 95 memset(a, 'a', sizeof(a)); 96 gpt->buf = &a[0]; 97 98 /* Set header_size mismatch */ 99 gpt->sector_size = 512; 100 head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size); 101 to_le32(&head->header_size, 0x258); 102 re = spdk_gpt_read_header(gpt); 103 CU_ASSERT(re == -1); 104 105 /* Set head->header_size matched, header_crc32 mismatch */ 106 head->header_size = sizeof(*head); 107 to_le32(&head->header_crc32, 0x22D18C80); 108 re = spdk_gpt_read_header(gpt); 109 CU_ASSERT(re == -1); 110 111 /* Set head->header_crc32 matched, gpt_signature mismatch */ 112 to_le32(&head->header_crc32, 0xC5B2117E); 113 re = spdk_gpt_read_header(gpt); 114 CU_ASSERT(re == -1); 115 116 /* Set head->gpt_signature matched, head->my_lba mismatch */ 117 to_le32(&head->header_crc32, 0xD637335A); 118 head->gpt_signature[0] = 'E'; 119 head->gpt_signature[1] = 'F'; 120 head->gpt_signature[2] = 'I'; 121 head->gpt_signature[3] = ' '; 122 head->gpt_signature[4] = 'P'; 123 head->gpt_signature[5] = 'A'; 124 head->gpt_signature[6] = 'R'; 125 head->gpt_signature[7] = 'T'; 126 re = spdk_gpt_read_header(gpt); 127 CU_ASSERT(re == -1); 128 129 /* Set head->my_lba matched, lba_end usable_lba mismatch */ 130 to_le32(&head->header_crc32, 0xB3CDB2D2); 131 to_le64(&head->my_lba, 0x1); 132 re = spdk_gpt_read_header(gpt); 133 CU_ASSERT(re == -1); 134 135 /* Set gpt->lba_end usable_lba matched, passing case */ 136 to_le32(&head->header_crc32, 0x5531F2F0); 137 to_le64(&gpt->lba_start, 0x0); 138 to_le64(&gpt->lba_end, 0x2E935FFE); 139 to_le64(&head->first_usable_lba, 0xA); 140 to_le64(&head->last_usable_lba, 0xF4240); 141 re = spdk_gpt_read_header(gpt); 142 CU_ASSERT(re == 0); 143 144 free(gpt); 145 } 146 147 static void 148 test_read_partitions(void) 149 { 150 struct spdk_gpt *gpt; 151 struct spdk_gpt_header *head; 152 unsigned char a[SPDK_GPT_BUFFER_SIZE]; 153 int re; 154 155 /* spdk_gpt_read_partitions(NULL) does not exist, NULL is filtered out in spdk_gpt_parse() */ 156 gpt = calloc(1, sizeof(*gpt)); 157 SPDK_CU_ASSERT_FATAL(gpt != NULL); 158 159 /* Set *gpt is "aaa..." */ 160 memset(a, 'a', sizeof(a)); 161 gpt->buf = &a[0]; 162 163 /* Set num_partition_entries exceeds Max value of entries GPT supported */ 164 gpt->sector_size = 512; 165 head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size); 166 gpt->header = head; 167 to_le32(&head->num_partition_entries, 0x100); 168 re = spdk_gpt_read_partitions(gpt); 169 CU_ASSERT(re == -1); 170 171 /* Set num_partition_entries within Max value, size_of_partition_entry mismatch */ 172 to_le32(&head->header_crc32, 0x573857BE); 173 to_le32(&head->num_partition_entries, 0x40); 174 to_le32(&head->size_of_partition_entry, 0x0); 175 re = spdk_gpt_read_partitions(gpt); 176 CU_ASSERT(re == -1); 177 178 /* Set size_of_partition_entry matched, partition_entry_lba mismatch */ 179 to_le32(&head->header_crc32, 0x5279B712); 180 to_le32(&head->size_of_partition_entry, 0x80); 181 to_le64(&head->partition_entry_lba, 0x64); 182 re = spdk_gpt_read_partitions(gpt); 183 CU_ASSERT(re == -1); 184 185 /* Set partition_entry_lba matched, partition_entry_array_crc32 mismatch */ 186 to_le32(&head->header_crc32, 0xEC093B43); 187 to_le64(&head->partition_entry_lba, 0x20); 188 to_le32(&head->partition_entry_array_crc32, 0x0); 189 re = spdk_gpt_read_partitions(gpt); 190 CU_ASSERT(re == -1); 191 192 /* Set partition_entry_array_crc32 matched, passing case */ 193 to_le32(&head->header_crc32, 0xE1A08822); 194 to_le32(&head->partition_entry_array_crc32, 0xEBEE44FB); 195 to_le32(&head->num_partition_entries, 0x80); 196 re = spdk_gpt_read_partitions(gpt); 197 CU_ASSERT(re == 0); 198 199 free(gpt); 200 } 201 202 static void 203 test_parse(void) 204 { 205 struct spdk_gpt *gpt; 206 struct spdk_mbr *mbr; 207 struct spdk_gpt_header *head; 208 unsigned char a[SPDK_GPT_BUFFER_SIZE]; 209 int re; 210 211 /* Set gpt is NULL */ 212 re = spdk_gpt_parse(NULL); 213 CU_ASSERT(re == -1); 214 215 /* Set gpt->buf is NULL */ 216 gpt = calloc(1, sizeof(*gpt)); 217 SPDK_CU_ASSERT_FATAL(gpt != NULL); 218 re = spdk_gpt_parse(gpt); 219 CU_ASSERT(re == -1); 220 221 /* Set *gpt is "aaa...", check_mbr failed */ 222 memset(a, 'a', sizeof(a)); 223 gpt->buf = &a[0]; 224 re = spdk_gpt_parse(gpt); 225 CU_ASSERT(re == -1); 226 227 /* Set check_mbr passed, read_header failed */ 228 mbr = (struct spdk_mbr *)gpt->buf; 229 mbr->mbr_signature = 0xAA55; 230 mbr->partitions[0].start_lba = 1; 231 mbr->partitions[0].os_type = 0xEE; 232 mbr->partitions[0].size_lba = 0xFFFFFFFF; 233 re = spdk_gpt_parse(gpt); 234 CU_ASSERT(re == -1); 235 236 /* Set read_header passed, read_partitions failed */ 237 gpt->sector_size = 512; 238 head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size); 239 head->header_size = sizeof(*head); 240 head->gpt_signature[0] = 'E'; 241 head->gpt_signature[1] = 'F'; 242 head->gpt_signature[2] = 'I'; 243 head->gpt_signature[3] = ' '; 244 head->gpt_signature[4] = 'P'; 245 head->gpt_signature[5] = 'A'; 246 head->gpt_signature[6] = 'R'; 247 head->gpt_signature[7] = 'T'; 248 to_le32(&head->header_crc32, 0x5531F2F0); 249 to_le64(&head->my_lba, 0x1); 250 to_le64(&gpt->lba_start, 0x0); 251 to_le64(&gpt->lba_end, 0x2E935FFE); 252 to_le64(&head->first_usable_lba, 0xA); 253 to_le64(&head->last_usable_lba, 0xF4240); 254 re = spdk_gpt_parse(gpt); 255 CU_ASSERT(re == -1); 256 257 /* Set read_partitions passed, all passed */ 258 to_le32(&head->size_of_partition_entry, 0x80); 259 to_le64(&head->partition_entry_lba, 0x20); 260 to_le32(&head->header_crc32, 0x845A09AA); 261 to_le32(&head->partition_entry_array_crc32, 0xEBEE44FB); 262 to_le32(&head->num_partition_entries, 0x80); 263 re = spdk_gpt_parse(gpt); 264 CU_ASSERT(re == 0); 265 266 free(gpt); 267 } 268 269 int 270 main(int argc, char **argv) 271 { 272 CU_pSuite suite = NULL; 273 unsigned int num_failures; 274 275 if (CU_initialize_registry() != CUE_SUCCESS) { 276 return CU_get_error(); 277 } 278 279 suite = CU_add_suite("gpt_parse", NULL, NULL); 280 if (suite == NULL) { 281 CU_cleanup_registry(); 282 return CU_get_error(); 283 } 284 285 if ( 286 CU_add_test(suite, "parse", 287 test_parse) == NULL || 288 CU_add_test(suite, "check mbr", 289 test_check_mbr) == NULL || 290 CU_add_test(suite, "read header", 291 test_read_header) == NULL || 292 CU_add_test(suite, "read partitions", 293 test_read_partitions) == NULL 294 ) { 295 CU_cleanup_registry(); 296 return CU_get_error(); 297 } 298 299 CU_basic_set_mode(CU_BRM_VERBOSE); 300 CU_basic_run_tests(); 301 num_failures = CU_get_number_of_failures(); 302 CU_cleanup_registry(); 303 return num_failures; 304 } 305