mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 02:05:01 +00:00
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>
This commit is contained in:
committed by
chrome-internal-fetch
parent
731f8e8a1d
commit
d92856ddfa
@@ -27,6 +27,9 @@
|
|||||||
#include "flash_ts_api.h"
|
#include "flash_ts_api.h"
|
||||||
#include "vboot_host.h"
|
#include "vboot_host.h"
|
||||||
|
|
||||||
|
static const char kErrorTag[] = "ERROR";
|
||||||
|
static const char kWarningTag[] = "WARNING";
|
||||||
|
|
||||||
struct nand_layout nand;
|
struct nand_layout nand;
|
||||||
|
|
||||||
void EnableNandImage(int bytes_per_page, int pages_per_block,
|
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;
|
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, ...) {
|
void Error(const char *format, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
fprintf(stderr, "ERROR: ");
|
LogToStderr(kErrorTag, format, ap);
|
||||||
vfprintf(stderr, format, ap);
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Warning(const char *format, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
LogToStderr(kWarningTag, format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CheckValid(const struct drive *drive) {
|
int CheckValid(const struct drive *drive) {
|
||||||
if ((drive->gpt.valid_headers != MASK_BOTH) ||
|
if ((drive->gpt.valid_headers != MASK_BOTH) ||
|
||||||
(drive->gpt.valid_entries != MASK_BOTH)) {
|
(drive->gpt.valid_entries != MASK_BOTH)) {
|
||||||
fprintf(stderr,
|
Warning("One of the GPT headers/entries is invalid\n\n");
|
||||||
"\nWARNING: one of the GPT header/entries is invalid\n\n");
|
|
||||||
return CGPT_FAILED;
|
return CGPT_FAILED;
|
||||||
}
|
}
|
||||||
return CGPT_OK;
|
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,
|
if (CGPT_OK != Load(drive, &drive->gpt.primary_header,
|
||||||
GPT_PMBR_SECTORS,
|
GPT_PMBR_SECTORS,
|
||||||
drive->gpt.sector_bytes, GPT_HEADER_SECTORS)) {
|
drive->gpt.sector_bytes, GPT_HEADER_SECTORS)) {
|
||||||
|
Error("Cannot read primary GPT header\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (CGPT_OK != Load(drive, &drive->gpt.secondary_header,
|
if (CGPT_OK != Load(drive, &drive->gpt.secondary_header,
|
||||||
drive->gpt.drive_sectors - GPT_PMBR_SECTORS,
|
drive->gpt.drive_sectors - GPT_PMBR_SECTORS,
|
||||||
drive->gpt.sector_bytes, GPT_HEADER_SECTORS)) {
|
drive->gpt.sector_bytes, GPT_HEADER_SECTORS)) {
|
||||||
|
Error("Cannot read secondary GPT header\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header;
|
GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header;
|
||||||
if (CGPT_OK != Load(drive, &drive->gpt.primary_entries,
|
if (CheckHeader(primary_header, 0, drive->gpt.drive_sectors) == 0) {
|
||||||
primary_header->entries_lba,
|
if (CGPT_OK != Load(drive, &drive->gpt.primary_entries,
|
||||||
drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) {
|
primary_header->entries_lba,
|
||||||
return -1;
|
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;
|
GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header;
|
||||||
if (CGPT_OK != Load(drive, &drive->gpt.secondary_entries,
|
if (CheckHeader(secondary_header, 1, drive->gpt.drive_sectors) == 0) {
|
||||||
secondary_header->entries_lba,
|
if (CGPT_OK != Load(drive, &drive->gpt.secondary_entries,
|
||||||
drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) {
|
secondary_header->entries_lba,
|
||||||
return -1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,16 +9,30 @@
|
|||||||
#include "cgptlib_internal.h"
|
#include "cgptlib_internal.h"
|
||||||
#include "vboot_host.h"
|
#include "vboot_host.h"
|
||||||
|
|
||||||
|
static void AllocAndClear(uint8_t **buf, uint64_t size) {
|
||||||
|
if (*buf) {
|
||||||
|
memset(*buf, 0, size);
|
||||||
|
} else {
|
||||||
|
*buf = calloc(1, size);
|
||||||
|
if (!*buf) {
|
||||||
|
Error("Cannot allocate %u bytes.\n", size);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int GptCreate(struct drive *drive, CgptCreateParams *params) {
|
static int GptCreate(struct drive *drive, CgptCreateParams *params) {
|
||||||
// Erase the data
|
// Allocate and/or erase the data.
|
||||||
memset(drive->gpt.primary_header, 0,
|
// We cannot assume the GPT headers or entry arrays have been allocated
|
||||||
drive->gpt.sector_bytes * GPT_HEADER_SECTORS);
|
// by GptLoad() because those fields might have failed validation checks.
|
||||||
memset(drive->gpt.secondary_header, 0,
|
AllocAndClear(&drive->gpt.primary_header,
|
||||||
drive->gpt.sector_bytes * GPT_HEADER_SECTORS);
|
drive->gpt.sector_bytes * GPT_HEADER_SECTORS);
|
||||||
memset(drive->gpt.primary_entries, 0,
|
AllocAndClear(&drive->gpt.secondary_header,
|
||||||
drive->gpt.sector_bytes * GPT_ENTRIES_SECTORS);
|
drive->gpt.sector_bytes * GPT_HEADER_SECTORS);
|
||||||
memset(drive->gpt.secondary_entries, 0,
|
AllocAndClear(&drive->gpt.primary_entries,
|
||||||
drive->gpt.sector_bytes * GPT_ENTRIES_SECTORS);
|
drive->gpt.sector_bytes * GPT_ENTRIES_SECTORS);
|
||||||
|
AllocAndClear(&drive->gpt.secondary_entries,
|
||||||
|
drive->gpt.sector_bytes * GPT_ENTRIES_SECTORS);
|
||||||
|
|
||||||
drive->gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 |
|
drive->gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 |
|
||||||
GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2);
|
GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2);
|
||||||
|
|||||||
Reference in New Issue
Block a user