diff options
author | Nam T. Nguyen <namnguyen@chromium.org> | 2014-10-16 15:02:40 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-10-17 03:25:28 +0000 |
commit | d92856ddfa4f58efbaf17427eda8da5dcdbdc8e2 (patch) | |
tree | 551e02b32f164effa058fb63545a2de915e27013 /cgpt/cgpt_common.c | |
parent | 731f8e8a1df73a00f4840120171b07a259a6304a (diff) | |
download | vboot-d92856ddfa4f58efbaf17427eda8da5dcdbdc8e2.tar.gz |
cgpt: Validate GPT headers before loading them
This CL validates the GPT headers before continue loading its fields.
BRANCH=none
BUG=chromium:422469
TEST=unittest
TEST=cpgt show on a random file. There should be some warnings.
TEST=boot from SD/USB on a device. cgpt show that boot device. It should
not fail.
Change-Id: I1e5e986cc46620643ec8ec6914fa696a3d04d23a
Reviewed-on: https://chromium-review.googlesource.com/223800
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Queue: Nam Nguyen <namnguyen@chromium.org>
Tested-by: Nam Nguyen <namnguyen@chromium.org>
Diffstat (limited to 'cgpt/cgpt_common.c')
-rw-r--r-- | cgpt/cgpt_common.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c index 9eb99504..3900cf33 100644 --- a/cgpt/cgpt_common.c +++ b/cgpt/cgpt_common.c @@ -27,6 +27,9 @@ #include "flash_ts_api.h" #include "vboot_host.h" +static const char kErrorTag[] = "ERROR"; +static const char kWarningTag[] = "WARNING"; + struct nand_layout nand; void EnableNandImage(int bytes_per_page, int pages_per_block, @@ -38,19 +41,29 @@ void EnableNandImage(int bytes_per_page, int pages_per_block, nand.fts_block_size = fts_block_size; } +static void LogToStderr(const char *tag, const char *format, va_list ap) { + fprintf(stderr, "%s: ", tag); + vfprintf(stderr, format, ap); +} + void Error(const char *format, ...) { va_list ap; va_start(ap, format); - fprintf(stderr, "ERROR: "); - vfprintf(stderr, format, ap); + LogToStderr(kErrorTag, format, ap); + va_end(ap); +} + +void Warning(const char *format, ...) { + va_list ap; + va_start(ap, format); + LogToStderr(kWarningTag, format, ap); va_end(ap); } int CheckValid(const struct drive *drive) { if ((drive->gpt.valid_headers != MASK_BOTH) || (drive->gpt.valid_entries != MASK_BOTH)) { - fprintf(stderr, - "\nWARNING: one of the GPT header/entries is invalid\n\n"); + Warning("One of the GPT headers/entries is invalid\n\n"); return CGPT_FAILED; } return CGPT_OK; @@ -311,24 +324,36 @@ static int GptLoad(struct drive *drive, uint32_t sector_bytes) { if (CGPT_OK != Load(drive, &drive->gpt.primary_header, GPT_PMBR_SECTORS, drive->gpt.sector_bytes, GPT_HEADER_SECTORS)) { + Error("Cannot read primary GPT header\n"); return -1; } if (CGPT_OK != Load(drive, &drive->gpt.secondary_header, drive->gpt.drive_sectors - GPT_PMBR_SECTORS, drive->gpt.sector_bytes, GPT_HEADER_SECTORS)) { + Error("Cannot read secondary GPT header\n"); return -1; } GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header; - if (CGPT_OK != Load(drive, &drive->gpt.primary_entries, - primary_header->entries_lba, - drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) { - return -1; + if (CheckHeader(primary_header, 0, drive->gpt.drive_sectors) == 0) { + if (CGPT_OK != Load(drive, &drive->gpt.primary_entries, + primary_header->entries_lba, + drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) { + Error("Cannot read primary partition entry array\n"); + return -1; + } + } else { + Warning("Primary GPT header is invalid\n"); } GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header; - if (CGPT_OK != Load(drive, &drive->gpt.secondary_entries, - secondary_header->entries_lba, - drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) { - return -1; + if (CheckHeader(secondary_header, 1, drive->gpt.drive_sectors) == 0) { + if (CGPT_OK != Load(drive, &drive->gpt.secondary_entries, + secondary_header->entries_lba, + drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) { + Error("Cannot read secondary partition entry array\n"); + return -1; + } + } else { + Warning("Secondary GPT header is invalid\n"); } return 0; } |