summaryrefslogtreecommitdiff
path: root/firmware/lib/vboot_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/lib/vboot_common.c')
-rw-r--r--firmware/lib/vboot_common.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/firmware/lib/vboot_common.c b/firmware/lib/vboot_common.c
index 3811e1ef..2cb01f37 100644
--- a/firmware/lib/vboot_common.c
+++ b/firmware/lib/vboot_common.c
@@ -435,10 +435,54 @@ int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
return VBOOT_PREAMBLE_INVALID;
}
+ /*
+ * If the preamble header version is at least 2.1, verify we have space
+ * for the added fields from 2.1.
+ */
+ if (preamble->header_version_minor >= 1) {
+ if(size < EXPECTED_VBKERNELPREAMBLEHEADER2_1_SIZE) {
+ VBDEBUG(("Not enough data for preamble header 2.1.\n"));
+ return VBOOT_PREAMBLE_INVALID;
+ }
+ }
+
/* Success */
return VBOOT_SUCCESS;
}
+int VbGetKernelVmlinuzHeader(const VbKernelPreambleHeader *preamble,
+ uint64_t *vmlinuz_header_address,
+ uint64_t *vmlinuz_header_size)
+{
+ *vmlinuz_header_address = 0;
+ *vmlinuz_header_size = 0;
+ if (preamble->header_version_minor > 0) {
+ /*
+ * Set header and size only if the preamble header version is >
+ * 2.1 as they don't exist in version 2.0 (Note that we don't
+ * need to check header_version_major; if that's not 2 then
+ * VerifyKernelPreamble() would have already failed.
+ */
+ *vmlinuz_header_address = preamble->vmlinuz_header_address;
+ *vmlinuz_header_size = preamble->vmlinuz_header_size;
+ }
+ return VBOOT_SUCCESS;
+}
+
+int VerifyVmlinuzInsideKBlob(uint64_t kblob, uint64_t kblob_size,
+ uint64_t header, uint64_t header_size)
+{
+ uint64_t end = header-kblob;
+ if (end > kblob_size)
+ return VBOOT_PREAMBLE_INVALID;
+ if (UINT64_MAX - end < header_size)
+ return VBOOT_PREAMBLE_INVALID;
+ if (end + header_size > kblob_size)
+ return VBOOT_PREAMBLE_INVALID;
+
+ return VBOOT_SUCCESS;
+}
+
uint64_t VbSharedDataReserve(VbSharedDataHeader *header, uint64_t size)
{
uint64_t offs = header->data_used;