| Index: src/platform/vboot_reference/vboot_firmware/lib/load_kernel_fw.c
|
| diff --git a/src/platform/vboot_reference/vboot_firmware/lib/load_kernel_fw.c b/src/platform/vboot_reference/vboot_firmware/lib/load_kernel_fw.c
|
| index 8ec440b5993eb295769c3d0c859b7185dce79f33..dec92d199a4c69d2c2acffff434e3ee536df186c 100644
|
| --- a/src/platform/vboot_reference/vboot_firmware/lib/load_kernel_fw.c
|
| +++ b/src/platform/vboot_reference/vboot_firmware/lib/load_kernel_fw.c
|
| @@ -14,6 +14,46 @@
|
| #include "rollback_index.h"
|
| #include "utility.h"
|
|
|
| +#define GPT_ENTRIES_SIZE 16384 /* Bytes to read for GPT entries */
|
| +
|
| +// TODO: for testing
|
| +#include <stdio.h>
|
| +#include "cgptlib_internal.h"
|
| +
|
| +/* TODO: Remove this terrible hack which fakes partition attributes
|
| + * for the kernel partitions so that GptNextKernelEntry() won't
|
| + * choke. */
|
| +void FakePartitionAttributes(GptData* gpt) {
|
| + GptEntry* entries = (GptEntry*)gpt->primary_entries;
|
| + GptEntry* e;
|
| + int i;
|
| + printf("Hacking partition attributes...\n");
|
| + printf("Note that GUIDs below have first 3 fields endian-swapped\n");
|
| +
|
| + for (i = 0, e = entries; i < 12; i++, e++) {
|
| +
|
| + printf("%2d %08x %04x %04x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
| + i,
|
| + e->type.u.Uuid.time_low,
|
| + e->type.u.Uuid.time_mid,
|
| + e->type.u.Uuid.time_high_and_version,
|
| + e->type.u.Uuid.clock_seq_high_and_reserved,
|
| + e->type.u.Uuid.clock_seq_low,
|
| + e->type.u.Uuid.node[0],
|
| + e->type.u.Uuid.node[1],
|
| + e->type.u.Uuid.node[2],
|
| + e->type.u.Uuid.node[3],
|
| + e->type.u.Uuid.node[4],
|
| + e->type.u.Uuid.node[5]
|
| + );
|
| + if (!IsKernelEntry(e))
|
| + continue;
|
| + printf("Hacking attributes for kernel partition %d\n", i);
|
| + SetEntryPriority(e, 2);
|
| + SetEntrySuccessful(e, 1);
|
| + }
|
| +}
|
| +
|
|
|
| int AllocAndReadGptData(GptData *gptdata) {
|
| /* Allocates and reads GPT data from the drive. The sector_bytes and
|
| @@ -22,7 +62,7 @@ int AllocAndReadGptData(GptData *gptdata) {
|
| *
|
| * Returns 0 if successful, 1 if error. */
|
|
|
| - uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes;
|
| + uint64_t entries_sectors = GPT_ENTRIES_SIZE / gptdata->sector_bytes;
|
|
|
| /* No data to be written yet */
|
| gptdata->modified = 0;
|
| @@ -30,22 +70,22 @@ int AllocAndReadGptData(GptData *gptdata) {
|
| /* Allocate all buffers */
|
| gptdata->primary_header = (uint8_t*)Malloc(gptdata->sector_bytes);
|
| gptdata->secondary_header = (uint8_t*)Malloc(gptdata->sector_bytes);
|
| - gptdata->primary_entries = (uint8_t*)Malloc(TOTAL_ENTRIES_SIZE);
|
| - gptdata->secondary_entries = (uint8_t*)Malloc(TOTAL_ENTRIES_SIZE);
|
| + gptdata->primary_entries = (uint8_t*)Malloc(GPT_ENTRIES_SIZE);
|
| + gptdata->secondary_entries = (uint8_t*)Malloc(GPT_ENTRIES_SIZE);
|
|
|
| if (gptdata->primary_header == NULL || gptdata->secondary_header == NULL ||
|
| gptdata->primary_entries == NULL || gptdata->secondary_entries == NULL)
|
| return 1;
|
|
|
| - /* Read data from the drive */
|
| - if (0 != BootDeviceReadLBA(0, 1, gptdata->primary_header))
|
| + /* Read data from the drive, skipping the protective MBR */
|
| + if (0 != BootDeviceReadLBA(1, 1, gptdata->primary_header))
|
| return 1;
|
| - if (0 != BootDeviceReadLBA(1, entries_sectors, gptdata->primary_entries))
|
| + if (0 != BootDeviceReadLBA(2, entries_sectors, gptdata->primary_entries))
|
| return 1;
|
| if (0 != BootDeviceReadLBA(gptdata->drive_sectors - entries_sectors - 1,
|
| entries_sectors, gptdata->secondary_entries))
|
| return 1;
|
| - if (0 != BootDeviceReadLBA(gptdata->drive_sectors - entries_sectors - 1,
|
| + if (0 != BootDeviceReadLBA(gptdata->drive_sectors - 1,
|
| 1, gptdata->secondary_header))
|
| return 1;
|
|
|
| @@ -56,17 +96,17 @@ void WriteAndFreeGptData(GptData *gptdata) {
|
| /* Writes any changes for the GPT data back to the drive, then frees the
|
| * buffers. */
|
|
|
| - uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes;
|
| + uint64_t entries_sectors = GPT_ENTRIES_SIZE / gptdata->sector_bytes;
|
|
|
| if (gptdata->primary_header) {
|
| if (gptdata->modified & GPT_MODIFIED_HEADER1)
|
| - BootDeviceWriteLBA(0, 1, gptdata->primary_header);
|
| + BootDeviceWriteLBA(1, 1, gptdata->primary_header);
|
| Free(gptdata->primary_header);
|
| }
|
|
|
| if (gptdata->primary_entries) {
|
| if (gptdata->modified & GPT_MODIFIED_ENTRIES1)
|
| - BootDeviceWriteLBA(1, entries_sectors, gptdata->primary_entries);
|
| + BootDeviceWriteLBA(2, entries_sectors, gptdata->primary_entries);
|
| Free(gptdata->primary_entries);
|
| }
|
|
|
| @@ -81,8 +121,9 @@ void WriteAndFreeGptData(GptData *gptdata) {
|
| if (gptdata->modified & GPT_MODIFIED_HEADER2)
|
| BootDeviceWriteLBA(gptdata->drive_sectors - entries_sectors - 1,
|
| 1, gptdata->secondary_header);
|
| - BootDeviceWriteLBA(0, 1, gptdata->primary_header);
|
| - Free(gptdata->primary_header);
|
| + BootDeviceWriteLBA(gptdata->drive_sectors - 1, 1,
|
| + gptdata->secondary_header);
|
| + Free(gptdata->secondary_header);
|
| }
|
| /* TODO: What to do with return codes from the writes? */
|
| }
|
| @@ -112,6 +153,7 @@ int LoadKernel(LoadKernelParams* params) {
|
| GetStoredVersions(KERNEL_VERSIONS,
|
| &tpm_kernel_key_version,
|
| &tpm_kernel_version);
|
| +
|
| do {
|
| /* Read GPT data */
|
| gpt.sector_bytes = blba;
|
| @@ -119,33 +161,45 @@ int LoadKernel(LoadKernelParams* params) {
|
| if (0 != AllocAndReadGptData(&gpt))
|
| break;
|
|
|
| + fprintf(stderr, "RRS1\n");
|
| +
|
| /* Initialize GPT library */
|
| if (GPT_SUCCESS != GptInit(&gpt))
|
| break;
|
|
|
| + /* TODO: TERRIBLE KLUDGE - fake partition attributes */
|
| + FakePartitionAttributes(&gpt);
|
| +
|
| /* Allocate kernel header and image work buffers */
|
| kbuf = (uint8_t*)Malloc(KBUF_SIZE);
|
| if (!kbuf)
|
| break;
|
| +
|
| kbuf_sectors = KBUF_SIZE / blba;
|
| kim = (KernelImage*)Malloc(sizeof(KernelImage));
|
| if (!kim)
|
| break;
|
|
|
| + fprintf(stderr, "RRS2\n");
|
| +
|
| /* Loop over candidate kernel partitions */
|
| while (GPT_SUCCESS == GptNextKernelEntry(&gpt, &part_start, &part_size)) {
|
| RSAPublicKey *kernel_sign_key = NULL;
|
| int kernel_start, kernel_sectors;
|
|
|
| + fprintf(stderr, "RRS3\n");
|
| +
|
| /* Found at least one kernel partition. */
|
| found_partition = 1;
|
|
|
| /* Read the first part of the kernel partition */
|
| if (part_size < kbuf_sectors)
|
| continue;
|
| - if (1 != BootDeviceReadLBA(part_start, kbuf_sectors, kbuf))
|
| + if (0 != BootDeviceReadLBA(part_start, kbuf_sectors, kbuf))
|
| continue;
|
|
|
| + fprintf(stderr, "RRS4\n");
|
| +
|
| /* Verify the kernel header and preamble */
|
| if (VERIFY_KERNEL_SUCCESS != VerifyKernelHeader(
|
| params->header_sign_key_blob,
|
| @@ -157,6 +211,8 @@ int LoadKernel(LoadKernelParams* params) {
|
| continue;
|
| }
|
|
|
| + fprintf(stderr, "RRS5\n");
|
| +
|
| /* Check for rollback of key version */
|
| if (kim->kernel_key_version < tpm_kernel_key_version) {
|
| RSAPublicKeyFree(kernel_sign_key);
|
|
|