diff options
author | Dan Ehrenberg <dehrenberg@chromium.org> | 2014-10-21 16:15:54 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-10-29 00:22:03 +0000 |
commit | 7c2beb08380410ca6847abdac23e11ded2d1b625 (patch) | |
tree | 0477c0764bc1f53e6773171c60a92736bcf128ad | |
parent | f18038b750c43c2185e64db38d0d244c6810083b (diff) | |
download | vboot-7c2beb08380410ca6847abdac23e11ded2d1b625.tar.gz |
cgpt: Separate out certain GPT manipluation functionsstabilize-6415.Bfoo-test
For kernel NAND support, some vboot/cgptlib functionality is
needed from depthcharge. This patch moves certain function
declarations to a new header in firmware/include and puts
their definitions in a common place.
TEST=make runalltests passes and packages build
BRANCH=none
BUG=chromium:403432
Change-Id: Idd42b1f9f531651d78bb4afb80ca90c24aae93d9
Reviewed-on: https://chromium-review.googlesource.com/224996
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Queue: Daniel Ehrenberg <dehrenberg@chromium.org>
Tested-by: Daniel Ehrenberg <dehrenberg@chromium.org>
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | firmware/include/gpt_misc.h | 129 | ||||
-rw-r--r-- | firmware/lib/cgptlib/cgptlib_internal.c | 1 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/cgptlib.h | 105 | ||||
-rw-r--r-- | firmware/lib/gpt_misc.c | 181 | ||||
-rw-r--r-- | firmware/lib/include/vboot_kernel.h | 15 | ||||
-rw-r--r-- | firmware/lib/vboot_kernel.c | 167 |
7 files changed, 315 insertions, 284 deletions
@@ -271,6 +271,7 @@ VBSLK_SRCS = \ firmware/lib/cgptlib/cgptlib_internal.c \ firmware/lib/cgptlib/crc32.c \ firmware/lib/cgptlib/mtdlib.c \ + firmware/lib/gpt_misc.c \ firmware/lib/utility_string.c \ firmware/lib/vboot_api_kernel.c \ firmware/lib/vboot_audio.c \ diff --git a/firmware/include/gpt_misc.h b/firmware/include/gpt_misc.h new file mode 100644 index 00000000..4d91bd8c --- /dev/null +++ b/firmware/include/gpt_misc.h @@ -0,0 +1,129 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef VBOOT_REFERENCE_CGPT_MISC_H_ +#define VBOOT_REFERENCE_CGPT_MISC_H_ + +#include "vboot_api.h" + +enum { + GPT_SUCCESS = 0, + GPT_ERROR_NO_VALID_KERNEL, + GPT_ERROR_INVALID_HEADERS, + GPT_ERROR_INVALID_ENTRIES, + GPT_ERROR_INVALID_SECTOR_SIZE, + GPT_ERROR_INVALID_SECTOR_NUMBER, + GPT_ERROR_INVALID_UPDATE_TYPE, + GPT_ERROR_CRC_CORRUPTED, + GPT_ERROR_OUT_OF_REGION, + GPT_ERROR_START_LBA_OVERLAP, + GPT_ERROR_END_LBA_OVERLAP, + GPT_ERROR_DUP_GUID, + GPT_ERROR_INVALID_FLASH_GEOMETRY, + GPT_ERROR_NO_SUCH_ENTRY, + /* Number of errors */ + GPT_ERROR_COUNT +}; + +/* Bit masks for GptData.modified field. */ +#define GPT_MODIFIED_HEADER1 0x01 +#define GPT_MODIFIED_HEADER2 0x02 +#define GPT_MODIFIED_ENTRIES1 0x04 +#define GPT_MODIFIED_ENTRIES2 0x08 + +/* + * Size of GptData.primary_entries and secondary_entries: 128 bytes/entry * 128 + * entries. + */ +#define TOTAL_ENTRIES_SIZE 16384 + +/* + * The 'update_type' of GptUpdateKernelEntry(). We expose TRY and BAD only + * because those are what verified boot needs. For more precise control on GPT + * attribute bits, please refer to gpt_internal.h. + */ +enum { + /* + * System will be trying to boot the currently selected kernel + * partition. Update its try count if necessary. + */ + GPT_UPDATE_ENTRY_TRY = 1, + /* + * The currently selected kernel partition failed validation. Mark + * entry as invalid. + */ + GPT_UPDATE_ENTRY_BAD = 2, +}; + +typedef struct { + /* Fill in the following fields before calling GptInit() */ + /* GPT primary header, from sector 1 of disk (size: 512 bytes) */ + uint8_t *primary_header; + /* GPT secondary header, from last sector of disk (size: 512 bytes) */ + uint8_t *secondary_header; + /* Primary GPT table, follows primary header (size: 16 KB) */ + uint8_t *primary_entries; + /* Secondary GPT table, precedes secondary header (size: 16 KB) */ + uint8_t *secondary_entries; + /* Size of a LBA sector, in bytes */ + uint32_t sector_bytes; + /* Size of drive in LBA sectors, in sectors */ + uint64_t drive_sectors; + + /* Outputs */ + /* Which inputs have been modified? GPT_MODIFIED_* */ + uint8_t modified; + /* + * The current chromeos kernel index in partition table. -1 means not + * found on drive. Note that GPT partition numbers are traditionally + * 1-based, but we're using a zero-based index here. + */ + int current_kernel; + + /* Internal variables */ + uint32_t valid_headers, valid_entries; + int current_priority; +} GptData; + +/** + * Initializes the GPT data structure's internal state. + * + * The following fields must be filled before calling this function: + * + * primary_header + * secondary_header + * primary_entries + * secondary_entries + * sector_bytes + * drive_sectors + * + * On return the modified field may be set, if the GPT data has been modified + * and should be written to disk. + * + * Returns GPT_SUCCESS if successful, non-zero if error: + * GPT_ERROR_INVALID_HEADERS, both partition table headers are invalid, enters + * recovery mode, + * GPT_ERROR_INVALID_ENTRIES, both partition table entries are invalid, enters + * recovery mode, + * GPT_ERROR_INVALID_SECTOR_SIZE, size of a sector is not supported, + * GPT_ERROR_INVALID_SECTOR_NUMBER, number of sectors in drive is invalid (too + * small) */ +int GptInit(GptData *gpt); + +/** + * Allocate and read GPT data from the drive. The sector_bytes and + * drive_sectors fields should be filled on input. The primary and secondary + * header and entries are filled on output. + * + * Returns 0 if successful, 1 if error. + */ +int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata); + +/** + * Write any changes for the GPT data back to the drive, then free the buffers. + */ +int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata); + +#endif /* VBOOT_REFERENCE_CGPT_MISC_H_ */ diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c index 38ca7d92..9fdf9e28 100644 --- a/firmware/lib/cgptlib/cgptlib_internal.c +++ b/firmware/lib/cgptlib/cgptlib_internal.c @@ -9,6 +9,7 @@ #include "cgptlib_internal.h" #include "crc32.h" #include "gpt.h" +#include "gpt_misc.h" #include "utility.h" diff --git a/firmware/lib/cgptlib/include/cgptlib.h b/firmware/lib/cgptlib/include/cgptlib.h index ef329783..968ec635 100644 --- a/firmware/lib/cgptlib/include/cgptlib.h +++ b/firmware/lib/cgptlib/include/cgptlib.h @@ -7,110 +7,7 @@ #define VBOOT_REFERENCE_CGPTLIB_H_ #include "sysincludes.h" - -enum { - GPT_SUCCESS = 0, - GPT_ERROR_NO_VALID_KERNEL, - GPT_ERROR_INVALID_HEADERS, - GPT_ERROR_INVALID_ENTRIES, - GPT_ERROR_INVALID_SECTOR_SIZE, - GPT_ERROR_INVALID_SECTOR_NUMBER, - GPT_ERROR_INVALID_UPDATE_TYPE, - GPT_ERROR_CRC_CORRUPTED, - GPT_ERROR_OUT_OF_REGION, - GPT_ERROR_START_LBA_OVERLAP, - GPT_ERROR_END_LBA_OVERLAP, - GPT_ERROR_DUP_GUID, - GPT_ERROR_INVALID_FLASH_GEOMETRY, - GPT_ERROR_NO_SUCH_ENTRY, - /* Number of errors */ - GPT_ERROR_COUNT -}; - -/* Bit masks for GptData.modified field. */ -#define GPT_MODIFIED_HEADER1 0x01 -#define GPT_MODIFIED_HEADER2 0x02 -#define GPT_MODIFIED_ENTRIES1 0x04 -#define GPT_MODIFIED_ENTRIES2 0x08 - -/* - * Size of GptData.primary_entries and secondary_entries: 128 bytes/entry * 128 - * entries. - */ -#define TOTAL_ENTRIES_SIZE 16384 - -/* - * The 'update_type' of GptUpdateKernelEntry(). We expose TRY and BAD only - * because those are what verified boot needs. For more precise control on GPT - * attribute bits, please refer to gpt_internal.h. - */ -enum { - /* - * System will be trying to boot the currently selected kernel - * partition. Update its try count if necessary. - */ - GPT_UPDATE_ENTRY_TRY = 1, - /* - * The currently selected kernel partition failed validation. Mark - * entry as invalid. - */ - GPT_UPDATE_ENTRY_BAD = 2, -}; - -typedef struct { - /* Fill in the following fields before calling GptInit() */ - /* GPT primary header, from sector 1 of disk (size: 512 bytes) */ - uint8_t *primary_header; - /* GPT secondary header, from last sector of disk (size: 512 bytes) */ - uint8_t *secondary_header; - /* Primary GPT table, follows primary header (size: 16 KB) */ - uint8_t *primary_entries; - /* Secondary GPT table, precedes secondary header (size: 16 KB) */ - uint8_t *secondary_entries; - /* Size of a LBA sector, in bytes */ - uint32_t sector_bytes; - /* Size of drive in LBA sectors, in sectors */ - uint64_t drive_sectors; - - /* Outputs */ - /* Which inputs have been modified? GPT_MODIFIED_* */ - uint8_t modified; - /* - * The current chromeos kernel index in partition table. -1 means not - * found on drive. Note that GPT partition numbers are traditionally - * 1-based, but we're using a zero-based index here. - */ - int current_kernel; - - /* Internal variables */ - uint32_t valid_headers, valid_entries; - int current_priority; -} GptData; - -/** - * Initializes the GPT data structure's internal state. - * - * The following fields must be filled before calling this function: - * - * primary_header - * secondary_header - * primary_entries - * secondary_entries - * sector_bytes - * drive_sectors - * - * On return the modified field may be set, if the GPT data has been modified - * and should be written to disk. - * - * Returns GPT_SUCCESS if successful, non-zero if error: - * GPT_ERROR_INVALID_HEADERS, both partition table headers are invalid, enters - * recovery mode, - * GPT_ERROR_INVALID_ENTRIES, both partition table entries are invalid, enters - * recovery mode, - * GPT_ERROR_INVALID_SECTOR_SIZE, size of a sector is not supported, - * GPT_ERROR_INVALID_SECTOR_NUMBER, number of sectors in drive is invalid (too - * small) */ -int GptInit(GptData *gpt); +#include "gpt_misc.h" /** * Provides the location of the next kernel partition, in order of decreasing diff --git a/firmware/lib/gpt_misc.c b/firmware/lib/gpt_misc.c new file mode 100644 index 00000000..d00d6b2e --- /dev/null +++ b/firmware/lib/gpt_misc.c @@ -0,0 +1,181 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "sysincludes.h" + +#include "cgptlib.h" +#include "cgptlib_internal.h" +#include "crc32.h" +#include "gpt.h" +#include "utility.h" +#include "vboot_api.h" + + +/** + * Allocate and read GPT data from the drive. + * + * The sector_bytes and drive_sectors fields should be filled on input. The + * primary and secondary header and entries are filled on output. + * + * Returns 0 if successful, 1 if error. + */ +int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) +{ + uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes; + int primary_valid = 0, secondary_valid = 0; + + /* No data to be written yet */ + gptdata->modified = 0; + + /* Allocate all buffers */ + gptdata->primary_header = (uint8_t *)VbExMalloc(gptdata->sector_bytes); + gptdata->secondary_header = + (uint8_t *)VbExMalloc(gptdata->sector_bytes); + gptdata->primary_entries = (uint8_t *)VbExMalloc(TOTAL_ENTRIES_SIZE); + gptdata->secondary_entries = (uint8_t *)VbExMalloc(TOTAL_ENTRIES_SIZE); + + if (gptdata->primary_header == NULL || + gptdata->secondary_header == NULL || + gptdata->primary_entries == NULL || + gptdata->secondary_entries == NULL) + return 1; + + /* Read primary header from the drive, skipping the protective MBR */ + if (0 != VbExDiskRead(disk_handle, 1, 1, gptdata->primary_header)) + return 1; + + /* Only read primary GPT if the primary header is valid */ + GptHeader* primary_header = (GptHeader*)gptdata->primary_header; + if (0 == CheckHeader(primary_header, 0, gptdata->drive_sectors)) { + primary_valid = 1; + if (0 != VbExDiskRead(disk_handle, + primary_header->entries_lba, + entries_sectors, + gptdata->primary_entries)) + return 1; + } else { + VBDEBUG(("Primary GPT header invalid!\n")); + } + + /* Read secondary header from the end of the drive */ + if (0 != VbExDiskRead(disk_handle, gptdata->drive_sectors - 1, 1, + gptdata->secondary_header)) + return 1; + + /* Only read secondary GPT if the secondary header is valid */ + GptHeader* secondary_header = (GptHeader*)gptdata->secondary_header; + if (0 == CheckHeader(secondary_header, 1, gptdata->drive_sectors)) { + secondary_valid = 1; + if (0 != VbExDiskRead(disk_handle, + secondary_header->entries_lba, + entries_sectors, + gptdata->secondary_entries)) + return 1; + } else { + VBDEBUG(("Secondary GPT header invalid!\n")); + } + + /* Return 0 if least one GPT header was valid */ + return (primary_valid || secondary_valid) ? 0 : 1; +} + +/** + * Write any changes for the GPT data back to the drive, then free the buffers. + * + * Returns 0 if successful, 1 if error. + */ +int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) +{ + int legacy = 0; + uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes; + int ret = 1; + + /* + * TODO(namnguyen): Preserve padding between primary GPT header and + * its entries. + */ + uint64_t entries_lba = GPT_PMBR_SECTORS + GPT_HEADER_SECTORS; + if (gptdata->primary_header) { + 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: " + "legacy mode is enabled.\n")); + } else { + VBDEBUG(("Updating GPT header 1\n")); + if (0 != VbExDiskWrite(disk_handle, 1, 1, + gptdata->primary_header)) + goto fail; + } + } + } + + if (gptdata->primary_entries) { + 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; + } + } + } + + entries_lba = (gptdata->drive_sectors - entries_sectors - + GPT_HEADER_SECTORS); + if (gptdata->secondary_header) { + GptHeader *h = (GptHeader *)(gptdata->secondary_header); + entries_lba = h->entries_lba; + if (gptdata->modified & GPT_MODIFIED_HEADER2) { + VBDEBUG(("Updating GPT entries 2\n")); + if (0 != VbExDiskWrite(disk_handle, + gptdata->drive_sectors - 1, 1, + gptdata->secondary_header)) + goto fail; + } + } + + if (gptdata->secondary_entries) { + if (gptdata->modified & GPT_MODIFIED_ENTRIES2) { + VBDEBUG(("Updating GPT header 2\n")); + if (0 != VbExDiskWrite(disk_handle, + entries_lba, entries_sectors, + gptdata->secondary_entries)) + goto fail; + } + } + + ret = 0; + +fail: + /* Avoid leaking memory on disk write failure */ + if (gptdata->primary_header) + VbExFree(gptdata->primary_header); + if (gptdata->primary_entries) + VbExFree(gptdata->primary_entries); + if (gptdata->secondary_entries) + VbExFree(gptdata->secondary_entries); + if (gptdata->secondary_header) + VbExFree(gptdata->secondary_header); + + /* Success */ + return ret; +} + diff --git a/firmware/lib/include/vboot_kernel.h b/firmware/lib/include/vboot_kernel.h index 2c0f2cef..2f1be5be 100644 --- a/firmware/lib/include/vboot_kernel.h +++ b/firmware/lib/include/vboot_kernel.h @@ -10,25 +10,12 @@ #define VBOOT_REFERENCE_VBOOT_KERNEL_H_ #include "cgptlib.h" +#include "gpt_misc.h" #include "load_firmware_fw.h" #include "load_kernel_fw.h" #include "vboot_api.h" /** - * Allocate and read GPT data from the drive. The sector_bytes and - * drive_sectors fields should be filled on input. The primary and secondary - * header and entries are filled on output. - * - * Returns 0 if successful, 1 if error. - */ -int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata); - -/** - * Write any changes for the GPT data back to the drive, then free the buffers. - */ -int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata); - -/** * Accessors for unit tests only. */ VbNvContext *VbApiKernelGetVnc(void); diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c index a66b8861..b2cb8172 100644 --- a/firmware/lib/vboot_kernel.c +++ b/firmware/lib/vboot_kernel.c @@ -13,6 +13,7 @@ #include "region.h" #include "gbb_access.h" #include "gbb_header.h" +#include "gpt_misc.h" #include "load_kernel_fw.h" #include "utility.h" #include "vboot_api.h" @@ -28,172 +29,6 @@ typedef enum BootMode { kBootDev = 2 /* Developer boot - self-signed kernel ok */ } BootMode; -/** - * Allocate and read GPT data from the drive. - * - * The sector_bytes and drive_sectors fields should be filled on input. The - * primary and secondary header and entries are filled on output. - * - * Returns 0 if successful, 1 if error. - */ -int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) -{ - uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes; - int primary_valid = 0, secondary_valid = 0; - - /* No data to be written yet */ - gptdata->modified = 0; - - /* Allocate all buffers */ - gptdata->primary_header = (uint8_t *)VbExMalloc(gptdata->sector_bytes); - gptdata->secondary_header = - (uint8_t *)VbExMalloc(gptdata->sector_bytes); - gptdata->primary_entries = (uint8_t *)VbExMalloc(TOTAL_ENTRIES_SIZE); - gptdata->secondary_entries = (uint8_t *)VbExMalloc(TOTAL_ENTRIES_SIZE); - - if (gptdata->primary_header == NULL || - gptdata->secondary_header == NULL || - gptdata->primary_entries == NULL || - gptdata->secondary_entries == NULL) - return 1; - - /* Read primary header from the drive, skipping the protective MBR */ - if (0 != VbExDiskRead(disk_handle, 1, 1, gptdata->primary_header)) - return 1; - - /* Only read primary GPT if the primary header is valid */ - GptHeader* primary_header = (GptHeader*)gptdata->primary_header; - if (0 == CheckHeader(primary_header, 0, gptdata->drive_sectors)) { - primary_valid = 1; - if (0 != VbExDiskRead(disk_handle, - primary_header->entries_lba, - entries_sectors, - gptdata->primary_entries)) - return 1; - } else { - VBDEBUG(("Primary GPT header invalid!\n")); - } - - /* Read secondary header from the end of the drive */ - if (0 != VbExDiskRead(disk_handle, gptdata->drive_sectors - 1, 1, - gptdata->secondary_header)) - return 1; - - /* Only read secondary GPT if the secondary header is valid */ - GptHeader* secondary_header = (GptHeader*)gptdata->secondary_header; - if (0 == CheckHeader(secondary_header, 1, gptdata->drive_sectors)) { - secondary_valid = 1; - if (0 != VbExDiskRead(disk_handle, - secondary_header->entries_lba, - entries_sectors, - gptdata->secondary_entries)) - return 1; - } else { - VBDEBUG(("Secondary GPT header invalid!\n")); - } - - /* Return 0 if least one GPT header was valid */ - return (primary_valid || secondary_valid) ? 0 : 1; -} - -/** - * Write any changes for the GPT data back to the drive, then free the buffers. - * - * Returns 0 if successful, 1 if error. - */ -int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) -{ - int legacy = 0; - uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes; - int ret = 1; - - /* - * TODO(namnguyen): Preserve padding between primary GPT header and - * its entries. - */ - uint64_t entries_lba = GPT_PMBR_SECTORS + GPT_HEADER_SECTORS; - if (gptdata->primary_header) { - 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: " - "legacy mode is enabled.\n")); - } else { - VBDEBUG(("Updating GPT header 1\n")); - if (0 != VbExDiskWrite(disk_handle, 1, 1, - gptdata->primary_header)) - goto fail; - } - } - } - - if (gptdata->primary_entries) { - 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; - } - } - } - - entries_lba = (gptdata->drive_sectors - entries_sectors - - GPT_HEADER_SECTORS); - if (gptdata->secondary_header) { - GptHeader *h = (GptHeader *)(gptdata->secondary_header); - entries_lba = h->entries_lba; - if (gptdata->modified & GPT_MODIFIED_HEADER2) { - VBDEBUG(("Updating GPT entries 2\n")); - if (0 != VbExDiskWrite(disk_handle, - gptdata->drive_sectors - 1, 1, - gptdata->secondary_header)) - goto fail; - } - } - - if (gptdata->secondary_entries) { - if (gptdata->modified & GPT_MODIFIED_ENTRIES2) { - VBDEBUG(("Updating GPT header 2\n")); - if (0 != VbExDiskWrite(disk_handle, - entries_lba, entries_sectors, - gptdata->secondary_entries)) - goto fail; - } - } - - ret = 0; - -fail: - /* Avoid leaking memory on disk write failure */ - if (gptdata->primary_header) - VbExFree(gptdata->primary_header); - if (gptdata->primary_entries) - VbExFree(gptdata->primary_entries); - if (gptdata->secondary_entries) - VbExFree(gptdata->secondary_entries); - if (gptdata->secondary_header) - VbExFree(gptdata->secondary_header); - - /* Success */ - return ret; -} - VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams) { VbSharedDataHeader *shared = |