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, lba_end usable_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 gpt->lba_end usable_lba matched, passing case */ 130 to_le32(&head->header_crc32, 0x30CB7378); 131 to_le64(&gpt->lba_start, 0x0); 132 to_le64(&gpt->lba_end, 0x2E935FFE); 133 to_le64(&head->first_usable_lba, 0xA); 134 to_le64(&head->last_usable_lba, 0xF4240); 135 re = spdk_gpt_read_header(gpt); 136 CU_ASSERT(re == 0); 137 138 free(gpt); 139 } 140 141 static void 142 test_read_partitions(void) 143 { 144 struct spdk_gpt *gpt; 145 struct spdk_gpt_header *head; 146 unsigned char a[SPDK_GPT_BUFFER_SIZE]; 147 int re; 148 149 /* spdk_gpt_read_partitions(NULL) does not exist, NULL is filtered out in spdk_gpt_parse() */ 150 gpt = calloc(1, sizeof(*gpt)); 151 SPDK_CU_ASSERT_FATAL(gpt != NULL); 152 153 /* Set *gpt is "aaa..." */ 154 memset(a, 'a', sizeof(a)); 155 gpt->buf = &a[0]; 156 157 /* Set num_partition_entries exceeds Max vaule of entries GPT supported */ 158 gpt->sector_size = 512; 159 head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size); 160 gpt->header = head; 161 to_le32(&head->num_partition_entries, 0x100); 162 re = spdk_gpt_read_partitions(gpt); 163 CU_ASSERT(re == -1); 164 165 /* Set num_partition_entries within Max vaule, size_of_partition_entry mismatch */ 166 to_le32(&head->header_crc32, 0x573857BE); 167 to_le32(&head->num_partition_entries, 0x40); 168 to_le32(&head->size_of_partition_entry, 0x0); 169 re = spdk_gpt_read_partitions(gpt); 170 CU_ASSERT(re == -1); 171 172 /* Set size_of_partition_entry matched, partition_entry_lba mismatch */ 173 to_le32(&head->header_crc32, 0x5279B712); 174 to_le32(&head->size_of_partition_entry, 0x80); 175 to_le64(&head->partition_entry_lba, 0x64); 176 re = spdk_gpt_read_partitions(gpt); 177 CU_ASSERT(re == -1); 178 179 /* Set partition_entry_lba matched, partition_entry_array_crc32 mismatch */ 180 to_le32(&head->header_crc32, 0xEC093B43); 181 to_le64(&head->partition_entry_lba, 0x20); 182 to_le32(&head->partition_entry_array_crc32, 0x0); 183 re = spdk_gpt_read_partitions(gpt); 184 CU_ASSERT(re == -1); 185 186 /* Set partition_entry_array_crc32 matched, passing case */ 187 to_le32(&head->header_crc32, 0xE1A08822); 188 to_le32(&head->partition_entry_array_crc32, 0xEBEE44FB); 189 to_le32(&head->num_partition_entries, 0x80); 190 re = spdk_gpt_read_partitions(gpt); 191 CU_ASSERT(re == 0); 192 193 free(gpt); 194 } 195 196 static void 197 test_parse(void) 198 { 199 struct spdk_gpt *gpt; 200 struct spdk_mbr *mbr; 201 struct spdk_gpt_header *head; 202 unsigned char a[SPDK_GPT_BUFFER_SIZE]; 203 int re; 204 205 /* Set gpt is NULL */ 206 re = spdk_gpt_parse(NULL); 207 CU_ASSERT(re == -1); 208 209 /* Set gpt->buf is NULL */ 210 gpt = calloc(1, sizeof(*gpt)); 211 SPDK_CU_ASSERT_FATAL(gpt != NULL); 212 re = spdk_gpt_parse(gpt); 213 CU_ASSERT(re == -1); 214 215 /* Set *gpt is "aaa...", check_mbr failed */ 216 memset(a, 'a', sizeof(a)); 217 gpt->buf = &a[0]; 218 re = spdk_gpt_parse(gpt); 219 CU_ASSERT(re == -1); 220 221 /* Set check_mbr passed, read_header failed */ 222 mbr = (struct spdk_mbr *)gpt->buf; 223 mbr->mbr_signature = 0xAA55; 224 mbr->partitions[0].start_lba = 1; 225 mbr->partitions[0].os_type = 0xEE; 226 mbr->partitions[0].size_lba = 0xFFFFFFFF; 227 re = spdk_gpt_parse(gpt); 228 CU_ASSERT(re == -1); 229 230 /* Set read_header passed, read_partitions failed */ 231 gpt->sector_size = 512; 232 head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size); 233 head->header_size = sizeof(*head); 234 head->gpt_signature[0] = 'E'; 235 head->gpt_signature[1] = 'F'; 236 head->gpt_signature[2] = 'I'; 237 head->gpt_signature[3] = ' '; 238 head->gpt_signature[4] = 'P'; 239 head->gpt_signature[5] = 'A'; 240 head->gpt_signature[6] = 'R'; 241 head->gpt_signature[7] = 'T'; 242 to_le32(&head->header_crc32, 0x30CB7378); 243 to_le64(&gpt->lba_start, 0x0); 244 to_le64(&gpt->lba_end, 0x2E935FFE); 245 to_le64(&head->first_usable_lba, 0xA); 246 to_le64(&head->last_usable_lba, 0xF4240); 247 re = spdk_gpt_parse(gpt); 248 CU_ASSERT(re == -1); 249 250 /* Set read_partitions passed, all passed */ 251 to_le32(&head->size_of_partition_entry, 0x80); 252 to_le64(&head->partition_entry_lba, 0x20); 253 to_le32(&head->header_crc32, 0xE1A08822); 254 to_le32(&head->partition_entry_array_crc32, 0xEBEE44FB); 255 to_le32(&head->num_partition_entries, 0x80); 256 re = spdk_gpt_parse(gpt); 257 CU_ASSERT(re == 0); 258 259 free(gpt); 260 } 261 262 int 263 main(int argc, char **argv) 264 { 265 CU_pSuite suite = NULL; 266 unsigned int num_failures; 267 268 if (CU_initialize_registry() != CUE_SUCCESS) { 269 return CU_get_error(); 270 } 271 272 suite = CU_add_suite("gpt_parse", NULL, NULL); 273 if (suite == NULL) { 274 CU_cleanup_registry(); 275 return CU_get_error(); 276 } 277 278 if ( 279 CU_add_test(suite, "parse", 280 test_parse) == NULL || 281 CU_add_test(suite, "check mbr", 282 test_check_mbr) == NULL || 283 CU_add_test(suite, "read header", 284 test_read_header) == NULL || 285 CU_add_test(suite, "read partitions", 286 test_read_partitions) == NULL 287 ) { 288 CU_cleanup_registry(); 289 return CU_get_error(); 290 } 291 292 CU_basic_set_mode(CU_BRM_VERBOSE); 293 CU_basic_run_tests(); 294 num_failures = CU_get_number_of_failures(); 295 CU_cleanup_registry(); 296 return num_failures; 297 } 298