summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgpt/cgpt_common.c61
-rw-r--r--cgpt/cgpt_show.c140
-rw-r--r--firmware/include/gpt.h3
-rw-r--r--firmware/include/gpt_misc.h2
-rw-r--r--firmware/lib/cgptlib/cgptlib_internal.c16
-rw-r--r--firmware/lib/gpt_misc.c66
-rw-r--r--tests/cgptlib_test.c85
7 files changed, 249 insertions, 124 deletions
diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c
index 2c21cdc2..29fe524a 100644
--- a/cgpt/cgpt_common.c
+++ b/cgpt/cgpt_common.c
@@ -184,7 +184,11 @@ static int GptLoad(struct drive *drive, uint32_t sector_bytes) {
return -1;
}
} else {
- Warning("Primary GPT header is invalid\n");
+ Warning("Primary GPT header is %s\n",
+ memcmp(primary_header->signature, GPT_HEADER_SIGNATURE_IGNORED,
+ GPT_HEADER_SIGNATURE_SIZE) ? "invalid" : "being ignored");
+ drive->gpt.primary_entries = calloc(MAX_NUMBER_OF_ENTRIES,
+ sizeof(GptEntry));
}
GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header;
if (CheckHeader(secondary_header, 1, drive->gpt.streaming_drive_sectors,
@@ -198,41 +202,48 @@ static int GptLoad(struct drive *drive, uint32_t sector_bytes) {
return -1;
}
} else {
- Warning("Secondary GPT header is invalid\n");
+ Warning("Secondary GPT header is %s\n",
+ memcmp(primary_header->signature, GPT_HEADER_SIGNATURE_IGNORED,
+ GPT_HEADER_SIGNATURE_SIZE) ? "invalid" : "being ignored");
+ drive->gpt.secondary_entries = calloc(MAX_NUMBER_OF_ENTRIES,
+ sizeof(GptEntry));
}
return 0;
}
static int GptSave(struct drive *drive) {
int errors = 0;
- if (drive->gpt.modified & GPT_MODIFIED_HEADER1) {
- if (CGPT_OK != Save(drive, drive->gpt.primary_header,
- GPT_PMBR_SECTORS,
- drive->gpt.sector_bytes, GPT_HEADER_SECTORS)) {
- errors++;
- Error("Cannot write primary header: %s\n", strerror(errno));
+
+ if (!(drive->gpt.ignored & MASK_PRIMARY)) {
+ if (drive->gpt.modified & GPT_MODIFIED_HEADER1) {
+ if (CGPT_OK != Save(drive, drive->gpt.primary_header,
+ GPT_PMBR_SECTORS,
+ drive->gpt.sector_bytes, GPT_HEADER_SECTORS)) {
+ errors++;
+ Error("Cannot write primary header: %s\n", strerror(errno));
+ }
}
- }
- GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header;
- if (drive->gpt.modified & GPT_MODIFIED_ENTRIES1) {
- if (CGPT_OK != Save(drive, drive->gpt.primary_entries,
- primary_header->entries_lba,
- drive->gpt.sector_bytes,
- CalculateEntriesSectors(primary_header))) {
- errors++;
- Error("Cannot write primary entries: %s\n", strerror(errno));
+ GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header;
+ if (drive->gpt.modified & GPT_MODIFIED_ENTRIES1) {
+ if (CGPT_OK != Save(drive, drive->gpt.primary_entries,
+ primary_header->entries_lba,
+ drive->gpt.sector_bytes,
+ CalculateEntriesSectors(primary_header))) {
+ errors++;
+ Error("Cannot write primary entries: %s\n", strerror(errno));
+ }
}
- }
- // Sync primary GPT before touching secondary so one is always valid.
- if (drive->gpt.modified & (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1))
- if (fsync(drive->fd) < 0 && errno == EIO) {
- errors++;
- Error("I/O error when trying to write primary GPT\n");
- }
+ // Sync primary GPT before touching secondary so one is always valid.
+ if (drive->gpt.modified & (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1))
+ if (fsync(drive->fd) < 0 && errno == EIO) {
+ errors++;
+ Error("I/O error when trying to write primary GPT\n");
+ }
+ }
// Only start writing secondary GPT if primary was written correctly.
- if (!errors) {
+ if (!errors && !(drive->gpt.ignored & MASK_SECONDARY)) {
if (drive->gpt.modified & GPT_MODIFIED_HEADER2) {
if(CGPT_OK != Save(drive, drive->gpt.secondary_header,
drive->gpt.gpt_drive_sectors - GPT_PMBR_SECTORS,
diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c
index 143b5fa1..638655bd 100644
--- a/cgpt/cgpt_show.c
+++ b/cgpt/cgpt_show.c
@@ -250,79 +250,91 @@ static int GptShow(struct drive *drive, CgptShowParams *params) {
PMBRToStr(&drive->pmbr, buf, sizeof(buf)); // will exit if buf is too small
printf(GPT_FMT, 0, GPT_PMBR_SECTORS, "", buf);
- if (drive->gpt.valid_headers & MASK_PRIMARY) {
+ if (drive->gpt.ignored & MASK_PRIMARY) {
printf(GPT_FMT, (int)GPT_PMBR_SECTORS,
- (int)GPT_HEADER_SECTORS, "", "Pri GPT header");
+ (int)GPT_HEADER_SECTORS, "IGNORED", "Pri GPT header");
} else {
- printf(GPT_FMT, (int)GPT_PMBR_SECTORS,
- (int)GPT_HEADER_SECTORS, "INVALID", "Pri GPT header");
- }
-
- if (params->debug ||
- ((drive->gpt.valid_headers & MASK_PRIMARY) && params->verbose)) {
- GptHeader *header;
- char indent[64];
+ if (drive->gpt.valid_headers & MASK_PRIMARY) {
+ printf(GPT_FMT, (int)GPT_PMBR_SECTORS,
+ (int)GPT_HEADER_SECTORS, "", "Pri GPT header");
+ } else {
+ printf(GPT_FMT, (int)GPT_PMBR_SECTORS,
+ (int)GPT_HEADER_SECTORS, "INVALID", "Pri GPT header");
+ }
- require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
- header = (GptHeader*)drive->gpt.primary_header;
- entries = (GptEntry*)drive->gpt.primary_entries;
- HeaderDetails(header, entries, indent, params->numeric);
- }
+ if (params->debug ||
+ ((drive->gpt.valid_headers & MASK_PRIMARY) && params->verbose)) {
+ GptHeader *header;
+ char indent[64];
- GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header;
- printf(GPT_FMT, (int)primary_header->entries_lba,
- (int)CalculateEntriesSectors(primary_header),
- drive->gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID",
- "Pri GPT table");
+ require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
+ header = (GptHeader*)drive->gpt.primary_header;
+ entries = (GptEntry*)drive->gpt.primary_entries;
+ HeaderDetails(header, entries, indent, params->numeric);
+ }
- if (params->debug ||
- (drive->gpt.valid_entries & MASK_PRIMARY))
- EntriesDetails(drive, PRIMARY, params->numeric);
+ GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header;
+ printf(GPT_FMT, (int)primary_header->entries_lba,
+ (int)CalculateEntriesSectors(primary_header),
+ drive->gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID",
+ "Pri GPT table");
- /****************************** Secondary *************************/
- GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header;
- printf(GPT_FMT, (int)secondary_header->entries_lba,
- (int)CalculateEntriesSectors(secondary_header),
- drive->gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID",
- "Sec GPT table");
- /* We show secondary table details if any of following is true.
- * 1. in debug mode.
- * 2. only secondary is valid.
- * 3. secondary is not identical to promary.
- */
- if (params->debug ||
- ((drive->gpt.valid_entries & MASK_SECONDARY) &&
- (!(drive->gpt.valid_entries & MASK_PRIMARY) ||
- memcmp(drive->gpt.primary_entries, drive->gpt.secondary_entries,
- secondary_header->number_of_entries *
- secondary_header->size_of_entry)))) {
- EntriesDetails(drive, SECONDARY, params->numeric);
+ if (params->debug ||
+ (drive->gpt.valid_entries & MASK_PRIMARY))
+ EntriesDetails(drive, PRIMARY, params->numeric);
}
- if (drive->gpt.valid_headers & MASK_SECONDARY)
+ /****************************** Secondary *************************/
+ if (drive->gpt.ignored & MASK_SECONDARY) {
printf(GPT_FMT, (int)(drive->gpt.gpt_drive_sectors - GPT_HEADER_SECTORS),
- (int)GPT_HEADER_SECTORS, "", "Sec GPT header");
- else
- printf(GPT_FMT, (int)GPT_PMBR_SECTORS,
- (int)GPT_HEADER_SECTORS, "INVALID", "Sec GPT header");
- /* We show secondary header if any of following is true:
- * 1. in debug mode.
- * 2. only secondary is valid.
- * 3. secondary is not synonymous to primary.
- */
- if (params->debug ||
- ((drive->gpt.valid_headers & MASK_SECONDARY) &&
- (!(drive->gpt.valid_headers & MASK_PRIMARY) ||
- !IsSynonymous((GptHeader*)drive->gpt.primary_header,
- (GptHeader*)drive->gpt.secondary_header)) &&
- params->verbose)) {
- GptHeader *header;
- char indent[64];
-
- require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
- header = (GptHeader*)drive->gpt.secondary_header;
- entries = (GptEntry*)drive->gpt.secondary_entries;
- HeaderDetails(header, entries, indent, params->numeric);
+ (int)GPT_HEADER_SECTORS, "IGNORED", "Sec GPT header");
+ } else {
+ GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header;
+ printf(GPT_FMT, (int)secondary_header->entries_lba,
+ (int)CalculateEntriesSectors(secondary_header),
+ drive->gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID",
+ "Sec GPT table");
+ /* We show secondary table details if any of following is true.
+ * 1. in debug mode.
+ * 2. primary table is being ignored
+ * 3. only secondary is valid.
+ * 4. secondary is not identical to promary.
+ */
+ if (params->debug || (drive->gpt.ignored & MASK_PRIMARY) ||
+ ((drive->gpt.valid_entries & MASK_SECONDARY) &&
+ (!(drive->gpt.valid_entries & MASK_PRIMARY) ||
+ memcmp(drive->gpt.primary_entries, drive->gpt.secondary_entries,
+ secondary_header->number_of_entries *
+ secondary_header->size_of_entry)))) {
+ EntriesDetails(drive, SECONDARY, params->numeric);
+ }
+
+ if (drive->gpt.valid_headers & MASK_SECONDARY) {
+ printf(GPT_FMT, (int)(drive->gpt.gpt_drive_sectors - GPT_HEADER_SECTORS),
+ (int)GPT_HEADER_SECTORS, "", "Sec GPT header");
+ } else {
+ printf(GPT_FMT, (int)GPT_PMBR_SECTORS,
+ (int)GPT_HEADER_SECTORS, "INVALID", "Sec GPT header");
+ }
+ /* We show secondary header if any of following is true:
+ * 1. in debug mode.
+ * 2. only secondary is valid.
+ * 3. secondary is not synonymous to primary and not ignored.
+ */
+ if (params->debug ||
+ ((drive->gpt.valid_headers & MASK_SECONDARY) &&
+ (!(drive->gpt.valid_headers & MASK_PRIMARY) ||
+ !IsSynonymous((GptHeader*)drive->gpt.primary_header,
+ (GptHeader*)drive->gpt.secondary_header)) &&
+ params->verbose)) {
+ GptHeader *header;
+ char indent[64];
+
+ require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
+ header = (GptHeader*)drive->gpt.secondary_header;
+ entries = (GptEntry*)drive->gpt.secondary_entries;
+ HeaderDetails(header, entries, indent, params->numeric);
+ }
}
}
diff --git a/firmware/include/gpt.h b/firmware/include/gpt.h
index ed8bfce7..275b3ae8 100644
--- a/firmware/include/gpt.h
+++ b/firmware/include/gpt.h
@@ -19,6 +19,9 @@
/* From https://chromium-review.googlesource.com/31264 */
#define GPT_HEADER_SIGNATURE2 "CHROMEOS"
+/* From http://crosbug.com/p/52595 */
+#define GPT_HEADER_SIGNATURE_IGNORED "IGNOREME"
+
/*
* The first 3 numbers should be stored in network-endian format according to
* the GUID RFC. The UEFI spec appendix A claims they should be stored in
diff --git a/firmware/include/gpt_misc.h b/firmware/include/gpt_misc.h
index 9f442c49..0ecbba4b 100644
--- a/firmware/include/gpt_misc.h
+++ b/firmware/include/gpt_misc.h
@@ -108,7 +108,7 @@ typedef struct {
int current_kernel;
/* Internal variables */
- uint32_t valid_headers, valid_entries;
+ uint8_t valid_headers, valid_entries, ignored;
int current_priority;
} GptData;
diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c
index 29756308..7d402dfb 100644
--- a/firmware/lib/cgptlib/cgptlib_internal.c
+++ b/firmware/lib/cgptlib/cgptlib_internal.c
@@ -245,6 +245,7 @@ int GptSanityCheck(GptData *gpt)
gpt->valid_headers = 0;
gpt->valid_entries = 0;
+ gpt->ignored = 0;
retval = CheckParameters(gpt);
if (retval != GPT_SUCCESS)
@@ -255,12 +256,18 @@ int GptSanityCheck(GptData *gpt)
gpt->gpt_drive_sectors, gpt->flags)) {
gpt->valid_headers |= MASK_PRIMARY;
goodhdr = header1;
+ } else if (header1 && !Memcmp(header1->signature,
+ GPT_HEADER_SIGNATURE_IGNORED, GPT_HEADER_SIGNATURE_SIZE)) {
+ gpt->ignored |= MASK_PRIMARY;
}
if (0 == CheckHeader(header2, 1, gpt->streaming_drive_sectors,
gpt->gpt_drive_sectors, gpt->flags)) {
gpt->valid_headers |= MASK_SECONDARY;
if (!goodhdr)
goodhdr = header2;
+ } else if (header2 && !Memcmp(header2->signature,
+ GPT_HEADER_SIGNATURE_IGNORED, GPT_HEADER_SIGNATURE_SIZE)) {
+ gpt->ignored |= MASK_SECONDARY;
}
if (!gpt->valid_headers)
@@ -309,6 +316,15 @@ int GptSanityCheck(GptData *gpt)
0 != HeaderFieldsSame(header1, header2))
gpt->valid_headers &= ~MASK_SECONDARY;
+ /*
+ * When we're ignoring a GPT, make it look in memory like the other one
+ * and pretend that everything is fine (until we try to save).
+ */
+ if (MASK_NONE != gpt->ignored) {
+ GptRepair(gpt);
+ gpt->modified = 0;
+ }
+
return GPT_SUCCESS;
}
diff --git a/firmware/lib/gpt_misc.c b/firmware/lib/gpt_misc.c
index cff9221f..0bf09401 100644
--- a/firmware/lib/gpt_misc.c
+++ b/firmware/lib/gpt_misc.c
@@ -28,6 +28,8 @@ int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
/* No data to be written yet */
gptdata->modified = 0;
+ /* This should get overwritten by GptInit() */
+ gptdata->ignored = 0;
/* Allocate all buffers */
gptdata->primary_header = (uint8_t *)VbExMalloc(gptdata->sector_bytes);
@@ -67,7 +69,11 @@ int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
primary_valid = 0;
}
} else {
- VBDEBUG(("Primary GPT header invalid!\n"));
+ VBDEBUG(("Primary GPT header is %s\n",
+ Memcmp(primary_header->signature,
+ GPT_HEADER_SIGNATURE_IGNORED,
+ GPT_HEADER_SIGNATURE_SIZE)
+ ? "invalid" : "being ignored"));
}
/* Read secondary header from the end of the drive */
@@ -96,7 +102,11 @@ int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
secondary_valid = 0;
}
} else {
- VBDEBUG(("Secondary GPT header invalid!\n"));
+ VBDEBUG(("Secondary GPT header is %s\n",
+ Memcmp(secondary_header->signature,
+ GPT_HEADER_SIGNATURE_IGNORED,
+ GPT_HEADER_SIGNATURE_SIZE)
+ ? "invalid" : "being ignored"));
}
/* Return 0 if least one GPT header was valid */
@@ -110,7 +120,7 @@ int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
*/
int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
{
- int legacy = 0;
+ int skip_primary = 0;
GptHeader *header = (GptHeader *)gptdata->primary_header;
uint64_t entries_bytes = header->number_of_entries
* header->size_of_entry;
@@ -126,19 +136,16 @@ int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
GptHeader *h = (GptHeader *)(gptdata->primary_header);
entries_lba = h->entries_lba;
- /*
- * Avoid even looking at this data if we don't need to. We
- * may in fact not have read it from disk if the read failed,
- * and this avoids a valgrind complaint.
- */
- if (gptdata->modified) {
- legacy = !Memcmp(h->signature, GPT_HEADER_SIGNATURE2,
- GPT_HEADER_SIGNATURE_SIZE);
- }
- if (gptdata->modified & GPT_MODIFIED_HEADER1) {
- if (legacy) {
- VBDEBUG(("Not updating GPT header 1: "
+ if (gptdata->ignored & MASK_PRIMARY) {
+ VBDEBUG(("Not updating primary GPT: "
+ "marked to be ignored.\n"));
+ skip_primary = 1;
+ } else if (gptdata->modified & GPT_MODIFIED_HEADER1) {
+ if (!Memcmp(h->signature, GPT_HEADER_SIGNATURE2,
+ GPT_HEADER_SIGNATURE_SIZE)) {
+ VBDEBUG(("Not updating primary GPT: "
"legacy mode is enabled.\n"));
+ skip_primary = 1;
} else {
VBDEBUG(("Updating GPT header 1\n"));
if (0 != VbExDiskWrite(disk_handle, 1, 1,
@@ -148,28 +155,23 @@ int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
}
}
- if (gptdata->primary_entries) {
+ if (gptdata->primary_entries && !skip_primary) {
if (gptdata->modified & GPT_MODIFIED_ENTRIES1) {
- if (legacy) {
- VBDEBUG(("Not updating GPT entries 1: "
- "legacy mode is enabled.\n"));
- } else {
- VBDEBUG(("Updating GPT entries 1\n"));
- if (0 != VbExDiskWrite(disk_handle, entries_lba,
- entries_sectors,
- gptdata->primary_entries))
- goto fail;
- }
+ VBDEBUG(("Updating GPT entries 1\n"));
+ if (0 != VbExDiskWrite(disk_handle, entries_lba,
+ entries_sectors,
+ gptdata->primary_entries))
+ goto fail;
}
}
entries_lba = (gptdata->gpt_drive_sectors - entries_sectors -
GPT_HEADER_SECTORS);
- if (gptdata->secondary_header) {
+ if (gptdata->secondary_header && !(gptdata->ignored & MASK_SECONDARY)) {
GptHeader *h = (GptHeader *)(gptdata->secondary_header);
entries_lba = h->entries_lba;
if (gptdata->modified & GPT_MODIFIED_HEADER2) {
- VBDEBUG(("Updating GPT entries 2\n"));
+ VBDEBUG(("Updating GPT header 2\n"));
if (0 != VbExDiskWrite(disk_handle,
gptdata->gpt_drive_sectors - 1, 1,
gptdata->secondary_header))
@@ -177,12 +179,12 @@ int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
}
}
- if (gptdata->secondary_entries) {
+ if (gptdata->secondary_entries && !(gptdata->ignored & MASK_SECONDARY)){
if (gptdata->modified & GPT_MODIFIED_ENTRIES2) {
- VBDEBUG(("Updating GPT header 2\n"));
+ VBDEBUG(("Updating GPT entries 2\n"));
if (0 != VbExDiskWrite(disk_handle,
- entries_lba, entries_sectors,
- gptdata->secondary_entries))
+ entries_lba, entries_sectors,
+ gptdata->secondary_entries))
goto fail;
}
}
diff --git a/tests/cgptlib_test.c b/tests/cgptlib_test.c
index 61747522..1e8df252 100644
--- a/tests/cgptlib_test.c
+++ b/tests/cgptlib_test.c
@@ -827,6 +827,7 @@ static int SanityCheckTest(void)
{
GptData *gpt = GetEmptyGptData();
GptHeader *h1 = (GptHeader *)gpt->primary_header;
+ GptHeader *h2 = (GptHeader *)gpt->secondary_header;
GptEntry *e1 = (GptEntry *)gpt->primary_entries;
uint8_t *tempptr;
@@ -835,11 +836,13 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(MASK_NONE == gpt->ignored);
/* Repair doesn't damage it */
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT(0 == gpt->modified);
/* Invalid sector size should fail */
@@ -854,11 +857,13 @@ static int SanityCheckTest(void)
EXPECT(GPT_ERROR_INVALID_HEADERS == GptSanityCheck(gpt));
EXPECT(0 == gpt->valid_headers);
EXPECT(0 == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
/* Repair can't fix completely busted headers */
GptRepair(gpt);
EXPECT(GPT_ERROR_INVALID_HEADERS == GptSanityCheck(gpt));
EXPECT(0 == gpt->valid_headers);
EXPECT(0 == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT(0 == gpt->modified);
BuildTestGptData(gpt);
@@ -866,10 +871,12 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_SECONDARY == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT(GPT_MODIFIED_HEADER1 == gpt->modified);
BuildTestGptData(gpt);
@@ -877,10 +884,12 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_PRIMARY == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT(GPT_MODIFIED_HEADER2 == gpt->modified);
/*
@@ -893,10 +902,12 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_PRIMARY == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT(GPT_MODIFIED_HEADER2 == gpt->modified);
/* Modify entries */
@@ -906,11 +917,13 @@ static int SanityCheckTest(void)
EXPECT(GPT_ERROR_INVALID_ENTRIES == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_NONE == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
/* Repair can't fix both copies of entries being bad, either. */
GptRepair(gpt);
EXPECT(GPT_ERROR_INVALID_ENTRIES == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_NONE == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT(0 == gpt->modified);
BuildTestGptData(gpt);
@@ -918,10 +931,12 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_SECONDARY == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT(GPT_MODIFIED_ENTRIES1 == gpt->modified);
BuildTestGptData(gpt);
@@ -929,10 +944,12 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_PRIMARY == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT(GPT_MODIFIED_ENTRIES2 == gpt->modified);
/*
@@ -949,6 +966,7 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_SECONDARY == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
gpt->primary_entries = tempptr;
/* Modify both header and entries */
@@ -958,10 +976,12 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_SECONDARY == gpt->valid_headers);
EXPECT(MASK_SECONDARY == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT((GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1) == gpt->modified);
BuildTestGptData(gpt);
@@ -970,10 +990,12 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_PRIMARY == gpt->valid_headers);
EXPECT(MASK_PRIMARY == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2) == gpt->modified);
/* Test cross-correction (h1+e2, h2+e1) */
@@ -983,10 +1005,12 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_SECONDARY == gpt->valid_headers);
EXPECT(MASK_PRIMARY == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT((GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES2) == gpt->modified);
BuildTestGptData(gpt);
@@ -995,10 +1019,12 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_PRIMARY == gpt->valid_headers);
EXPECT(MASK_SECONDARY == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES1) == gpt->modified);
/*
@@ -1011,35 +1037,90 @@ static int SanityCheckTest(void)
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_PRIMARY == gpt->valid_headers);
EXPECT(MASK_PRIMARY == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
GptRepair(gpt);
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_BOTH == gpt->valid_headers);
EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2) == gpt->modified);
/* Test unloaded entry array. */
- gpt = GetEmptyGptData();
BuildTestGptData(gpt);
gpt->primary_entries = NULL;
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_SECONDARY == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
gpt = GetEmptyGptData();
BuildTestGptData(gpt);
gpt->secondary_entries = NULL;
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_PRIMARY == gpt->valid_entries);
+ EXPECT(0 == gpt->ignored);
+ gpt = GetEmptyGptData();
/* Test unloaded header. */
- gpt = GetEmptyGptData();
BuildTestGptData(gpt);
gpt->primary_header = NULL;
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_SECONDARY == gpt->valid_headers);
+ EXPECT(0 == gpt->ignored);
gpt = GetEmptyGptData();
BuildTestGptData(gpt);
gpt->secondary_header = NULL;
EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
EXPECT(MASK_PRIMARY == gpt->valid_headers);
+ EXPECT(0 == gpt->ignored);
+ gpt = GetEmptyGptData();
+
+ /* Test correct recognition of IGNOREME in primary GPT. */
+ BuildTestGptData(gpt);
+ Memset(gpt->primary_entries, 0, PARTITION_ENTRIES_SIZE);
+ Memset(gpt->primary_header, 0, sizeof(GptHeader));
+ Memcpy(h1->signature, GPT_HEADER_SIGNATURE_IGNORED,
+ GPT_HEADER_SIGNATURE_SIZE);
+ EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
+ EXPECT(MASK_BOTH == gpt->valid_headers);
+ EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(MASK_PRIMARY == gpt->ignored);
+ EXPECT(0 == gpt->modified);
+
+ /* Test correct recognition of IGNOREME in secondary GPT. */
+ BuildTestGptData(gpt);
+ Memset(gpt->secondary_entries, 0, PARTITION_ENTRIES_SIZE);
+ Memset(gpt->secondary_header, 0, sizeof(GptHeader));
+ Memcpy(h2->signature, GPT_HEADER_SIGNATURE_IGNORED,
+ GPT_HEADER_SIGNATURE_SIZE);
+ EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
+ EXPECT(MASK_BOTH == gpt->valid_headers);
+ EXPECT(MASK_BOTH == gpt->valid_entries);
+ EXPECT(MASK_SECONDARY == gpt->ignored);
+ EXPECT(0 == gpt->modified);
+
+ /* Test that two IGNOREME GPTs are invalid. */
+ ZeroHeadersEntries(gpt);
+ Memcpy(h1->signature, GPT_HEADER_SIGNATURE_IGNORED,
+ GPT_HEADER_SIGNATURE_SIZE);
+ Memcpy(h2->signature, GPT_HEADER_SIGNATURE_IGNORED,
+ GPT_HEADER_SIGNATURE_SIZE);
+ EXPECT(GPT_ERROR_INVALID_HEADERS == GptSanityCheck(gpt));
+ EXPECT(0 == gpt->valid_headers);
+ EXPECT(0 == gpt->valid_entries);
+ EXPECT(MASK_BOTH == gpt->ignored);
+ EXPECT(0 == gpt->modified);
+
+ /* Test that one IGNOREME GPT and one corrupted one are invalid. */
+ BuildTestGptData(gpt);
+ Memset(gpt->primary_entries, 0, PARTITION_ENTRIES_SIZE);
+ Memset(gpt->primary_header, 0, sizeof(GptHeader));
+ Memcpy(h1->signature, GPT_HEADER_SIGNATURE_IGNORED,
+ GPT_HEADER_SIGNATURE_SIZE);
+ gpt->secondary_entries[0]++;
+ EXPECT(GPT_ERROR_INVALID_ENTRIES == GptSanityCheck(gpt));
+ EXPECT(MASK_SECONDARY == gpt->valid_headers);
+ EXPECT(0 == gpt->valid_entries);
+ EXPECT(MASK_PRIMARY == gpt->ignored);
+ EXPECT(0 == gpt->modified);
return TEST_OK;
}