Blame SOURCES/kvm-multiboot-validate-multiboot-header-address-values.patch

9bac43
From de21908e4f8daf06b67ba2118c5d2e41da9c51a6 Mon Sep 17 00:00:00 2001
9bac43
From: Bandan Das <bsd@redhat.com>
9bac43
Date: Thu, 26 Oct 2017 09:55:58 +0200
9bac43
Subject: [PATCH 1/7] multiboot: validate multiboot header address values
9bac43
9bac43
RH-Author: Bandan Das <bsd@redhat.com>
9bac43
Message-id: <jpgh8ump70x.fsf@linux.bootlegged.copy>
9bac43
Patchwork-id: 77442
9bac43
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] multiboot: validate multiboot header address values
9bac43
Bugzilla: 1501124
9bac43
RH-Acked-by: Thomas Huth <thuth@redhat.com>
9bac43
RH-Acked-by: Peter Xu <peterx@redhat.com>
9bac43
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
9bac43
9bac43
While loading kernel via multiboot-v1 image, (flags & 0x00010000)
9bac43
indicates that multiboot header contains valid addresses to load
9bac43
the kernel image. These addresses are used to compute kernel
9bac43
size and kernel text offset in the OS image. Validate these
9bac43
address values to avoid an OOB access issue.
9bac43
9bac43
This is CVE-2017-14167.
9bac43
9bac43
Reported-by: Thomas Garnier <thgarnie@google.com>
9bac43
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
9bac43
Message-Id: <20170907063256.7418-1-ppandit@redhat.com>
9bac43
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9bac43
(cherry picked from commit ed4f86e8b6eff8e600c69adee68c7cd34dd2cccb)
9bac43
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9bac43
---
9bac43
 hw/i386/multiboot.c | 19 +++++++++++++++++++
9bac43
 1 file changed, 19 insertions(+)
9bac43
9bac43
diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
9bac43
index f13e231..22688d3 100644
9bac43
--- a/hw/i386/multiboot.c
9bac43
+++ b/hw/i386/multiboot.c
9bac43
@@ -221,15 +221,34 @@ int load_multiboot(FWCfgState *fw_cfg,
9bac43
         uint32_t mh_header_addr = ldl_p(header+i+12);
9bac43
         uint32_t mh_load_end_addr = ldl_p(header+i+20);
9bac43
         uint32_t mh_bss_end_addr = ldl_p(header+i+24);
9bac43
+
9bac43
         mh_load_addr = ldl_p(header+i+16);
9bac43
+        if (mh_header_addr < mh_load_addr) {
9bac43
+            fprintf(stderr, "invalid mh_load_addr address\n");
9bac43
+            exit(1);
9bac43
+        }
9bac43
+
9bac43
         uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
9bac43
         uint32_t mb_load_size = 0;
9bac43
         mh_entry_addr = ldl_p(header+i+28);
9bac43
 
9bac43
         if (mh_load_end_addr) {
9bac43
+            if (mh_bss_end_addr < mh_load_addr) {
9bac43
+                fprintf(stderr, "invalid mh_bss_end_addr address\n");
9bac43
+                exit(1);
9bac43
+            }
9bac43
             mb_kernel_size = mh_bss_end_addr - mh_load_addr;
9bac43
+
9bac43
+            if (mh_load_end_addr < mh_load_addr) {
9bac43
+                fprintf(stderr, "invalid mh_load_end_addr address\n");
9bac43
+                exit(1);
9bac43
+            }
9bac43
             mb_load_size = mh_load_end_addr - mh_load_addr;
9bac43
         } else {
9bac43
+            if (kernel_file_size < mb_kernel_text_offset) {
9bac43
+                fprintf(stderr, "invalid kernel_file_size\n");
9bac43
+                exit(1);
9bac43
+            }
9bac43
             mb_kernel_size = kernel_file_size - mb_kernel_text_offset;
9bac43
             mb_load_size = mb_kernel_size;
9bac43
         }
9bac43
-- 
9bac43
1.8.3.1
9bac43