summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-02-01 13:31:20 -0800
committerChromeBot <chrome-bot@google.com>2013-02-01 16:14:30 -0800
commit3e9cf90442632bed695ac0552a76ca0d1154f799 (patch)
tree8b768b506c41afc82139df72f689917b51d7cbb2
parent5d0a2e7b391649b6ba5a5fc4c87097a191e594c8 (diff)
downloadvboot-stabilize-3658.0.0.tar.gz
Add even more load kernel testsstabilize-3658.0.0
BUG=chromium-os:38139 BRANCH=none TEST=make runtests && FEATURES=test emerge-daisy vboot_reference Change-Id: I49ac7f64c1d0ef17afab5dcc8fcb9f777d6cab1c Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/42472 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--tests/vboot_kernel_tests.c138
1 files changed, 133 insertions, 5 deletions
diff --git a/tests/vboot_kernel_tests.c b/tests/vboot_kernel_tests.c
index 7e7beca6..1ee1528f 100644
--- a/tests/vboot_kernel_tests.c
+++ b/tests/vboot_kernel_tests.c
@@ -42,6 +42,7 @@ static int disk_write_to_fail;
static int gpt_init_fail;
static int key_block_verify_fail; /* 0=ok, 1=sig, 2=hash */
static int preamble_verify_fail;
+static int verify_data_fail;
static RSAPublicKey *mock_data_key;
static int mock_data_key_allocated;
@@ -72,6 +73,7 @@ static void ResetMocks(void)
gpt_init_fail = 0;
key_block_verify_fail = 0;
preamble_verify_fail = 0;
+ verify_data_fail = 0;
mock_data_key = (RSAPublicKey *)"TestDataKey";
mock_data_key_allocated = 0;
@@ -107,6 +109,8 @@ static void ResetMocks(void)
kph.kernel_version = 1;
kph.preamble_size = 4096 - kbh.key_block_size;
kph.body_signature.data_size = 70000;
+ kph.bootloader_address = 0xbeadd008;
+ kph.bootloader_size = 0x1234;
memset(mock_parts, 0, sizeof(mock_parts));
mock_parts[0].start = 100;
@@ -157,6 +161,13 @@ int GptNextKernelEntry(GptData *gpt, uint64_t *start_sector, uint64_t *size)
return GPT_SUCCESS;
}
+void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest)
+{
+ static char fake_guid[] = "FakeGuid";
+
+ memcpy(dest, fake_guid, sizeof(fake_guid));
+}
+
int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
const VbPublicKey *key, int hash_only) {
@@ -198,6 +209,16 @@ int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
return VBERROR_SUCCESS;
}
+int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
+ const RSAPublicKey *key)
+{
+ if (verify_data_fail)
+ return VBERROR_SIMULATED;
+
+ return VBERROR_SUCCESS;
+}
+
+
/**
* Test reading/writing GPT
*/
@@ -256,12 +277,46 @@ static void ReadWriteGptTest(void)
TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
WriteAndFreeGptData(handle, &g);
+ ResetMocks();
+ disk_read_to_fail = 2;
+ TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
+ WriteAndFreeGptData(handle, &g);
+
+ ResetMocks();
+ disk_read_to_fail = 991;
+ TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
+ WriteAndFreeGptData(handle, &g);
+
+ ResetMocks();
+ disk_read_to_fail = 1023;
+ TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
+ WriteAndFreeGptData(handle, &g);
+
/* Error writing */
ResetMocks();
disk_write_to_fail = 1;
AllocAndReadGptData(handle, &g);
g.modified = -1;
TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
+
+ ResetMocks();
+ disk_write_to_fail = 2;
+ AllocAndReadGptData(handle, &g);
+ g.modified = -1;
+ TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
+
+ ResetMocks();
+ disk_write_to_fail = 991;
+ AllocAndReadGptData(handle, &g);
+ g.modified = -1;
+ TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
+
+ ResetMocks();
+ disk_write_to_fail = 1023;
+ AllocAndReadGptData(handle, &g);
+ g.modified = -1;
+ TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
+
}
/**
@@ -290,17 +345,39 @@ static void InvalidParamsTest(void)
TEST_EQ(LoadKernel(&lkp), VBERROR_NO_KERNEL_FOUND, "Bad GPT");
}
-static void KernelLoopTest(void)
+static void LoadKernelTest(void)
{
+ uint32_t u;
+
+ ResetMocks();
+ TEST_EQ(LoadKernel(&lkp), 0, "First kernel good");
+ TEST_EQ(lkp.partition_number, 1, " part num");
+ TEST_EQ(lkp.bootloader_address, 0xbeadd008, " bootloader addr");
+ TEST_EQ(lkp.bootloader_size, 0x1234, " bootloader size");
+ TEST_STR_EQ((char *)lkp.partition_guid, "FakeGuid", " guid");
+ VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
+ TEST_EQ(u, 0, " recovery request");
+
+ ResetMocks();
+ mock_parts[1].start = 300;
+ mock_parts[1].size = 150;
+ TEST_EQ(LoadKernel(&lkp), 0, "Two good kernels");
+ TEST_EQ(lkp.partition_number, 1, " part num");
+ TEST_EQ(mock_part_next, 1, " didn't read second one");
+
/* Fail if no kernels found */
ResetMocks();
mock_parts[0].size = 0;
TEST_EQ(LoadKernel(&lkp), VBERROR_NO_KERNEL_FOUND, "No kernels");
+ VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
+ TEST_EQ(u, VBNV_RECOVERY_RW_NO_OS, " recovery request");
/* Skip kernels which are too small */
ResetMocks();
mock_parts[0].size = 10;
TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_KERNEL_FOUND, "Too small");
+ VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
+ TEST_EQ(u, VBNV_RECOVERY_RW_INVALID_OS, " recovery request");
ResetMocks();
disk_read_to_fail = 100;
@@ -319,6 +396,12 @@ static void KernelLoopTest(void)
TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_KERNEL_FOUND,
"Fail key block dev hash");
+ /* But just bad sig is ok */
+ ResetMocks();
+ lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
+ key_block_verify_fail = 1;
+ TEST_EQ(LoadKernel(&lkp), 0, "Succeed key block dev sig");
+
/* In dev mode and requiring signed kernel, fail if sig is bad */
ResetMocks();
lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
@@ -365,8 +448,28 @@ static void KernelLoopTest(void)
TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_KERNEL_FOUND,
"Key block kernel key version too big");
- /* TODO: key version ignored in recovery mode */
- /* TODO: key block validity ignored in dev mode */
+ ResetMocks();
+ kbh.data_key.key_version = 3;
+ TEST_EQ(LoadKernel(&lkp), 0, "Key block version roll forward");
+ TEST_EQ(shared->kernel_version_tpm, 0x30001, " shared version");
+
+ ResetMocks();
+ kbh.data_key.key_version = 3;
+ mock_parts[1].start = 300;
+ mock_parts[1].size = 150;
+ TEST_EQ(LoadKernel(&lkp), 0, "Two kernels roll forward");
+ TEST_EQ(mock_part_next, 2, " read both");
+ TEST_EQ(shared->kernel_version_tpm, 0x30001, " shared version");
+
+ ResetMocks();
+ kbh.data_key.key_version = 1;
+ lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
+ TEST_EQ(LoadKernel(&lkp), 0, "Key version ignored in dev mode");
+
+ ResetMocks();
+ kbh.data_key.key_version = 1;
+ lkp.boot_flags |= BOOT_FLAG_RECOVERY;
+ TEST_EQ(LoadKernel(&lkp), 0, "Key version ignored in rec mode");
ResetMocks();
mock_data_key = NULL;
@@ -381,13 +484,30 @@ static void KernelLoopTest(void)
TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_KERNEL_FOUND,
"Kernel version rollback");
- /* TODO: kernel version ignored in recovery and dev modes */
+ ResetMocks();
+ kph.kernel_version = 0;
+ lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
+ TEST_EQ(LoadKernel(&lkp), 0, "Kernel version ignored in dev mode");
+
+ ResetMocks();
+ kph.kernel_version = 0;
+ lkp.boot_flags |= BOOT_FLAG_RECOVERY;
+ TEST_EQ(LoadKernel(&lkp), 0, "Kernel version ignored in rec mode");
ResetMocks();
kph.preamble_size |= 0x07;
TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_KERNEL_FOUND,
"Kernel body offset");
+ /* Check getting kernel load address from header */
+ ResetMocks();
+ kph.body_load_address = (size_t)kernel_buffer;
+ lkp.kernel_buffer = NULL;
+ TEST_EQ(LoadKernel(&lkp), 0, "Get load address from preamble");
+ TEST_PTR_EQ(lkp.kernel_buffer, kernel_buffer, " address");
+ /* Size is rounded up to nearest sector */
+ TEST_EQ(lkp.kernel_buffer_size, 70144, " size");
+
ResetMocks();
lkp.kernel_buffer_size = 8192;
TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_KERNEL_FOUND,
@@ -398,13 +518,21 @@ static void KernelLoopTest(void)
TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_KERNEL_FOUND,
"Kernel too big for partition");
+ ResetMocks();
+ disk_read_to_fail = 108;
+ TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_KERNEL_FOUND,
+ "Fail reading kernel data");
+
+ ResetMocks();
+ verify_data_fail = 1;
+ TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_KERNEL_FOUND, "Bad data");
}
int main(void)
{
ReadWriteGptTest();
InvalidParamsTest();
- KernelLoopTest();
+ LoadKernelTest();
return gTestSuccess ? 0 : 255;
}