Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Unified Diff: firmware/lib/vboot_kernel.c

Issue 3186013: Security fixes for LoadKernel() (Closed) Base URL: ssh://gitrw.chromium.org/vboot_reference.git
Patch Set: Add local var for offset sectors Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | firmware/version.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: firmware/lib/vboot_kernel.c
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c
index 2402a090eae25c1b724db43b0c4b7e3bb24e609d..d1d4004b32fb8633fca4bc0b309475ee5d84039d 100644
--- a/firmware/lib/vboot_kernel.c
+++ b/firmware/lib/vboot_kernel.c
@@ -141,6 +141,11 @@ int LoadKernel(LoadKernelParams* params) {
kernel_subkey = (VbPublicKey*)params->header_sign_key_blob;
blba = params->bytes_per_lba;
kbuf_sectors = KBUF_SIZE / blba;
+ if (0 == kbuf_sectors) {
+ VBDEBUG(("LoadKernel() called with sector size > KBUF_SIZE\n"));
+ return LOAD_KERNEL_INVALID;
+ }
+
is_dev = (BOOT_FLAG_DEVELOPER & params->boot_flags ? 1 : 0);
is_rec = (BOOT_FLAG_RECOVERY & params->boot_flags ? 1 : 0);
is_normal = (!is_dev && !is_rec);
@@ -198,6 +203,8 @@ int LoadKernel(LoadKernelParams* params) {
uint64_t key_version;
uint64_t combined_version;
uint64_t body_offset;
+ uint64_t body_offset_sectors;
+ uint64_t body_sectors;
VBDEBUG(("Found kernel entry at %" PRIu64 " size %" PRIu64 "\n",
part_start, part_size));
@@ -299,20 +306,27 @@ int LoadKernel(LoadKernelParams* params) {
RSAPublicKeyFree(data_key);
continue;
}
+ body_offset_sectors = body_offset / blba;
+
+ /* Verify kernel body fits in the buffer */
+ body_sectors = (preamble->body_signature.data_size + blba - 1) / blba;
+ if (body_sectors * blba > params->kernel_buffer_size) {
+ VBDEBUG(("Kernel body doesn't fit in memory.\n"));
+ RSAPublicKeyFree(data_key);
+ continue;
+ }
/* Verify kernel body fits in the partition */
- if (body_offset + preamble->body_signature.data_size >
- part_size * blba) {
+ if (body_offset_sectors + body_sectors > part_size) {
VBDEBUG(("Kernel body doesn't fit in partition.\n"));
RSAPublicKeyFree(data_key);
continue;
}
/* Read the kernel data */
- if (0 != BootDeviceReadLBA(
- part_start + (body_offset / blba),
- (preamble->body_signature.data_size + blba - 1) / blba,
- params->kernel_buffer)) {
+ if (0 != BootDeviceReadLBA(part_start + body_offset_sectors,
+ body_sectors,
+ params->kernel_buffer)) {
VBDEBUG(("Unable to read kernel data.\n"));
RSAPublicKeyFree(data_key);
continue;
« no previous file with comments | « no previous file | firmware/version.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698