summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Kitching <kitching@google.com>2021-07-20 07:18:42 +0800
committerCommit Bot <commit-bot@chromium.org>2021-07-21 06:49:54 +0000
commite355c9ea7e30775dc9698646339a4d9fe5fe3ee1 (patch)
treea0ddc6809fc90f14a9971fd587bb76c4eda7079b
parent2d3af1227d6c74733f4e16da424ffaabdfcd23d4 (diff)
downloadvboot-e355c9ea7e30775dc9698646339a4d9fe5fe3ee1.tar.gz
vboot/vboot_kernel: split gpt tests out of vboot_kernel_tests
These don't really belong together. We can get two cleaner test files by splitting them apart. This CL is part of a series to merge vboot1 and vboot2.0 kernel verification code; see b/181739551. BUG=b:181739551, b:172337800, b:124141368 TEST=make clean && make runtests BRANCH=none Signed-off-by: Joel Kitching <kitching@google.com> Change-Id: Idaa4c36214cc98bffdc50bdb5c071673829250ee Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3039164 Tested-by: Joel Kitching <kitching@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Commit-Queue: Joel Kitching <kitching@chromium.org>
-rw-r--r--Makefile2
-rw-r--r--tests/gpt_misc_tests.c378
-rw-r--r--tests/vboot_kernel_tests.c344
3 files changed, 392 insertions, 332 deletions
diff --git a/Makefile b/Makefile
index 38dad3e5..fd13991e 100644
--- a/Makefile
+++ b/Makefile
@@ -710,6 +710,7 @@ TEST_OBJS += ${TESTLIB_OBJS}
TEST_NAMES = \
tests/cgptlib_test \
tests/chromeos_config_tests \
+ tests/gpt_misc_tests \
tests/sha_benchmark \
tests/subprocess_tests \
tests/vboot_api_kernel4_tests \
@@ -1266,6 +1267,7 @@ runtestscripts: install_for_test genfuzztestcases
.PHONY: runmisctests
runmisctests: install_for_test
+ ${RUNTEST} ${BUILD_RUN}/tests/gpt_misc_tests
${RUNTEST} ${BUILD_RUN}/tests/subprocess_tests
ifeq (${MOCK_TPM}${TPM2_MODE},)
# tlcl_tests only works when MOCK_TPM is disabled
diff --git a/tests/gpt_misc_tests.c b/tests/gpt_misc_tests.c
new file mode 100644
index 00000000..e0a8d56e
--- /dev/null
+++ b/tests/gpt_misc_tests.c
@@ -0,0 +1,378 @@
+/* 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.
+ *
+ * Tests for vboot_kernel.c
+ */
+
+#include "2api.h"
+#include "cgptlib.h"
+#include "cgptlib_internal.h"
+#include "gpt.h"
+#include "test_common.h"
+
+#define LOGCALL(fmt, args...) sprintf(call_log + strlen(call_log), fmt, ##args)
+#define TEST_CALLS(expect_log) TEST_STR_EQ(call_log, expect_log, " calls")
+
+/* Assumes 512-byte disk sectors */
+#define MOCK_SECTOR_SIZE 512
+#define MOCK_SECTOR_COUNT 1024
+
+/* Mock kernel partition */
+struct mock_part {
+ uint32_t start;
+ uint32_t size;
+};
+
+/* Mock data */
+static char call_log[4096];
+static int disk_read_to_fail;
+static int disk_write_to_fail;
+
+static VbExDiskHandle_t handle;
+static uint8_t mock_disk[MOCK_SECTOR_SIZE * MOCK_SECTOR_COUNT];
+static GptHeader *mock_gpt_primary =
+ (GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * 1];
+static GptHeader *mock_gpt_secondary =
+ (GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * (MOCK_SECTOR_COUNT - 1)];
+
+/**
+ * Prepare a valid GPT header that will pass CheckHeader() tests
+ */
+static void SetupGptHeader(GptHeader *h, int is_secondary)
+{
+ memset(h, '\0', MOCK_SECTOR_SIZE);
+
+ /* "EFI PART" */
+ memcpy(h->signature, GPT_HEADER_SIGNATURE, GPT_HEADER_SIGNATURE_SIZE);
+ h->revision = GPT_HEADER_REVISION;
+ h->size = MIN_SIZE_OF_HEADER;
+
+ /* 16KB: 128 entries of 128 bytes */
+ h->size_of_entry = sizeof(GptEntry);
+ h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
+
+ /* Set LBA pointers for primary or secondary header */
+ if (is_secondary) {
+ h->my_lba = MOCK_SECTOR_COUNT - GPT_HEADER_SECTORS;
+ h->entries_lba = h->my_lba - CalculateEntriesSectors(h,
+ MOCK_SECTOR_SIZE);
+ } else {
+ h->my_lba = GPT_PMBR_SECTORS;
+ h->entries_lba = h->my_lba + 1;
+ }
+
+ h->first_usable_lba = 2 + CalculateEntriesSectors(h, MOCK_SECTOR_SIZE);
+ h->last_usable_lba = MOCK_SECTOR_COUNT - 2 - CalculateEntriesSectors(h,
+ MOCK_SECTOR_SIZE);
+
+ h->header_crc32 = HeaderCrc(h);
+}
+
+static void ResetCallLog(void)
+{
+ *call_log = 0;
+}
+
+/**
+ * Reset mock data (for use before each test)
+ */
+static void ResetMocks(void)
+{
+ ResetCallLog();
+
+ memset(&mock_disk, 0, sizeof(mock_disk));
+ SetupGptHeader(mock_gpt_primary, 0);
+ SetupGptHeader(mock_gpt_secondary, 1);
+
+ disk_read_to_fail = -1;
+ disk_write_to_fail = -1;
+}
+
+/* Mocks */
+
+vb2_error_t VbExDiskRead(VbExDiskHandle_t h, uint64_t lba_start,
+ uint64_t lba_count, void *buffer)
+{
+ LOGCALL("VbExDiskRead(h, %d, %d)\n", (int)lba_start, (int)lba_count);
+
+ if ((int)lba_start == disk_read_to_fail)
+ return VB2_ERROR_MOCK;
+
+ memcpy(buffer, &mock_disk[lba_start * MOCK_SECTOR_SIZE],
+ lba_count * MOCK_SECTOR_SIZE);
+
+ return VB2_SUCCESS;
+}
+
+vb2_error_t VbExDiskWrite(VbExDiskHandle_t h, uint64_t lba_start,
+ uint64_t lba_count, const void *buffer)
+{
+ LOGCALL("VbExDiskWrite(h, %d, %d)\n", (int)lba_start, (int)lba_count);
+
+ if ((int)lba_start == disk_write_to_fail)
+ return VB2_ERROR_MOCK;
+
+ memcpy(&mock_disk[lba_start * MOCK_SECTOR_SIZE], buffer,
+ lba_count * MOCK_SECTOR_SIZE);
+
+ return VB2_SUCCESS;
+}
+
+/**
+ * Test reading/writing GPT
+ */
+static void ReadWriteGptTest(void)
+{
+ GptData g;
+ GptHeader *h;
+
+ g.sector_bytes = MOCK_SECTOR_SIZE;
+ g.streaming_drive_sectors = g.gpt_drive_sectors = MOCK_SECTOR_COUNT;
+ g.valid_headers = g.valid_entries = MASK_BOTH;
+
+ ResetMocks();
+ TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead");
+ TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
+ "VbExDiskRead(h, 2, 32)\n"
+ "VbExDiskRead(h, 1023, 1)\n"
+ "VbExDiskRead(h, 991, 32)\n");
+ ResetCallLog();
+ /*
+ * Valgrind complains about access to uninitialized memory here, so
+ * zero the primary header before each test.
+ */
+ memset(g.primary_header, '\0', g.sector_bytes);
+ TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree");
+ TEST_CALLS("");
+
+ /*
+ * Invalidate primary GPT header,
+ * check that AllocAndReadGptData still succeeds
+ */
+ ResetMocks();
+ memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
+ TEST_EQ(AllocAndReadGptData(handle, &g), 0,
+ "AllocAndRead primary invalid");
+ TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
+ g.gpt_drive_sectors, 0, g.sector_bytes),
+ 1, "Primary header is invalid");
+ TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
+ g.gpt_drive_sectors, 0, g.sector_bytes),
+ 0, "Secondary header is valid");
+ TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
+ "VbExDiskRead(h, 1023, 1)\n"
+ "VbExDiskRead(h, 991, 32)\n");
+ WriteAndFreeGptData(handle, &g);
+
+ /*
+ * Invalidate secondary GPT header,
+ * check that AllocAndReadGptData still succeeds
+ */
+ ResetMocks();
+ memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
+ TEST_EQ(AllocAndReadGptData(handle, &g), 0,
+ "AllocAndRead secondary invalid");
+ TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
+ g.gpt_drive_sectors, 0, g.sector_bytes),
+ 0, "Primary header is valid");
+ TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
+ g.gpt_drive_sectors, 0, g.sector_bytes),
+ 1, "Secondary header is invalid");
+ TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
+ "VbExDiskRead(h, 2, 32)\n"
+ "VbExDiskRead(h, 1023, 1)\n");
+ WriteAndFreeGptData(handle, &g);
+
+ /*
+ * Invalidate primary AND secondary GPT header,
+ * check that AllocAndReadGptData fails.
+ */
+ ResetMocks();
+ memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
+ memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
+ TEST_EQ(AllocAndReadGptData(handle, &g), 1,
+ "AllocAndRead primary and secondary invalid");
+ TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
+ g.gpt_drive_sectors, 0, g.sector_bytes),
+ 1, "Primary header is invalid");
+ TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
+ g.gpt_drive_sectors, 0, g.sector_bytes),
+ 1, "Secondary header is invalid");
+ TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
+ "VbExDiskRead(h, 1023, 1)\n");
+ WriteAndFreeGptData(handle, &g);
+
+ /*
+ * Invalidate primary GPT header and check that it is
+ * repaired by GptRepair().
+ *
+ * This would normally be called by LoadKernel()->GptInit()
+ * but this callback is mocked in these tests.
+ */
+ ResetMocks();
+ memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
+ TEST_EQ(AllocAndReadGptData(handle, &g), 0,
+ "Fix Primary GPT: AllocAndRead");
+ /* Call GptRepair() with input indicating secondary GPT is valid */
+ g.valid_headers = g.valid_entries = MASK_SECONDARY;
+ GptRepair(&g);
+ TEST_EQ(WriteAndFreeGptData(handle, &g), 0,
+ "Fix Primary GPT: WriteAndFreeGptData");
+ TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
+ "VbExDiskRead(h, 1023, 1)\n"
+ "VbExDiskRead(h, 991, 32)\n"
+ "VbExDiskWrite(h, 1, 1)\n"
+ "VbExDiskWrite(h, 2, 32)\n");
+ TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
+ g.gpt_drive_sectors, 0, g.sector_bytes),
+ 0, "Fix Primary GPT: Primary header is valid");
+
+ /*
+ * Invalidate secondary GPT header and check that it can be
+ * repaired by GptRepair().
+ *
+ * This would normally be called by LoadKernel()->GptInit()
+ * but this callback is mocked in these tests.
+ */
+ ResetMocks();
+ memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
+ TEST_EQ(AllocAndReadGptData(handle, &g), 0,
+ "Fix Secondary GPT: AllocAndRead");
+ /* Call GptRepair() with input indicating primary GPT is valid */
+ g.valid_headers = g.valid_entries = MASK_PRIMARY;
+ GptRepair(&g);
+ TEST_EQ(WriteAndFreeGptData(handle, &g), 0,
+ "Fix Secondary GPT: WriteAndFreeGptData");
+ TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
+ "VbExDiskRead(h, 2, 32)\n"
+ "VbExDiskRead(h, 1023, 1)\n"
+ "VbExDiskWrite(h, 1023, 1)\n"
+ "VbExDiskWrite(h, 991, 32)\n");
+ TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
+ g.gpt_drive_sectors, 0, g.sector_bytes),
+ 0, "Fix Secondary GPT: Secondary header is valid");
+
+ /* Data which is changed is written */
+ ResetMocks();
+ AllocAndReadGptData(handle, &g);
+ g.modified |= GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1;
+ ResetCallLog();
+ memset(g.primary_header, '\0', g.sector_bytes);
+ h = (GptHeader*)g.primary_header;
+ h->entries_lba = 2;
+ h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
+ h->size_of_entry = sizeof(GptEntry);
+ TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
+ TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
+ "VbExDiskWrite(h, 2, 32)\n");
+
+ /* Data which is changed is written */
+ ResetMocks();
+ AllocAndReadGptData(handle, &g);
+ g.modified = -1;
+ ResetCallLog();
+ memset(g.primary_header, '\0', g.sector_bytes);
+ h = (GptHeader*)g.primary_header;
+ h->entries_lba = 2;
+ h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
+ h->size_of_entry = sizeof(GptEntry);
+ h = (GptHeader*)g.secondary_header;
+ h->entries_lba = 991;
+ TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
+ TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
+ "VbExDiskWrite(h, 2, 32)\n"
+ "VbExDiskWrite(h, 1023, 1)\n"
+ "VbExDiskWrite(h, 991, 32)\n");
+
+ /* If legacy signature, don't modify GPT header/entries 1 */
+ ResetMocks();
+ AllocAndReadGptData(handle, &g);
+ h = (GptHeader *)g.primary_header;
+ memcpy(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE);
+ g.modified = -1;
+ ResetCallLog();
+ TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
+ TEST_CALLS("VbExDiskWrite(h, 1023, 1)\n"
+ "VbExDiskWrite(h, 991, 32)\n");
+
+ /* Error reading */
+ ResetMocks();
+ disk_read_to_fail = 1;
+ TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
+ g.valid_headers = g.valid_entries = MASK_SECONDARY;
+ GptRepair(&g);
+ ResetCallLog();
+ TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
+ TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
+ "VbExDiskWrite(h, 2, 32)\n");
+
+ ResetMocks();
+ disk_read_to_fail = 2;
+ TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
+ g.valid_headers = MASK_BOTH;
+ g.valid_entries = MASK_SECONDARY;
+ GptRepair(&g);
+ ResetCallLog();
+ TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
+ TEST_CALLS("VbExDiskWrite(h, 2, 32)\n");
+
+ ResetMocks();
+ disk_read_to_fail = 991;
+ TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
+ g.valid_headers = MASK_BOTH;
+ g.valid_entries = MASK_PRIMARY;
+ GptRepair(&g);
+ ResetCallLog();
+ TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 2");
+ TEST_CALLS("VbExDiskWrite(h, 991, 32)\n");
+
+ ResetMocks();
+ disk_read_to_fail = 1023;
+ TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
+ g.valid_headers = g.valid_entries = MASK_PRIMARY;
+ GptRepair(&g);
+ ResetCallLog();
+ TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 2");
+ TEST_CALLS("VbExDiskWrite(h, 1023, 1)\n"
+ "VbExDiskWrite(h, 991, 32)\n");
+
+ /* Error writing */
+ ResetMocks();
+ disk_write_to_fail = 1;
+ AllocAndReadGptData(handle, &g);
+ g.modified = -1;
+ memset(g.primary_header, '\0', g.sector_bytes);
+ TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
+
+ ResetMocks();
+ disk_write_to_fail = 2;
+ AllocAndReadGptData(handle, &g);
+ g.modified = -1;
+ memset(g.primary_header, '\0', g.sector_bytes);
+ h = (GptHeader*)g.primary_header;
+ h->entries_lba = 2;
+ TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
+
+ ResetMocks();
+ disk_write_to_fail = 991;
+ AllocAndReadGptData(handle, &g);
+ g.modified = -1;
+ memset(g.primary_header, '\0', g.sector_bytes);
+ TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
+
+ ResetMocks();
+ disk_write_to_fail = 1023;
+ AllocAndReadGptData(handle, &g);
+ g.modified = -1;
+ memset(g.primary_header, '\0', g.sector_bytes);
+ TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
+
+}
+
+int main(void)
+{
+ ReadWriteGptTest();
+
+ return gTestSuccess ? 0 : 255;
+}
diff --git a/tests/vboot_kernel_tests.c b/tests/vboot_kernel_tests.c
index 486602c0..944be0aa 100644
--- a/tests/vboot_kernel_tests.c
+++ b/tests/vboot_kernel_tests.c
@@ -11,23 +11,12 @@
#include "2nvstorage.h"
#include "2secdata.h"
#include "2secdata_struct.h"
-#include "2sha.h"
-#include "2sysincludes.h"
#include "cgptlib.h"
#include "cgptlib_internal.h"
-#include "crc32.h"
#include "gpt.h"
-#include "host_common.h"
#include "load_kernel_fw.h"
#include "test_common.h"
#include "vboot_api.h"
-#include "vboot_kernel.h"
-
-#define LOGCALL(fmt, args...) sprintf(call_log + strlen(call_log), fmt, ##args)
-#define TEST_CALLS(expect_log) TEST_STR_EQ(call_log, expect_log, " calls")
-
-#define MOCK_SECTOR_SIZE 512
-#define MOCK_SECTOR_COUNT 1024
/* Mock kernel partition */
struct mock_part {
@@ -41,10 +30,8 @@ static struct mock_part mock_parts[MOCK_PART_COUNT];
static int mock_part_next;
/* Mock data */
-static char call_log[4096];
static uint8_t kernel_buffer[80000];
static int disk_read_to_fail;
-static int disk_write_to_fail;
static int gpt_init_fail;
static int keyblock_verify_fail; /* 0=ok, 1=sig, 2=hash */
static int preamble_verify_fail;
@@ -53,17 +40,11 @@ static int unpack_key_fail;
static int gpt_flag_external;
static struct vb2_gbb_header gbb;
-static VbExDiskHandle_t handle;
static VbSelectAndLoadKernelParams lkp;
static VbDiskInfo disk_info;
static struct vb2_keyblock kbh;
static struct vb2_kernel_preamble kph;
static struct vb2_secdata_fwmp *fwmp;
-static uint8_t mock_disk[MOCK_SECTOR_SIZE * MOCK_SECTOR_COUNT];
-static GptHeader *mock_gpt_primary =
- (GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * 1];
-static GptHeader *mock_gpt_secondary =
- (GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * (MOCK_SECTOR_COUNT - 1)];
static uint8_t mock_digest[VB2_SHA256_DIGEST_SIZE] = {12, 34, 56, 78};
static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
__attribute__((aligned(VB2_WORKBUF_ALIGN)));
@@ -72,56 +53,11 @@ static struct vb2_shared_data *sd;
static struct vb2_packed_key mock_key;
/**
- * Prepare a valid GPT header that will pass CheckHeader() tests
- */
-static void SetupGptHeader(GptHeader *h, int is_secondary)
-{
- memset(h, '\0', MOCK_SECTOR_SIZE);
-
- /* "EFI PART" */
- memcpy(h->signature, GPT_HEADER_SIGNATURE, GPT_HEADER_SIGNATURE_SIZE);
- h->revision = GPT_HEADER_REVISION;
- h->size = MIN_SIZE_OF_HEADER;
-
- /* 16KB: 128 entries of 128 bytes */
- h->size_of_entry = sizeof(GptEntry);
- h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
-
- /* Set LBA pointers for primary or secondary header */
- if (is_secondary) {
- h->my_lba = MOCK_SECTOR_COUNT - GPT_HEADER_SECTORS;
- h->entries_lba = h->my_lba - CalculateEntriesSectors(h,
- MOCK_SECTOR_SIZE);
- } else {
- h->my_lba = GPT_PMBR_SECTORS;
- h->entries_lba = h->my_lba + 1;
- }
-
- h->first_usable_lba = 2 + CalculateEntriesSectors(h, MOCK_SECTOR_SIZE);
- h->last_usable_lba = MOCK_SECTOR_COUNT - 2 - CalculateEntriesSectors(h,
- MOCK_SECTOR_SIZE);
-
- h->header_crc32 = HeaderCrc(h);
-}
-
-static void ResetCallLog(void)
-{
- *call_log = 0;
-}
-
-/**
* Reset mock data (for use before each test)
*/
static void ResetMocks(void)
{
- ResetCallLog();
-
- memset(&mock_disk, 0, sizeof(mock_disk));
- SetupGptHeader(mock_gpt_primary, 0);
- SetupGptHeader(mock_gpt_secondary, 1);
-
disk_read_to_fail = -1;
- disk_write_to_fail = -1;
gpt_init_fail = 0;
keyblock_verify_fail = 0;
@@ -219,29 +155,15 @@ vb2_error_t vb2_gbb_read_recovery_key(struct vb2_context *c,
vb2_error_t VbExDiskRead(VbExDiskHandle_t h, uint64_t lba_start,
uint64_t lba_count, void *buffer)
{
- LOGCALL("VbExDiskRead(h, %d, %d)\n", (int)lba_start, (int)lba_count);
-
if ((int)lba_start == disk_read_to_fail)
return VB2_ERROR_MOCK;
- memcpy(buffer, &mock_disk[lba_start * MOCK_SECTOR_SIZE],
- lba_count * MOCK_SECTOR_SIZE);
-
return VB2_SUCCESS;
}
-vb2_error_t VbExDiskWrite(VbExDiskHandle_t h, uint64_t lba_start,
- uint64_t lba_count, const void *buffer)
+int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
{
- LOGCALL("VbExDiskWrite(h, %d, %d)\n", (int)lba_start, (int)lba_count);
-
- if ((int)lba_start == disk_write_to_fail)
- return VB2_ERROR_MOCK;
-
- memcpy(&mock_disk[lba_start * MOCK_SECTOR_SIZE], buffer,
- lba_count * MOCK_SECTOR_SIZE);
-
- return VB2_SUCCESS;
+ return GPT_SUCCESS;
}
int GptInit(GptData *gpt)
@@ -266,6 +188,16 @@ int GptNextKernelEntry(GptData *gpt, uint64_t *start_sector, uint64_t *size)
return GPT_SUCCESS;
}
+int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type)
+{
+ return GPT_SUCCESS;
+}
+
+int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
+{
+ return GPT_SUCCESS;
+}
+
void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest)
{
static char fake_guid[] = "FakeGuid";
@@ -343,257 +275,6 @@ void vb2api_fail(struct vb2_context *c, uint8_t reason, uint8_t subcode)
TEST_TRUE(0, " called vb2api_fail()");
}
-/**
- * Test reading/writing GPT
- */
-static void ReadWriteGptTest(void)
-{
- GptData g;
- GptHeader *h;
-
- g.sector_bytes = MOCK_SECTOR_SIZE;
- g.streaming_drive_sectors = g.gpt_drive_sectors = MOCK_SECTOR_COUNT;
- g.valid_headers = g.valid_entries = MASK_BOTH;
-
- ResetMocks();
- TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead");
- TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
- "VbExDiskRead(h, 2, 32)\n"
- "VbExDiskRead(h, 1023, 1)\n"
- "VbExDiskRead(h, 991, 32)\n");
- ResetCallLog();
- /*
- * Valgrind complains about access to uninitialized memory here, so
- * zero the primary header before each test.
- */
- memset(g.primary_header, '\0', g.sector_bytes);
- TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree");
- TEST_CALLS("");
-
- /*
- * Invalidate primary GPT header,
- * check that AllocAndReadGptData still succeeds
- */
- ResetMocks();
- memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
- TEST_EQ(AllocAndReadGptData(handle, &g), 0,
- "AllocAndRead primary invalid");
- TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
- g.gpt_drive_sectors, 0, g.sector_bytes),
- 1, "Primary header is invalid");
- TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
- g.gpt_drive_sectors, 0, g.sector_bytes),
- 0, "Secondary header is valid");
- TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
- "VbExDiskRead(h, 1023, 1)\n"
- "VbExDiskRead(h, 991, 32)\n");
- WriteAndFreeGptData(handle, &g);
-
- /*
- * Invalidate secondary GPT header,
- * check that AllocAndReadGptData still succeeds
- */
- ResetMocks();
- memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
- TEST_EQ(AllocAndReadGptData(handle, &g), 0,
- "AllocAndRead secondary invalid");
- TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
- g.gpt_drive_sectors, 0, g.sector_bytes),
- 0, "Primary header is valid");
- TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
- g.gpt_drive_sectors, 0, g.sector_bytes),
- 1, "Secondary header is invalid");
- TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
- "VbExDiskRead(h, 2, 32)\n"
- "VbExDiskRead(h, 1023, 1)\n");
- WriteAndFreeGptData(handle, &g);
-
- /*
- * Invalidate primary AND secondary GPT header,
- * check that AllocAndReadGptData fails.
- */
- ResetMocks();
- memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
- memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
- TEST_EQ(AllocAndReadGptData(handle, &g), 1,
- "AllocAndRead primary and secondary invalid");
- TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
- g.gpt_drive_sectors, 0, g.sector_bytes),
- 1, "Primary header is invalid");
- TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
- g.gpt_drive_sectors, 0, g.sector_bytes),
- 1, "Secondary header is invalid");
- TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
- "VbExDiskRead(h, 1023, 1)\n");
- WriteAndFreeGptData(handle, &g);
-
- /*
- * Invalidate primary GPT header and check that it is
- * repaired by GptRepair().
- *
- * This would normally be called by LoadKernel()->GptInit()
- * but this callback is mocked in these tests.
- */
- ResetMocks();
- memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
- TEST_EQ(AllocAndReadGptData(handle, &g), 0,
- "Fix Primary GPT: AllocAndRead");
- /* Call GptRepair() with input indicating secondary GPT is valid */
- g.valid_headers = g.valid_entries = MASK_SECONDARY;
- GptRepair(&g);
- TEST_EQ(WriteAndFreeGptData(handle, &g), 0,
- "Fix Primary GPT: WriteAndFreeGptData");
- TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
- "VbExDiskRead(h, 1023, 1)\n"
- "VbExDiskRead(h, 991, 32)\n"
- "VbExDiskWrite(h, 1, 1)\n"
- "VbExDiskWrite(h, 2, 32)\n");
- TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
- g.gpt_drive_sectors, 0, g.sector_bytes),
- 0, "Fix Primary GPT: Primary header is valid");
-
- /*
- * Invalidate secondary GPT header and check that it can be
- * repaired by GptRepair().
- *
- * This would normally be called by LoadKernel()->GptInit()
- * but this callback is mocked in these tests.
- */
- ResetMocks();
- memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
- TEST_EQ(AllocAndReadGptData(handle, &g), 0,
- "Fix Secondary GPT: AllocAndRead");
- /* Call GptRepair() with input indicating primary GPT is valid */
- g.valid_headers = g.valid_entries = MASK_PRIMARY;
- GptRepair(&g);
- TEST_EQ(WriteAndFreeGptData(handle, &g), 0,
- "Fix Secondary GPT: WriteAndFreeGptData");
- TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
- "VbExDiskRead(h, 2, 32)\n"
- "VbExDiskRead(h, 1023, 1)\n"
- "VbExDiskWrite(h, 1023, 1)\n"
- "VbExDiskWrite(h, 991, 32)\n");
- TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
- g.gpt_drive_sectors, 0, g.sector_bytes),
- 0, "Fix Secondary GPT: Secondary header is valid");
-
- /* Data which is changed is written */
- ResetMocks();
- AllocAndReadGptData(handle, &g);
- g.modified |= GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1;
- ResetCallLog();
- memset(g.primary_header, '\0', g.sector_bytes);
- h = (GptHeader*)g.primary_header;
- h->entries_lba = 2;
- h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
- h->size_of_entry = sizeof(GptEntry);
- TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
- TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
- "VbExDiskWrite(h, 2, 32)\n");
-
- /* Data which is changed is written */
- ResetMocks();
- AllocAndReadGptData(handle, &g);
- g.modified = -1;
- ResetCallLog();
- memset(g.primary_header, '\0', g.sector_bytes);
- h = (GptHeader*)g.primary_header;
- h->entries_lba = 2;
- h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
- h->size_of_entry = sizeof(GptEntry);
- h = (GptHeader*)g.secondary_header;
- h->entries_lba = 991;
- TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
- TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
- "VbExDiskWrite(h, 2, 32)\n"
- "VbExDiskWrite(h, 1023, 1)\n"
- "VbExDiskWrite(h, 991, 32)\n");
-
- /* If legacy signature, don't modify GPT header/entries 1 */
- ResetMocks();
- AllocAndReadGptData(handle, &g);
- h = (GptHeader *)g.primary_header;
- memcpy(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE);
- g.modified = -1;
- ResetCallLog();
- TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
- TEST_CALLS("VbExDiskWrite(h, 1023, 1)\n"
- "VbExDiskWrite(h, 991, 32)\n");
-
- /* Error reading */
- ResetMocks();
- disk_read_to_fail = 1;
- TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
- g.valid_headers = g.valid_entries = MASK_SECONDARY;
- GptRepair(&g);
- ResetCallLog();
- TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
- TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
- "VbExDiskWrite(h, 2, 32)\n");
-
- ResetMocks();
- disk_read_to_fail = 2;
- TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
- g.valid_headers = MASK_BOTH;
- g.valid_entries = MASK_SECONDARY;
- GptRepair(&g);
- ResetCallLog();
- TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
- TEST_CALLS("VbExDiskWrite(h, 2, 32)\n");
-
- ResetMocks();
- disk_read_to_fail = 991;
- TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
- g.valid_headers = MASK_BOTH;
- g.valid_entries = MASK_PRIMARY;
- GptRepair(&g);
- ResetCallLog();
- TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 2");
- TEST_CALLS("VbExDiskWrite(h, 991, 32)\n");
-
- ResetMocks();
- disk_read_to_fail = 1023;
- TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
- g.valid_headers = g.valid_entries = MASK_PRIMARY;
- GptRepair(&g);
- ResetCallLog();
- TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 2");
- TEST_CALLS("VbExDiskWrite(h, 1023, 1)\n"
- "VbExDiskWrite(h, 991, 32)\n");
-
- /* Error writing */
- ResetMocks();
- disk_write_to_fail = 1;
- AllocAndReadGptData(handle, &g);
- g.modified = -1;
- memset(g.primary_header, '\0', g.sector_bytes);
- TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
-
- ResetMocks();
- disk_write_to_fail = 2;
- AllocAndReadGptData(handle, &g);
- g.modified = -1;
- memset(g.primary_header, '\0', g.sector_bytes);
- h = (GptHeader*)g.primary_header;
- h->entries_lba = 2;
- TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
-
- ResetMocks();
- disk_write_to_fail = 991;
- AllocAndReadGptData(handle, &g);
- g.modified = -1;
- memset(g.primary_header, '\0', g.sector_bytes);
- TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
-
- ResetMocks();
- disk_write_to_fail = 1023;
- AllocAndReadGptData(handle, &g);
- g.modified = -1;
- memset(g.primary_header, '\0', g.sector_bytes);
- TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
-
-}
-
static void TestLoadKernel(int expect_retval, const char *test_name)
{
TEST_EQ(LoadKernel(ctx, &lkp, &disk_info), expect_retval, test_name);
@@ -878,7 +559,6 @@ static void LoadKernelTest(void)
int main(void)
{
- ReadWriteGptTest();
InvalidParamsTest();
LoadKernelTest();