summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2017-10-30 15:28:53 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-11-17 20:18:20 -0800
commit17fb34b647a73bb55fac876a9b20c2c90844ea2e (patch)
treea574ae9d7cfd9c680b19a7b79932e54c5af6c45f
parent4aaaeca130a701a06cb898d9a17eddf67daa3617 (diff)
downloadvboot-17fb34b647a73bb55fac876a9b20c2c90844ea2e.tar.gz
vboot: Use kernel max rollforward NV storage field
Kernel verification will now roll forward the minimum allowable version in the TPM no farther than the kernel_max_rollforward setting. Note that CL:765573 changes chromeos-setgoodkernel so it always sets kernel_max_rollforward to 0xfffffffe when marking a kernel as good. That ensures that firmware with this setting will behave the same for now as existing firmware. BUG=chromium:783997 BRANCH=none CQ-DEPEND=CL:765573 TEST=make runtests Manual testing: crossystem tpm_kernvel --> print current kernel version in TPM - Resign the kernel with a higher version - Reboot - Wait a minute for chromeos-setgoodkernel to run crossystem kernel_max_rollforward=0 - Reboot crossystem tpm_kernvel --> has not changed - Wait a minute for chromeos-setgoodkernel to run crossystem kernel_max_rollforward -> 0xfffffffe - Reboot crossystem tpm_kernvel --> has changed to the higher version Change-Id: Ia32ecb7fa4078548cd311541ccbe120570cf1bc5 Reviewed-on: https://chromium-review.googlesource.com/765574 Commit-Ready: Randall Spangler <rspangler@chromium.org> Tested-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Stefan Reinauer <reinauer@google.com>
-rw-r--r--firmware/lib/vboot_api_kernel.c20
-rw-r--r--tests/vboot_api_kernel4_tests.c17
2 files changed, 36 insertions, 1 deletions
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 2cc1a88b..1879b845 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -188,6 +188,7 @@ VbError_t VbBootNormal(struct vb2_context *ctx, VbCommonParams *cparams)
{
VbSharedDataHeader *shared =
(VbSharedDataHeader *)cparams->shared_data_blob;
+ uint32_t max_rollforward;
/* Boot from fixed disk only */
VB2_DEBUG("Entering\n");
@@ -224,6 +225,25 @@ VbError_t VbBootNormal(struct vb2_context *ctx, VbCommonParams *cparams)
return rv;
}
+ /* Limit kernel version rollforward if needed */
+ if (0 == VbNvGet(&vnc, VBNV_KERNEL_MAX_ROLLFORWARD, &max_rollforward)) {
+ /*
+ * Can't limit kernel version to less than the version
+ * currently in the TPM. That is, we're limiting rollforward,
+ * not allowing rollback.
+ */
+ if (max_rollforward < shared->kernel_version_tpm_start)
+ max_rollforward = shared->kernel_version_tpm_start;
+
+ if (shared->kernel_version_tpm > max_rollforward) {
+ VB2_DEBUG("Limiting TPM kernel version roll-forward "
+ "to 0x%x < 0x%x\n",
+ max_rollforward, shared->kernel_version_tpm);
+
+ shared->kernel_version_tpm = max_rollforward;
+ }
+ }
+
if ((shared->kernel_version_tpm > shared->kernel_version_tpm_start) &&
RollbackKernelWrite(shared->kernel_version_tpm)) {
VB2_DEBUG("Error writing kernel versions to TPM.\n");
diff --git a/tests/vboot_api_kernel4_tests.c b/tests/vboot_api_kernel4_tests.c
index 59650701..e00c928a 100644
--- a/tests/vboot_api_kernel4_tests.c
+++ b/tests/vboot_api_kernel4_tests.c
@@ -53,6 +53,7 @@ static void ResetMocks(void)
memset(&vnc, 0, sizeof(vnc));
VbNvSetup(&vnc);
+ VbNvSet(&vnc, VBNV_KERNEL_MAX_ROLLFORWARD, 0xffffffff);
VbNvTeardown(&vnc); /* So CRC gets generated */
memset(&shared_data, 0, sizeof(shared_data));
@@ -88,7 +89,6 @@ uint32_t RollbackKernelRead(uint32_t *version)
uint32_t RollbackKernelWrite(uint32_t version)
{
- TEST_EQ(version, new_version, "RollbackKernelWrite new version");
rkr_version = version;
return rkw_retval;
}
@@ -150,6 +150,7 @@ static void VbSlkTest(void)
{
ResetMocks();
test_slk(0, 0, "Normal");
+ TEST_EQ(rkr_version, 0x10002, " version");
/*
* If shared->flags doesn't ask for software sync, we won't notice
@@ -183,6 +184,20 @@ static void VbSlkTest(void)
TEST_EQ(rkr_version, 0x10002, " version");
ResetMocks();
+ VbNvSet(&vnc, VBNV_KERNEL_MAX_ROLLFORWARD, 0x30005);
+ VbNvTeardown(&vnc);
+ new_version = 0x40006;
+ test_slk(0, 0, "Limit max roll forward");
+ TEST_EQ(rkr_version, 0x30005, " version");
+
+ ResetMocks();
+ VbNvSet(&vnc, VBNV_KERNEL_MAX_ROLLFORWARD, 0x10001);
+ VbNvTeardown(&vnc);
+ new_version = 0x40006;
+ test_slk(0, 0, "Max roll forward can't rollback");
+ TEST_EQ(rkr_version, 0x10002, " version");
+
+ ResetMocks();
vbboot_retval = VBERROR_INVALID_KERNEL_FOUND;
VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123);
VbNvTeardown(&vnc);