[prev in list] [next in list] [prev in thread] [next in thread]
List: fedora-extras-commits
Subject: [qemu/f20] Fix SLES11 migration issue (bz #1109427) CVE-2014-7840: insufficient parameter validation
From: Cole Robinson <crobinso () fedoraproject ! org>
Date: 2014-11-30 23:12:21
Message-ID: 20141130231221.963D03334C () pkgs01 ! phx2 ! fedoraproject ! org
[Download RAW message or body]
commit 56715e285b6128fe0a9fbf9a38ce445d908d0119
Author: Cole Robinson <crobinso@redhat.com>
Date: Sun Nov 30 18:12:22 2014 -0500
Fix SLES11 migration issue (bz #1109427)
CVE-2014-7840: insufficient parameter validation during ram load (bz #1163080)
...sure-time-in-migration-never-goes-backwar.patch | 98 ++++++++++++++++++++
...sure-proper-env-tsc-value-for-kvmclock_cu.patch | 42 +++++++++
...tion-fix-parameter-validation-on-ram-load.patch | 56 +++++++++++
qemu.spec | 19 ++++-
4 files changed, 214 insertions(+), 1 deletions(-)
---
diff --git a/0419-kvmclock-Ensure-time-in-migration-never-goes-backwar.patch \
b/0419-kvmclock-Ensure-time-in-migration-never-goes-backwar.patch new file mode \
100644 index 0000000..5d1739a
--- /dev/null
+++ b/0419-kvmclock-Ensure-time-in-migration-never-goes-backwar.patch
@@ -0,0 +1,98 @@
+From: Alexander Graf <agraf@suse.de>
+Date: Fri, 5 Sep 2014 10:52:45 -0300
+Subject: [PATCH] kvmclock: Ensure time in migration never goes backward
+
+When we migrate we ask the kernel about its current belief on what the guest
+time would be. However, I've seen cases where the kvmclock guest structure
+indicates a time more recent than the kvm returned time.
+
+To make sure we never go backwards, calculate what the guest would have seen as time \
at the point of migration and use that value instead of the kernel returned one when \
it's more recent. +This bases the view of the kvmclock after migration on the
+same foundation in host as well as guest.
+
+Signed-off-by: Alexander Graf <agraf@suse.de>
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 9a48bcd1b82494671c111109b0eefdb882581499)
+---
+ hw/i386/kvm/clock.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
+diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
+index e89e2f7..2fea4eb 100644
+--- a/hw/i386/kvm/clock.c
++++ b/hw/i386/kvm/clock.c
+@@ -14,6 +14,7 @@
+ */
+
+ #include "qemu-common.h"
++#include "qemu/host-utils.h"
+ #include "sysemu/sysemu.h"
+ #include "sysemu/kvm.h"
+ #include "hw/sysbus.h"
+@@ -34,6 +35,48 @@ typedef struct KVMClockState {
+ bool clock_valid;
+ } KVMClockState;
+
++struct pvclock_vcpu_time_info {
++ uint32_t version;
++ uint32_t pad0;
++ uint64_t tsc_timestamp;
++ uint64_t system_time;
++ uint32_t tsc_to_system_mul;
++ int8_t tsc_shift;
++ uint8_t flags;
++ uint8_t pad[2];
++} __attribute__((__packed__)); /* 32 bytes */
++
++static uint64_t kvmclock_current_nsec(KVMClockState *s)
++{
++ CPUState *cpu = first_cpu;
++ CPUX86State *env = cpu->env_ptr;
++ hwaddr kvmclock_struct_pa = env->system_time_msr & ~1ULL;
++ uint64_t migration_tsc = env->tsc;
++ struct pvclock_vcpu_time_info time;
++ uint64_t delta;
++ uint64_t nsec_lo;
++ uint64_t nsec_hi;
++ uint64_t nsec;
++
++ if (!(env->system_time_msr & 1ULL)) {
++ /* KVM clock not active */
++ return 0;
++ }
++
++ cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time));
++
++ assert(time.tsc_timestamp <= migration_tsc);
++ delta = migration_tsc - time.tsc_timestamp;
++ if (time.tsc_shift < 0) {
++ delta >>= -time.tsc_shift;
++ } else {
++ delta <<= time.tsc_shift;
++ }
++
++ mulu64(&nsec_lo, &nsec_hi, delta, time.tsc_to_system_mul);
++ nsec = (nsec_lo >> 32) | (nsec_hi << 32);
++ return nsec + time.system_time;
++}
+
+ static void kvmclock_vm_state_change(void *opaque, int running,
+ RunState state)
+@@ -45,9 +88,15 @@ static void kvmclock_vm_state_change(void *opaque, int running,
+
+ if (running) {
+ struct kvm_clock_data data;
++ uint64_t time_at_migration = kvmclock_current_nsec(s);
+
+ s->clock_valid = false;
+
++ /* We can't rely on the migrated clock value, just discard it */
++ if (time_at_migration) {
++ s->clock = time_at_migration;
++ }
++
+ data.clock = s->clock;
+ data.flags = 0;
+ ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
diff --git a/0420-kvmclock-Ensure-proper-env-tsc-value-for-kvmclock_cu.patch \
b/0420-kvmclock-Ensure-proper-env-tsc-value-for-kvmclock_cu.patch new file mode \
100644 index 0000000..e939e46
--- /dev/null
+++ b/0420-kvmclock-Ensure-proper-env-tsc-value-for-kvmclock_cu.patch
@@ -0,0 +1,42 @@
+From: Marcelo Tosatti <mtosatti@redhat.com>
+Date: Fri, 5 Sep 2014 10:52:47 -0300
+Subject: [PATCH] kvmclock: Ensure proper env->tsc value for
+ kvmclock_current_nsec calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Ensure proper env->tsc value for kvmclock_current_nsec calculation.
+
+Reported-by: Marcin Gibuła <m.gibula@beyond.pl>
+Analyzed-by: Marcin Gibuła <m.gibula@beyond.pl>
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 317b0a6d8ba44e9bf8f9c3dbd776c4536843d82c)
+---
+ hw/i386/kvm/clock.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
+index 2fea4eb..eaf3f0a 100644
+--- a/hw/i386/kvm/clock.c
++++ b/hw/i386/kvm/clock.c
+@@ -17,6 +17,7 @@
+ #include "qemu/host-utils.h"
+ #include "sysemu/sysemu.h"
+ #include "sysemu/kvm.h"
++#include "sysemu/cpus.h"
+ #include "hw/sysbus.h"
+ #include "hw/kvm/clock.h"
+
+@@ -124,6 +125,9 @@ static void kvmclock_vm_state_change(void *opaque, int running,
+ if (s->clock_valid) {
+ return;
+ }
++
++ cpu_synchronize_all_states();
++ cpu_clean_all_dirty();
+ ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
+ if (ret < 0) {
+ fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
diff --git a/0421-migration-fix-parameter-validation-on-ram-load.patch \
b/0421-migration-fix-parameter-validation-on-ram-load.patch new file mode 100644
index 0000000..758eabb
--- /dev/null
+++ b/0421-migration-fix-parameter-validation-on-ram-load.patch
@@ -0,0 +1,56 @@
+From: "Michael S. Tsirkin" <mst@redhat.com>
+Date: Wed, 12 Nov 2014 11:44:39 +0200
+Subject: [PATCH] migration: fix parameter validation on ram load
+
+During migration, the values read from migration stream during ram load
+are not validated. Especially offset in host_from_stream_offset() and
+also the length of the writes in the callers of said function.
+
+To fix this, we need to make sure that the [offset, offset + length]
+range fits into one of the allocated memory regions.
+
+Validating addr < len should be sufficient since data seems to always be
+managed in TARGET_PAGE_SIZE chunks.
+
+Fixes: CVE-2014-7840
+
+Note: follow-up patches add extra checks on each block->host access.
+
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Amit Shah <amit.shah@redhat.com>
+(cherry picked from commit 0be839a2701369f669532ea5884c15bead1c6e08)
+
+Conflicts:
+ arch_init.c
+---
+ arch_init.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch_init.c b/arch_init.c
+index 23151b3..b6f7958 100644
+--- a/arch_init.c
++++ b/arch_init.c
+@@ -816,8 +816,8 @@ static inline void *host_from_stream_offset(QEMUFile *f,
+ uint8_t len;
+
+ if (flags & RAM_SAVE_FLAG_CONTINUE) {
+- if (!block) {
+- fprintf(stderr, "Ack, bad migration stream!\n");
++ if (!block || block->length <= offset) {
++ fprintf(stderr, "Ack, bad migration stream!");
+ return NULL;
+ }
+
+@@ -829,8 +829,9 @@ static inline void *host_from_stream_offset(QEMUFile *f,
+ id[len] = 0;
+
+ QTAILQ_FOREACH(block, &ram_list.blocks, next) {
+- if (!strncmp(id, block->idstr, sizeof(id)))
++ if (!strncmp(id, block->idstr, sizeof(id)) && block->length > offset) {
+ return memory_region_get_ram_ptr(block->mr) + offset;
++ }
+ }
+
+ fprintf(stderr, "Can't find block %s!\n", id);
diff --git a/qemu.spec b/qemu.spec
index abb9c3b..10dedc4 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -139,7 +139,7 @@
Summary: QEMU is a FAST! processor emulator
Name: qemu
Version: 1.6.2
-Release: 10%{?dist}
+Release: 11%{?dist}
Epoch: 2
License: GPLv2+ and LGPLv2+ and BSD
Group: Development/Tools
@@ -369,6 +369,12 @@ Patch0415: 0415-vmware-vga-add-vmsvga_verify_rect.patch
Patch0416: 0416-vmware-vga-use-vmsvga_verify_rect-in-vmsvga_update_r.patch
Patch0417: 0417-vmware-vga-use-vmsvga_verify_rect-in-vmsvga_copy_rec.patch
Patch0418: 0418-vmware-vga-use-vmsvga_verify_rect-in-vmsvga_fill_rec.patch
+# Fix SLES11 migration issue (bz #1109427)
+Patch0419: 0419-kvmclock-Ensure-time-in-migration-never-goes-backwar.patch
+Patch0420: 0420-kvmclock-Ensure-proper-env-tsc-value-for-kvmclock_cu.patch
+# CVE-2014-7840: insufficient parameter validation during ram load (bz
+# #1163080)
+Patch0421: 0421-migration-fix-parameter-validation-on-ram-load.patch
BuildRequires: SDL-devel
BuildRequires: zlib-devel
@@ -1070,6 +1076,12 @@ CAC emulation development files.
%patch0416 -p1
%patch0417 -p1
%patch0418 -p1
+# Fix SLES11 migration issue (bz #1109427)
+%patch0419 -p1
+%patch0420 -p1
+# CVE-2014-7840: insufficient parameter validation during ram load (bz
+# #1163080)
+%patch0421 -p1
%build
@@ -1777,6 +1789,11 @@ getent passwd qemu >/dev/null || \
%endif
%changelog
+* Sun Nov 30 2014 Cole Robinson <crobinso@redhat.com> - 2:1.6.2-11
+- Fix SLES11 migration issue (bz #1109427)
+- CVE-2014-7840: insufficient parameter validation during ram load (bz
+ #1163080)
+
* Wed Oct 29 2014 Cole Robinson <crobinso@redhat.com> - 2:1.6.2-10
- CVE-2014-7815 vnc: insufficient bits_per_pixel from the client sanitization
(bz #1157647, bz #1157641)
--
scm-commits mailing list
scm-commits@lists.fedoraproject.org
https://admin.fedoraproject.org/mailman/listinfo/scm-commits
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic