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

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