OLD | NEW |
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
4 */ | 4 */ |
5 | 5 |
6 #include <string.h> | 6 #include <string.h> |
7 | 7 |
8 #include "cgptlib.h" | 8 #include "cgptlib.h" |
9 #include "cgptlib_internal.h" | 9 #include "cgptlib_internal.h" |
10 #include "cgptlib_test.h" | 10 #include "cgptlib_test.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 | 38 |
39 #define DEFAULT_SECTOR_SIZE 512 | 39 #define DEFAULT_SECTOR_SIZE 512 |
40 #define MAX_SECTOR_SIZE 4096 | 40 #define MAX_SECTOR_SIZE 4096 |
41 #define DEFAULT_DRIVE_SECTORS 467 | 41 #define DEFAULT_DRIVE_SECTORS 467 |
42 #define PARTITION_ENTRIES_SIZE TOTAL_ENTRIES_SIZE /* 16384 */ | 42 #define PARTITION_ENTRIES_SIZE TOTAL_ENTRIES_SIZE /* 16384 */ |
43 | 43 |
44 static const Guid guid_zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; | 44 static const Guid guid_zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; |
45 static const Guid guid_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL; | 45 static const Guid guid_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL; |
46 static const Guid guid_rootfs = GPT_ENT_TYPE_CHROMEOS_ROOTFS; | 46 static const Guid guid_rootfs = GPT_ENT_TYPE_CHROMEOS_ROOTFS; |
47 | 47 |
| 48 /* Copy a random-for-this-program-only Guid into the dest. The num parameter |
| 49 * completely determines the Guid. |
| 50 */ |
| 51 static void SetGuid(void *dest, uint32_t num) { |
| 52 Guid g = {{{num,0xd450,0x44bc,0xa6,0x93,{0xb8,0xac,0x75,0x5f,0xcd,0x48}}}}; |
| 53 Memcpy(dest, &g, sizeof(Guid)); |
| 54 } |
48 | 55 |
49 /* Given a GptData pointer, first re-calculate entries CRC32 value, | 56 /* Given a GptData pointer, first re-calculate entries CRC32 value, |
50 * then reset header CRC32 value to 0, and calculate header CRC32 value. | 57 * then reset header CRC32 value to 0, and calculate header CRC32 value. |
51 * Both primary and secondary are updated. */ | 58 * Both primary and secondary are updated. */ |
52 static void RefreshCrc32(GptData* gpt) { | 59 static void RefreshCrc32(GptData* gpt) { |
53 GptHeader *header, *header2; | 60 GptHeader *header, *header2; |
54 GptEntry *entries, *entries2; | 61 GptEntry *entries, *entries2; |
55 | 62 |
56 header = (GptHeader*)gpt->primary_header; | 63 header = (GptHeader*)gpt->primary_header; |
57 entries = (GptEntry*)gpt->primary_entries; | 64 entries = (GptEntry*)gpt->primary_entries; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 header->size = sizeof(GptHeader); | 147 header->size = sizeof(GptHeader); |
141 header->reserved_zero = 0; | 148 header->reserved_zero = 0; |
142 header->my_lba = 1; | 149 header->my_lba = 1; |
143 header->alternate_lba = DEFAULT_DRIVE_SECTORS - 1; | 150 header->alternate_lba = DEFAULT_DRIVE_SECTORS - 1; |
144 header->first_usable_lba = 34; | 151 header->first_usable_lba = 34; |
145 header->last_usable_lba = DEFAULT_DRIVE_SECTORS - 1 - 32 - 1; /* 433 */ | 152 header->last_usable_lba = DEFAULT_DRIVE_SECTORS - 1 - 32 - 1; /* 433 */ |
146 header->entries_lba = 2; | 153 header->entries_lba = 2; |
147 header->number_of_entries = 128; /* 512B / 128B * 32sectors = 128 entries */ | 154 header->number_of_entries = 128; /* 512B / 128B * 32sectors = 128 entries */ |
148 header->size_of_entry = 128; /* bytes */ | 155 header->size_of_entry = 128; /* bytes */ |
149 Memcpy(&entries[0].type, &chromeos_kernel, sizeof(chromeos_kernel)); | 156 Memcpy(&entries[0].type, &chromeos_kernel, sizeof(chromeos_kernel)); |
| 157 SetGuid(&entries[0].unique, 0); |
150 entries[0].starting_lba = 34; | 158 entries[0].starting_lba = 34; |
151 entries[0].ending_lba = 133; | 159 entries[0].ending_lba = 133; |
152 Memcpy(&entries[1].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); | 160 Memcpy(&entries[1].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); |
| 161 SetGuid(&entries[1].unique, 1); |
153 entries[1].starting_lba = 134; | 162 entries[1].starting_lba = 134; |
154 entries[1].ending_lba = 232; | 163 entries[1].ending_lba = 232; |
155 Memcpy(&entries[2].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); | 164 Memcpy(&entries[2].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); |
| 165 SetGuid(&entries[2].unique, 2); |
156 entries[2].starting_lba = 234; | 166 entries[2].starting_lba = 234; |
157 entries[2].ending_lba = 331; | 167 entries[2].ending_lba = 331; |
158 Memcpy(&entries[3].type, &chromeos_kernel, sizeof(chromeos_kernel)); | 168 Memcpy(&entries[3].type, &chromeos_kernel, sizeof(chromeos_kernel)); |
| 169 SetGuid(&entries[3].unique, 3); |
159 entries[3].starting_lba = 334; | 170 entries[3].starting_lba = 334; |
160 entries[3].ending_lba = 430; | 171 entries[3].ending_lba = 430; |
161 | 172 |
162 /* build secondary */ | 173 /* build secondary */ |
163 header2 = (GptHeader*)gpt->secondary_header; | 174 header2 = (GptHeader*)gpt->secondary_header; |
164 entries2 = (GptEntry*)gpt->secondary_entries; | 175 entries2 = (GptEntry*)gpt->secondary_entries; |
165 Memcpy(header2, header, sizeof(GptHeader)); | 176 Memcpy(header2, header, sizeof(GptHeader)); |
166 Memcpy(entries2, entries, PARTITION_ENTRIES_SIZE); | 177 Memcpy(entries2, entries, PARTITION_ENTRIES_SIZE); |
167 header2->my_lba = DEFAULT_DRIVE_SECTORS - 1; /* 466 */ | 178 header2->my_lba = DEFAULT_DRIVE_SECTORS - 1; /* 466 */ |
168 header2->alternate_lba = 1; | 179 header2->alternate_lba = 1; |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 | 667 |
657 for (i = 0; i < ARRAY_SIZE(cases); ++i) { | 668 for (i = 0; i < ARRAY_SIZE(cases); ++i) { |
658 BuildTestGptData(gpt); | 669 BuildTestGptData(gpt); |
659 ZeroEntries(gpt); | 670 ZeroEntries(gpt); |
660 for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) { | 671 for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) { |
661 if (!cases[i].entries[j].starting_lba) | 672 if (!cases[i].entries[j].starting_lba) |
662 break; | 673 break; |
663 | 674 |
664 if (cases[i].entries[j].active) | 675 if (cases[i].entries[j].active) |
665 Memcpy(&e[j].type, &guid_kernel, sizeof(Guid)); | 676 Memcpy(&e[j].type, &guid_kernel, sizeof(Guid)); |
| 677 SetGuid(&e[j].unique, j); |
666 e[j].starting_lba = cases[i].entries[j].starting_lba; | 678 e[j].starting_lba = cases[i].entries[j].starting_lba; |
667 e[j].ending_lba = cases[i].entries[j].ending_lba; | 679 e[j].ending_lba = cases[i].entries[j].ending_lba; |
668 } | 680 } |
669 RefreshCrc32(gpt); | 681 RefreshCrc32(gpt); |
670 | 682 |
671 EXPECT(cases[i].overlapped == CheckEntries(e, h)); | 683 EXPECT(cases[i].overlapped == CheckEntries(e, h)); |
672 } | 684 } |
673 return TEST_OK; | 685 return TEST_OK; |
674 } | 686 } |
675 | 687 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 gpt->secondary_entries[0]++; | 782 gpt->secondary_entries[0]++; |
771 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); | 783 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
772 EXPECT(MASK_BOTH == gpt->valid_headers); | 784 EXPECT(MASK_BOTH == gpt->valid_headers); |
773 EXPECT(MASK_PRIMARY == gpt->valid_entries); | 785 EXPECT(MASK_PRIMARY == gpt->valid_entries); |
774 GptRepair(gpt); | 786 GptRepair(gpt); |
775 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); | 787 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
776 EXPECT(MASK_BOTH == gpt->valid_headers); | 788 EXPECT(MASK_BOTH == gpt->valid_headers); |
777 EXPECT(MASK_BOTH == gpt->valid_entries); | 789 EXPECT(MASK_BOTH == gpt->valid_entries); |
778 EXPECT(GPT_MODIFIED_ENTRIES2 == gpt->modified); | 790 EXPECT(GPT_MODIFIED_ENTRIES2 == gpt->modified); |
779 | 791 |
| 792 /* Modify both header and entries */ |
| 793 BuildTestGptData(gpt); |
| 794 gpt->primary_header[0]++; |
| 795 gpt->primary_entries[0]++; |
| 796 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 797 EXPECT(MASK_SECONDARY == gpt->valid_headers); |
| 798 EXPECT(MASK_SECONDARY == gpt->valid_entries); |
| 799 GptRepair(gpt); |
| 800 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 801 EXPECT(MASK_BOTH == gpt->valid_headers); |
| 802 EXPECT(MASK_BOTH == gpt->valid_entries); |
| 803 EXPECT((GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1) == gpt->modified); |
| 804 |
| 805 BuildTestGptData(gpt); |
| 806 gpt->secondary_header[0]++; |
| 807 gpt->secondary_entries[0]++; |
| 808 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 809 EXPECT(MASK_PRIMARY == gpt->valid_headers); |
| 810 EXPECT(MASK_PRIMARY == gpt->valid_entries); |
| 811 GptRepair(gpt); |
| 812 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 813 EXPECT(MASK_BOTH == gpt->valid_headers); |
| 814 EXPECT(MASK_BOTH == gpt->valid_entries); |
| 815 EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2) == gpt->modified); |
| 816 |
780 /* Test cross-correction (h1+e2, h2+e1) */ | 817 /* Test cross-correction (h1+e2, h2+e1) */ |
781 BuildTestGptData(gpt); | 818 BuildTestGptData(gpt); |
782 gpt->primary_header[0]++; | 819 gpt->primary_header[0]++; |
783 gpt->secondary_entries[0]++; | 820 gpt->secondary_entries[0]++; |
784 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); | 821 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
785 EXPECT(MASK_SECONDARY == gpt->valid_headers); | 822 EXPECT(MASK_SECONDARY == gpt->valid_headers); |
786 EXPECT(MASK_PRIMARY == gpt->valid_entries); | 823 EXPECT(MASK_PRIMARY == gpt->valid_entries); |
787 GptRepair(gpt); | 824 GptRepair(gpt); |
788 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); | 825 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
789 EXPECT(MASK_BOTH == gpt->valid_headers); | 826 EXPECT(MASK_BOTH == gpt->valid_headers); |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1085 GptData* gpt = GetEmptyGptData(); | 1122 GptData* gpt = GetEmptyGptData(); |
1086 | 1123 |
1087 BuildTestGptData(gpt); | 1124 BuildTestGptData(gpt); |
1088 gpt->current_kernel = 0; /* anything, but not CGPT_KERNEL_ENTRY_NOT_FOUND */ | 1125 gpt->current_kernel = 0; /* anything, but not CGPT_KERNEL_ENTRY_NOT_FOUND */ |
1089 EXPECT(GPT_ERROR_INVALID_UPDATE_TYPE == | 1126 EXPECT(GPT_ERROR_INVALID_UPDATE_TYPE == |
1090 GptUpdateKernelEntry(gpt, 99)); /* any invalid update_type value */ | 1127 GptUpdateKernelEntry(gpt, 99)); /* any invalid update_type value */ |
1091 | 1128 |
1092 return TEST_OK; | 1129 return TEST_OK; |
1093 } | 1130 } |
1094 | 1131 |
| 1132 |
| 1133 /* Tests duplicate UniqueGuids can be detected. */ |
| 1134 static int DuplicateUniqueGuidTest() { |
| 1135 GptData* gpt = GetEmptyGptData(); |
| 1136 GptHeader* h = (GptHeader*)gpt->primary_header; |
| 1137 GptEntry* e = (GptEntry*)gpt->primary_entries; |
| 1138 int i, j; |
| 1139 |
| 1140 struct { |
| 1141 int duplicate; |
| 1142 struct { |
| 1143 uint64_t starting_lba; |
| 1144 uint64_t ending_lba; |
| 1145 uint32_t type_guid; |
| 1146 uint32_t unique_guid; |
| 1147 } entries[16]; /* enough for testing. */ |
| 1148 } cases[] = { |
| 1149 {0, {{100, 109, 1, 1}, |
| 1150 {110, 119, 2, 2}, |
| 1151 {120, 129, 3, 3}, |
| 1152 {130, 139, 4, 4}, |
| 1153 }}, |
| 1154 {0, {{100, 109, 1, 1}, |
| 1155 {110, 119, 1, 2}, |
| 1156 {120, 129, 2, 3}, |
| 1157 {130, 139, 2, 4}, |
| 1158 }}, |
| 1159 {1, {{100, 109, 1, 1}, |
| 1160 {110, 119, 2, 2}, |
| 1161 {120, 129, 3, 1}, |
| 1162 {130, 139, 4, 4}, |
| 1163 }}, |
| 1164 {1, {{100, 109, 1, 1}, |
| 1165 {110, 119, 1, 2}, |
| 1166 {120, 129, 2, 3}, |
| 1167 {130, 139, 2, 2}, |
| 1168 }}, |
| 1169 }; |
| 1170 |
| 1171 for (i = 0; i < ARRAY_SIZE(cases); ++i) { |
| 1172 BuildTestGptData(gpt); |
| 1173 ZeroEntries(gpt); |
| 1174 for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) { |
| 1175 if (!cases[i].entries[j].starting_lba) |
| 1176 break; |
| 1177 |
| 1178 e[j].starting_lba = cases[i].entries[j].starting_lba; |
| 1179 e[j].ending_lba = cases[i].entries[j].ending_lba; |
| 1180 SetGuid(&e[j].type, cases[i].entries[j].type_guid); |
| 1181 SetGuid(&e[j].unique, cases[i].entries[j].unique_guid); |
| 1182 } |
| 1183 RefreshCrc32(gpt); |
| 1184 |
| 1185 EXPECT(cases[i].duplicate == CheckEntries(e, h)); |
| 1186 } |
| 1187 return TEST_OK; |
| 1188 } |
| 1189 |
| 1190 |
| 1191 |
1095 /* disable MSVC warnings on unused arguments */ | 1192 /* disable MSVC warnings on unused arguments */ |
1096 __pragma(warning (disable: 4100)) | 1193 __pragma(warning (disable: 4100)) |
1097 | 1194 |
1098 int main(int argc, char *argv[]) { | 1195 int main(int argc, char *argv[]) { |
1099 int i; | 1196 int i; |
1100 int error_count = 0; | 1197 int error_count = 0; |
1101 struct { | 1198 struct { |
1102 char *name; | 1199 char *name; |
1103 test_func fp; | 1200 test_func fp; |
1104 int retval; | 1201 int retval; |
(...skipping 16 matching lines...) Expand all Loading... |
1121 { TEST_CASE(OverlappedPartitionTest), }, | 1218 { TEST_CASE(OverlappedPartitionTest), }, |
1122 { TEST_CASE(SanityCheckTest), }, | 1219 { TEST_CASE(SanityCheckTest), }, |
1123 { TEST_CASE(NoValidKernelEntryTest), }, | 1220 { TEST_CASE(NoValidKernelEntryTest), }, |
1124 { TEST_CASE(EntryAttributeGetSetTest), }, | 1221 { TEST_CASE(EntryAttributeGetSetTest), }, |
1125 { TEST_CASE(EntryTypeTest), }, | 1222 { TEST_CASE(EntryTypeTest), }, |
1126 { TEST_CASE(GetNextNormalTest), }, | 1223 { TEST_CASE(GetNextNormalTest), }, |
1127 { TEST_CASE(GetNextPrioTest), }, | 1224 { TEST_CASE(GetNextPrioTest), }, |
1128 { TEST_CASE(GetNextTriesTest), }, | 1225 { TEST_CASE(GetNextTriesTest), }, |
1129 { TEST_CASE(GptUpdateTest), }, | 1226 { TEST_CASE(GptUpdateTest), }, |
1130 { TEST_CASE(UpdateInvalidKernelTypeTest), }, | 1227 { TEST_CASE(UpdateInvalidKernelTypeTest), }, |
| 1228 { TEST_CASE(DuplicateUniqueGuidTest), }, |
1131 { TEST_CASE(TestCrc32TestVectors), }, | 1229 { TEST_CASE(TestCrc32TestVectors), }, |
1132 }; | 1230 }; |
1133 | 1231 |
1134 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { | 1232 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { |
1135 printf("Running %s() ...\n", test_cases[i].name); | 1233 printf("Running %s() ...\n", test_cases[i].name); |
1136 test_cases[i].retval = test_cases[i].fp(); | 1234 test_cases[i].retval = test_cases[i].fp(); |
1137 if (test_cases[i].retval) { | 1235 if (test_cases[i].retval) { |
1138 printf(COL_RED "[ERROR]\n\n" COL_STOP); | 1236 printf(COL_RED "[ERROR]\n\n" COL_STOP); |
1139 ++error_count; | 1237 ++error_count; |
1140 } else { | 1238 } else { |
1141 printf(COL_GREEN "[PASS]\n\n" COL_STOP); | 1239 printf(COL_GREEN "[PASS]\n\n" COL_STOP); |
1142 } | 1240 } |
1143 } | 1241 } |
1144 | 1242 |
1145 if (error_count) { | 1243 if (error_count) { |
1146 printf("\n--------------------------------------------------\n"); | 1244 printf("\n--------------------------------------------------\n"); |
1147 printf(COL_RED "The following %d test cases are failed:\n" COL_STOP, | 1245 printf(COL_RED "The following %d test cases are failed:\n" COL_STOP, |
1148 error_count); | 1246 error_count); |
1149 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { | 1247 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { |
1150 if (test_cases[i].retval) | 1248 if (test_cases[i].retval) |
1151 printf(" %s()\n", test_cases[i].name); | 1249 printf(" %s()\n", test_cases[i].name); |
1152 } | 1250 } |
1153 } | 1251 } |
1154 | 1252 |
1155 return (error_count) ? 1 : 0; | 1253 return (error_count) ? 1 : 0; |
1156 } | 1254 } |
OLD | NEW |