diff --git a/SOURCES/kvm-apic-drop-debugging.patch b/SOURCES/kvm-apic-drop-debugging.patch new file mode 100644 index 0000000..e70d141 --- /dev/null +++ b/SOURCES/kvm-apic-drop-debugging.patch @@ -0,0 +1,59 @@ +From 4f34f153b4249624740401f2f65301932ff6898f Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Thu, 28 Jun 2018 17:57:09 +0200 +Subject: [PATCH 4/5] kvm/apic: drop debugging + +RH-Author: Dr. David Alan Gilbert +Message-id: <20180628175710.56848-5-dgilbert@redhat.com> +Patchwork-id: 81145 +O-Subject: [RHEL-7.5.z/RHEL-7.4.z/RHEL-7.3.z qemu-kvm PATCH 4/5] kvm/apic: drop debugging +Bugzilla: 1596302 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Laurent Vivier +RH-Acked-by: Michael S. Tsirkin + +From: "Dr. David Alan Gilbert" + +RH-Author: Dr. David Alan Gilbert +Message-id: <20180515115634.24469-5-dgilbert@redhat.com> +Patchwork-id: 80270 +O-Subject: [RHEL-7.6 qemu-kvm PATCH v2 4/5] kvm/apic: drop debugging +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Eduardo Habkost + +From: "Michael S. Tsirkin" + +commit 78d6a05d2f69cbfa6e95f0a4a24a2c934969913b + ("x86/lapic: Load LAPIC state at post_load") +has some debugging leftovers. + +Drop them. + +Cc: Dr. David Alan Gilbert +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Eduardo Habkost +(cherry picked from commit 1560fcfa96594f62cb2062f88e6785dda663529c) +Signed-off-by: Miroslav Rezanina +(cherry picked from commit 483ad2c6110b2810cb409d871cb9b4214f01bfdb) +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Miroslav Rezanina +--- + hw/i386/kvm/apic.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c +index 0f3a80c..d47d8da 100644 +--- a/hw/i386/kvm/apic.c ++++ b/hw/i386/kvm/apic.c +@@ -138,7 +138,6 @@ static void kvm_apic_put(void *data) + + static void kvm_apic_post_load(APICCommonState *s) + { +- fprintf(stderr, "%s: Yeh\n", __func__); + run_on_cpu(CPU(s->cpu), kvm_apic_put, s); + } + +-- +1.8.3.1 + diff --git a/SOURCES/kvm-apic-fix-2.2-2.1-migration.patch b/SOURCES/kvm-apic-fix-2.2-2.1-migration.patch new file mode 100644 index 0000000..c048c32 --- /dev/null +++ b/SOURCES/kvm-apic-fix-2.2-2.1-migration.patch @@ -0,0 +1,110 @@ +From 8af398963fd14ea74210c0796b47b870b58ad497 Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Thu, 28 Jun 2018 17:57:07 +0200 +Subject: [PATCH 2/5] kvm/apic: fix 2.2->2.1 migration + +RH-Author: Dr. David Alan Gilbert +Message-id: <20180628175710.56848-3-dgilbert@redhat.com> +Patchwork-id: 81146 +O-Subject: [RHEL-7.5.z/RHEL-7.4.z/RHEL-7.3.z qemu-kvm PATCH 2/5] kvm/apic: fix 2.2->2.1 migration +Bugzilla: 1596302 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Laurent Vivier +RH-Acked-by: Michael S. Tsirkin + +From: "Dr. David Alan Gilbert" + +RH-Author: Dr. David Alan Gilbert +Message-id: <20180515115634.24469-3-dgilbert@redhat.com> +Patchwork-id: 80269 +O-Subject: [RHEL-7.6 qemu-kvm PATCH v2 2/5] kvm/apic: fix 2.2->2.1 migration +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Eduardo Habkost + +From: Paolo Bonzini + +The wait_for_sipi field is set back to 1 after an INIT, so it was not +effective to reset it in kvm_apic_realize. Introduce a reset callback +and reset wait_for_sipi there. + +Reported-by: Igor Mammedov +Cc: qemu-stable@nongnu.org +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Paolo Bonzini +(cherry picked from commit 575a6f4082c45778b93032ef1e7fbea4467b3a2a) + We're adding this just to get the reset member; 1.5.3 doesn't + currently have the wait_for_sipi change in the kvm code. + +Signed-off-by: Miroslav Rezanina +(cherry picked from commit 9001bf38b596c0eb50daa52181ec6b4cf56cfb94) +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Miroslav Rezanina +--- + hw/i386/kvm/apic.c | 6 ++++++ + hw/intc/apic_common.c | 5 +++++ + include/hw/i386/apic_internal.h | 1 + + 3 files changed, 12 insertions(+) + +diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c +index 8f80425..6ead17c 100644 +--- a/hw/i386/kvm/apic.c ++++ b/hw/i386/kvm/apic.c +@@ -171,6 +171,11 @@ static const MemoryRegionOps kvm_apic_io_ops = { + .endianness = DEVICE_NATIVE_ENDIAN, + }; + ++static void kvm_apic_reset(APICCommonState *s) ++{ ++ /* This function intentionally left blank, for now */ ++} ++ + static void kvm_apic_init(APICCommonState *s) + { + memory_region_init_io(&s->io_memory, &kvm_apic_io_ops, s, "kvm-apic-msi", +@@ -186,6 +191,7 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data) + APICCommonClass *k = APIC_COMMON_CLASS(klass); + + k->init = kvm_apic_init; ++ k->reset = kvm_apic_reset; + k->set_base = kvm_apic_set_base; + k->set_tpr = kvm_apic_set_tpr; + k->get_tpr = kvm_apic_get_tpr; +diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c +index ff413de..fff9266 100644 +--- a/hw/intc/apic_common.c ++++ b/hw/intc/apic_common.c +@@ -173,6 +173,7 @@ bool apic_next_timer(APICCommonState *s, int64_t current_time) + void apic_init_reset(DeviceState *d) + { + APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); ++ APICCommonClass *info = APIC_COMMON_GET_CLASS(s); + int i; + + if (!s) { +@@ -201,6 +202,10 @@ void apic_init_reset(DeviceState *d) + qemu_del_timer(s->timer); + } + s->timer_expiry = -1; ++ ++ if (info->reset) { ++ info->reset(s); ++ } + } + + void apic_designate_bsp(DeviceState *d) +diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h +index 1b0a7fb..a77da1c 100644 +--- a/include/hw/i386/apic_internal.h ++++ b/include/hw/i386/apic_internal.h +@@ -89,6 +89,7 @@ typedef struct APICCommonClass + void (*external_nmi)(APICCommonState *s); + void (*pre_save)(APICCommonState *s); + void (*post_load)(APICCommonState *s); ++ void (*reset)(APICCommonState *s); + } APICCommonClass; + + struct APICCommonState { +-- +1.8.3.1 + diff --git a/SOURCES/kvm-apic-set-APIC-base-as-part-of-kvm_apic_put.patch b/SOURCES/kvm-apic-set-APIC-base-as-part-of-kvm_apic_put.patch new file mode 100644 index 0000000..f191938 --- /dev/null +++ b/SOURCES/kvm-apic-set-APIC-base-as-part-of-kvm_apic_put.patch @@ -0,0 +1,106 @@ +From 62a4c6bf428aaf562fb4b4ebfac22486be7b8ab8 Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Thu, 28 Jun 2018 17:57:10 +0200 +Subject: [PATCH 5/5] kvm: apic: set APIC base as part of kvm_apic_put + +RH-Author: Dr. David Alan Gilbert +Message-id: <20180628175710.56848-6-dgilbert@redhat.com> +Patchwork-id: 81148 +O-Subject: [RHEL-7.5.z/RHEL-7.4.z/RHEL-7.3.z qemu-kvm PATCH 5/5] kvm: apic: set APIC base as part of kvm_apic_put +Bugzilla: 1596302 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Laurent Vivier +RH-Acked-by: Michael S. Tsirkin + +From: "Dr. David Alan Gilbert" + +RH-Author: Dr. David Alan Gilbert +Message-id: <20180515115634.24469-6-dgilbert@redhat.com> +Patchwork-id: 80271 +O-Subject: [RHEL-7.6 qemu-kvm PATCH v2 5/5] kvm: apic: set APIC base as part of kvm_apic_put +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Eduardo Habkost + +From: "Dr. David Alan Gilbert" + +The parsing of KVM_SET_LAPIC's input depends on the current value of the +APIC base MSR---which indeed is stored in APICCommonState---but for historical +reasons APIC base is set through KVM_SET_SREGS together with cr8 (which is +really just the APIC TPR) and the actual "special CPU registers". + +APIC base must now be set before the actual LAPIC registers, so do that +in kvm_apic_put. It will be set again to the same value with KVM_SET_SREGS, +but that's not a big issue. + +This only happens since Linux 4.8, which checks for x2apic mode in +KVM_SET_LAPIC. However it's really a QEMU bug; until the recent +commit 78d6a05 ("x86/lapic: Load LAPIC state at post_load", 2016-09-13) +QEMU was indeed setting APIC base (via KVM_SET_SREGS) before the other +LAPIC registers. + +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Paolo Bonzini +(cherry picked from commit f8d9ccf8d5f9f4b7d364100871c4c7303b546de5) +Signed-off-by: Miroslav Rezanina +(cherry picked from commit 4142f7546da561898f15169f6e8085167601e878) +Signed-off-by: Miroslav Rezanina +--- + hw/i386/kvm/apic.c | 2 ++ + target-i386/kvm.c | 8 ++++++++ + target-i386/kvm_i386.h | 2 ++ + 3 files changed, 12 insertions(+) + +diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c +index d47d8da..77d2999 100644 +--- a/hw/i386/kvm/apic.c ++++ b/hw/i386/kvm/apic.c +@@ -12,6 +12,7 @@ + #include "hw/i386/apic_internal.h" + #include "hw/pci/msi.h" + #include "sysemu/kvm.h" ++#include "target-i386/kvm_i386.h" + + static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic, + int reg_id, uint32_t val) +@@ -127,6 +128,7 @@ static void kvm_apic_put(void *data) + struct kvm_lapic_state kapic; + int ret; + ++ kvm_put_apicbase(s->cpu, s->apicbase); + kvm_put_apic_state(s, &kapic); + + ret = kvm_vcpu_ioctl(CPU(s->cpu), KVM_SET_LAPIC, &kapic); +diff --git a/target-i386/kvm.c b/target-i386/kvm.c +index 1658621..35a9cf4 100644 +--- a/target-i386/kvm.c ++++ b/target-i386/kvm.c +@@ -1157,6 +1157,14 @@ static int kvm_put_one_msr(X86CPU *cpu, int index, uint64_t value) + return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data); + } + ++void kvm_put_apicbase(X86CPU *cpu, uint64_t value) ++{ ++ int ret; ++ ++ ret = kvm_put_one_msr(cpu, MSR_IA32_APICBASE, value); ++ assert(ret == 1); ++} ++ + static int kvm_put_tscdeadline_msr(X86CPU *cpu) + { + CPUX86State *env = &cpu->env; +diff --git a/target-i386/kvm_i386.h b/target-i386/kvm_i386.h +index 4392ab4..b260b31 100644 +--- a/target-i386/kvm_i386.h ++++ b/target-i386/kvm_i386.h +@@ -35,4 +35,6 @@ int kvm_device_msix_set_vector(KVMState *s, uint32_t dev_id, uint32_t vector, + int kvm_device_msix_assign(KVMState *s, uint32_t dev_id); + int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id); + ++void kvm_put_apicbase(X86CPU *cpu, uint64_t value); ++ + #endif +-- +1.8.3.1 + diff --git a/SOURCES/kvm-multiboot-Check-validity-of-mh_header_addr.patch b/SOURCES/kvm-multiboot-Check-validity-of-mh_header_addr.patch new file mode 100644 index 0000000..25dccb0 --- /dev/null +++ b/SOURCES/kvm-multiboot-Check-validity-of-mh_header_addr.patch @@ -0,0 +1,45 @@ +From 10868fe0444b0c74589e42695af665ee8d13e0b9 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 26 Jul 2018 16:24:48 +0200 +Subject: [PATCH 6/8] multiboot: Check validity of mh_header_addr + +RH-Author: Kevin Wolf +Message-id: <20180726162448.22072-7-kwolf@redhat.com> +Patchwork-id: 81515 +O-Subject: [RHEL-7.6/7.5.z qemu-kvm PATCH 6/6] multiboot: Check validity of mh_header_addr +Bugzilla: 1549824 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina + +I couldn't find a case where this prevents something bad from happening +that isn't already caught by other checks, but let's err on the safe +side and check that mh_header_addr is as expected. + +Signed-off-by: Kevin Wolf +Reviewed-by: Jack Schwartz +(cherry picked from commit dbf2dce7aabb7723542bd182175904846d70b0f9) +Signed-off-by: Kevin Wolf +Signed-off-by: Miroslav Rezanina +--- + hw/i386/multiboot.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c +index 6f489a5..e1f6e56 100644 +--- a/hw/i386/multiboot.c ++++ b/hw/i386/multiboot.c +@@ -208,6 +208,10 @@ int load_multiboot(FWCfgState *fw_cfg, + error_report("invalid load_addr address"); + exit(1); + } ++ if (mh_header_addr - mh_load_addr > i) { ++ error_report("invalid header_addr address"); ++ exit(1); ++ } + + uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr); + uint32_t mb_load_size = 0; +-- +1.8.3.1 + diff --git a/SOURCES/kvm-multiboot-Reject-kernels-exceeding-the-address-space.patch b/SOURCES/kvm-multiboot-Reject-kernels-exceeding-the-address-space.patch new file mode 100644 index 0000000..b34d4f8 --- /dev/null +++ b/SOURCES/kvm-multiboot-Reject-kernels-exceeding-the-address-space.patch @@ -0,0 +1,52 @@ +From 241aa1a7f62c5eba0fc95cbe310aaad3ee489a3d Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 26 Jul 2018 16:24:47 +0200 +Subject: [PATCH 5/8] multiboot: Reject kernels exceeding the address space + +RH-Author: Kevin Wolf +Message-id: <20180726162448.22072-6-kwolf@redhat.com> +Patchwork-id: 81514 +O-Subject: [RHEL-7.6/7.5.z qemu-kvm PATCH 5/6] multiboot: Reject kernels exceeding the address space +Bugzilla: 1549824 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina + +The code path where mh_load_end_addr is non-zero in the Multiboot +header checks that mh_load_end_addr >= mh_load_addr and so +mb_load_size is checked. However, mb_load_size is not checked when +calculated from the file size, when mh_load_end_addr is 0. + +If the kernel binary size is larger than can fit in the address space +after load_addr, we ended up with a kernel_size that is smaller than +load_size, which means that we read the file into a too small buffer. + +Add a check to reject kernel files with such Multiboot headers. + +Signed-off-by: Kevin Wolf +Reviewed-by: Jack Schwartz +(cherry picked from commit b17a9054a0652a1481be48a6729e972abf02412f) +Signed-off-by: Kevin Wolf +Signed-off-by: Miroslav Rezanina +--- + hw/i386/multiboot.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c +index 56889e8..6f489a5 100644 +--- a/hw/i386/multiboot.c ++++ b/hw/i386/multiboot.c +@@ -226,6 +226,10 @@ int load_multiboot(FWCfgState *fw_cfg, + } + mb_load_size = kernel_file_size - mb_kernel_text_offset; + } ++ if (mb_load_size > UINT32_MAX - mh_load_addr) { ++ error_report("kernel does not fit in address space"); ++ exit(1); ++ } + if (mh_bss_end_addr) { + if (mh_bss_end_addr < (mh_load_addr + mb_load_size)) { + error_report("invalid bss_end_addr address"); +-- +1.8.3.1 + diff --git a/SOURCES/kvm-multiboot-Remove-unused-variables-from-multiboot.c.patch b/SOURCES/kvm-multiboot-Remove-unused-variables-from-multiboot.c.patch new file mode 100644 index 0000000..80f9eae --- /dev/null +++ b/SOURCES/kvm-multiboot-Remove-unused-variables-from-multiboot.c.patch @@ -0,0 +1,49 @@ +From 8afeffd25dd6af6861439904f66a15f1606e06d5 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 26 Jul 2018 16:24:44 +0200 +Subject: [PATCH 2/8] multiboot: Remove unused variables from multiboot.c + +RH-Author: Kevin Wolf +Message-id: <20180726162448.22072-3-kwolf@redhat.com> +Patchwork-id: 81516 +O-Subject: [RHEL-7.6/7.5.z qemu-kvm PATCH 2/6] multiboot: Remove unused variables from multiboot.c +Bugzilla: 1549824 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina + +From: Jack Schwartz + +Remove unused variables: mh_mode_type, mh_width, mh_height, mh_depth + +Signed-off-by: Jack Schwartz +Reviewed-by: Daniel Kiper +Reviewed-by: Prasad J Pandit +Signed-off-by: Kevin Wolf +(cherry picked from commit 7a2e43cc96fd017883973caf9ee076ae23a3bebd) +Signed-off-by: Kevin Wolf +Signed-off-by: Miroslav Rezanina +--- + hw/i386/multiboot.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c +index 9a9a2e1..ee2ebd1 100644 +--- a/hw/i386/multiboot.c ++++ b/hw/i386/multiboot.c +@@ -234,12 +234,6 @@ int load_multiboot(FWCfgState *fw_cfg, + mb_kernel_size = mb_load_size; + } + +- /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE. +- uint32_t mh_mode_type = ldl_p(header+i+32); +- uint32_t mh_width = ldl_p(header+i+36); +- uint32_t mh_height = ldl_p(header+i+40); +- uint32_t mh_depth = ldl_p(header+i+44); */ +- + mb_debug("multiboot: mh_header_addr = %#x\n", mh_header_addr); + mb_debug("multiboot: mh_load_addr = %#x\n", mh_load_addr); + mb_debug("multiboot: mh_load_end_addr = %#x\n", mh_load_end_addr); +-- +1.8.3.1 + diff --git a/SOURCES/kvm-multiboot-Use-header-names-when-displaying-fields.patch b/SOURCES/kvm-multiboot-Use-header-names-when-displaying-fields.patch new file mode 100644 index 0000000..f58649d --- /dev/null +++ b/SOURCES/kvm-multiboot-Use-header-names-when-displaying-fields.patch @@ -0,0 +1,86 @@ +From 62b1260b11b0e93105377eadbf6deeadb84e5516 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 26 Jul 2018 16:24:45 +0200 +Subject: [PATCH 3/8] multiboot: Use header names when displaying fields + +RH-Author: Kevin Wolf +Message-id: <20180726162448.22072-4-kwolf@redhat.com> +Patchwork-id: 81520 +O-Subject: [RHEL-7.6/7.5.z qemu-kvm PATCH 3/6] multiboot: Use header names when displaying fields +Bugzilla: 1549824 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina + +From: Jack Schwartz + +Refer to field names when displaying fields in printf and debug statements. + +Signed-off-by: Jack Schwartz +Reviewed-by: Daniel Kiper +Signed-off-by: Kevin Wolf +(cherry picked from commit ce5eb6dc4dc5652f7e360a1db817f1d5dafab90f) +Signed-off-by: Kevin Wolf +Signed-off-by: Miroslav Rezanina +--- + hw/i386/multiboot.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c +index ee2ebd1..c4a361f 100644 +--- a/hw/i386/multiboot.c ++++ b/hw/i386/multiboot.c +@@ -203,7 +203,7 @@ int load_multiboot(FWCfgState *fw_cfg, + + mh_load_addr = ldl_p(header+i+16); + if (mh_header_addr < mh_load_addr) { +- fprintf(stderr, "invalid mh_load_addr address\n"); ++ fprintf(stderr, "invalid load_addr address\n"); + exit(1); + } + +@@ -213,7 +213,7 @@ int load_multiboot(FWCfgState *fw_cfg, + + if (mh_load_end_addr) { + if (mh_load_end_addr < mh_load_addr) { +- fprintf(stderr, "invalid mh_load_end_addr address\n"); ++ fprintf(stderr, "invalid load_end_addr address\n"); + exit(1); + } + mb_load_size = mh_load_end_addr - mh_load_addr; +@@ -226,7 +226,7 @@ int load_multiboot(FWCfgState *fw_cfg, + } + if (mh_bss_end_addr) { + if (mh_bss_end_addr < (mh_load_addr + mb_load_size)) { +- fprintf(stderr, "invalid mh_bss_end_addr address\n"); ++ fprintf(stderr, "invalid bss_end_addr address\n"); + exit(1); + } + mb_kernel_size = mh_bss_end_addr - mh_load_addr; +@@ -234,10 +234,10 @@ int load_multiboot(FWCfgState *fw_cfg, + mb_kernel_size = mb_load_size; + } + +- mb_debug("multiboot: mh_header_addr = %#x\n", mh_header_addr); +- mb_debug("multiboot: mh_load_addr = %#x\n", mh_load_addr); +- mb_debug("multiboot: mh_load_end_addr = %#x\n", mh_load_end_addr); +- mb_debug("multiboot: mh_bss_end_addr = %#x\n", mh_bss_end_addr); ++ mb_debug("multiboot: header_addr = %#x\n", mh_header_addr); ++ mb_debug("multiboot: load_addr = %#x\n", mh_load_addr); ++ mb_debug("multiboot: load_end_addr = %#x\n", mh_load_end_addr); ++ mb_debug("multiboot: bss_end_addr = %#x\n", mh_bss_end_addr); + mb_debug("qemu: loading multiboot kernel (%#x bytes) at %#x\n", + mb_load_size, mh_load_addr); + +@@ -335,7 +335,7 @@ int load_multiboot(FWCfgState *fw_cfg, + stl_p(bootinfo + MBI_BOOT_DEVICE, 0x8000ffff); /* XXX: use the -boot switch? */ + stl_p(bootinfo + MBI_MMAP_ADDR, ADDR_E820_MAP); + +- mb_debug("multiboot: mh_entry_addr = %#x\n", mh_entry_addr); ++ mb_debug("multiboot: entry_addr = %#x\n", mh_entry_addr); + mb_debug(" mb_buf_phys = "TARGET_FMT_plx"\n", mbs.mb_buf_phys); + mb_debug(" mod_start = "TARGET_FMT_plx"\n", mbs.mb_buf_phys + mbs.offset_mods); + mb_debug(" mb_mods_count = %d\n", mbs.mb_mods_count); +-- +1.8.3.1 + diff --git a/SOURCES/kvm-multiboot-bss_end_addr-can-be-zero.patch b/SOURCES/kvm-multiboot-bss_end_addr-can-be-zero.patch new file mode 100644 index 0000000..0074cb4 --- /dev/null +++ b/SOURCES/kvm-multiboot-bss_end_addr-can-be-zero.patch @@ -0,0 +1,72 @@ +From c36441a8376c6edddf4d1bc1ef27e132e71e4ddd Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 26 Jul 2018 16:24:43 +0200 +Subject: [PATCH 1/8] multiboot: bss_end_addr can be zero + +RH-Author: Kevin Wolf +Message-id: <20180726162448.22072-2-kwolf@redhat.com> +Patchwork-id: 81517 +O-Subject: [RHEL-7.6/7.5.z qemu-kvm PATCH 1/6] multiboot: bss_end_addr can be zero +Bugzilla: 1549824 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina + +From: Jack Schwartz + +The multiboot spec (https://www.gnu.org/software/grub/manual/multiboot/), +section 3.1.3, allows for bss_end_addr to be zero. + +A zero bss_end_addr signifies there is no .bss section. + +Suggested-by: Daniel Kiper +Signed-off-by: Jack Schwartz +Reviewed-by: Daniel Kiper +Reviewed-by: Prasad J Pandit +Signed-off-by: Kevin Wolf +(cherry picked from commit 2a8fcd119eb7c6bb3837fc3669eb1b2dfb31daf8) +Signed-off-by: Kevin Wolf +Signed-off-by: Miroslav Rezanina +--- + hw/i386/multiboot.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c +index 7eec230..9a9a2e1 100644 +--- a/hw/i386/multiboot.c ++++ b/hw/i386/multiboot.c +@@ -212,12 +212,6 @@ int load_multiboot(FWCfgState *fw_cfg, + mh_entry_addr = ldl_p(header+i+28); + + if (mh_load_end_addr) { +- if (mh_bss_end_addr < mh_load_addr) { +- fprintf(stderr, "invalid mh_bss_end_addr address\n"); +- exit(1); +- } +- mb_kernel_size = mh_bss_end_addr - mh_load_addr; +- + if (mh_load_end_addr < mh_load_addr) { + fprintf(stderr, "invalid mh_load_end_addr address\n"); + exit(1); +@@ -228,8 +222,16 @@ int load_multiboot(FWCfgState *fw_cfg, + fprintf(stderr, "invalid kernel_file_size\n"); + exit(1); + } +- mb_kernel_size = kernel_file_size - mb_kernel_text_offset; +- mb_load_size = mb_kernel_size; ++ mb_load_size = kernel_file_size - mb_kernel_text_offset; ++ } ++ if (mh_bss_end_addr) { ++ if (mh_bss_end_addr < (mh_load_addr + mb_load_size)) { ++ fprintf(stderr, "invalid mh_bss_end_addr address\n"); ++ exit(1); ++ } ++ mb_kernel_size = mh_bss_end_addr - mh_load_addr; ++ } else { ++ mb_kernel_size = mb_load_size; + } + + /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE. +-- +1.8.3.1 + diff --git a/SOURCES/kvm-multiboot-fprintf-stderr.-error_report.patch b/SOURCES/kvm-multiboot-fprintf-stderr.-error_report.patch new file mode 100644 index 0000000..e96f7ce --- /dev/null +++ b/SOURCES/kvm-multiboot-fprintf-stderr.-error_report.patch @@ -0,0 +1,202 @@ +From 5c4df6bfd7a729f99c61fc6e1068c8df22f18e7d Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 26 Jul 2018 16:24:46 +0200 +Subject: [PATCH 4/8] multiboot: fprintf(stderr...) -> error_report() + +RH-Author: Kevin Wolf +Message-id: <20180726162448.22072-5-kwolf@redhat.com> +Patchwork-id: 81519 +O-Subject: [RHEL-7.6/7.5.z qemu-kvm PATCH 4/6] multiboot: fprintf(stderr...) -> error_report() +Bugzilla: 1549824 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina + +From: Jack Schwartz + +Change all fprintf(stderr...) calls in hw/i386/multiboot.c to call +error_report() instead, including the mb_debug macro. Remove the "\n" +from strings passed to all modified calls, since error_report() appends +one. + +Signed-off-by: Jack Schwartz +Reviewed-by: Daniel Kiper +Signed-off-by: Kevin Wolf +(cherry picked from commit 4b9006a41ea8818f2385ae5228e07f211bb4a33d) +Signed-off-by: Kevin Wolf +Signed-off-by: Miroslav Rezanina +--- + hw/i386/multiboot.c | 53 ++++++++++++++++++++++++++++------------------------- + 1 file changed, 28 insertions(+), 25 deletions(-) + +diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c +index c4a361f..56889e8 100644 +--- a/hw/i386/multiboot.c ++++ b/hw/i386/multiboot.c +@@ -28,12 +28,13 @@ + #include "hw/loader.h" + #include "elf.h" + #include "sysemu/sysemu.h" ++#include "qemu/error-report.h" + + /* Show multiboot debug output */ + //#define DEBUG_MULTIBOOT + + #ifdef DEBUG_MULTIBOOT +-#define mb_debug(a...) fprintf(stderr, ## a) ++#define mb_debug(a...) error_report(a) + #else + #define mb_debug(a...) + #endif +@@ -118,7 +119,7 @@ static void mb_add_mod(MultibootState *s, + stl_p(p + MB_MOD_END, end); + stl_p(p + MB_MOD_CMDLINE, cmdline_phys); + +- mb_debug("mod%02d: "TARGET_FMT_plx" - "TARGET_FMT_plx"\n", ++ mb_debug("mod%02d: "TARGET_FMT_plx" - "TARGET_FMT_plx, + s->mb_mods_count, start, end); + + s->mb_mods_count++; +@@ -159,12 +160,12 @@ int load_multiboot(FWCfgState *fw_cfg, + if (!is_multiboot) + return 0; /* no multiboot */ + +- mb_debug("qemu: I believe we found a multiboot image!\n"); ++ mb_debug("qemu: I believe we found a multiboot image!"); + memset(bootinfo, 0, sizeof(bootinfo)); + memset(&mbs, 0, sizeof(mbs)); + + if (flags & 0x00000004) { /* MULTIBOOT_HEADER_HAS_VBE */ +- fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n"); ++ error_report("qemu: multiboot knows VBE. we don't."); + } + if (!(flags & 0x00010000)) { /* MULTIBOOT_HEADER_HAS_ADDR */ + uint64_t elf_entry; +@@ -173,14 +174,14 @@ int load_multiboot(FWCfgState *fw_cfg, + fclose(f); + + if (((struct elf64_hdr*)header)->e_machine == EM_X86_64) { +- fprintf(stderr, "Cannot load x86-64 image, give a 32bit one.\n"); ++ error_report("Cannot load x86-64 image, give a 32bit one."); + exit(1); + } + + kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + &elf_low, &elf_high, 0, ELF_MACHINE, 0); + if (kernel_size < 0) { +- fprintf(stderr, "Error while loading elf kernel\n"); ++ error_report("Error while loading elf kernel"); + exit(1); + } + mh_load_addr = elf_low; +@@ -189,12 +190,13 @@ int load_multiboot(FWCfgState *fw_cfg, + + mbs.mb_buf = g_malloc(mb_kernel_size); + if (rom_copy(mbs.mb_buf, mh_load_addr, mb_kernel_size) != mb_kernel_size) { +- fprintf(stderr, "Error while fetching elf kernel from rom\n"); ++ error_report("Error while fetching elf kernel from rom"); + exit(1); + } + +- mb_debug("qemu: loading multiboot-elf kernel (%#x bytes) with entry %#zx\n", +- mb_kernel_size, (size_t)mh_entry_addr); ++ mb_debug("qemu: loading multiboot-elf kernel " ++ "(%#x bytes) with entry %#zx", ++ mb_kernel_size, (size_t)mh_entry_addr); + } else { + /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_ADDR. */ + uint32_t mh_header_addr = ldl_p(header+i+12); +@@ -203,7 +205,7 @@ int load_multiboot(FWCfgState *fw_cfg, + + mh_load_addr = ldl_p(header+i+16); + if (mh_header_addr < mh_load_addr) { +- fprintf(stderr, "invalid load_addr address\n"); ++ error_report("invalid load_addr address"); + exit(1); + } + +@@ -213,20 +215,20 @@ int load_multiboot(FWCfgState *fw_cfg, + + if (mh_load_end_addr) { + if (mh_load_end_addr < mh_load_addr) { +- fprintf(stderr, "invalid load_end_addr address\n"); ++ error_report("invalid load_end_addr address"); + exit(1); + } + mb_load_size = mh_load_end_addr - mh_load_addr; + } else { + if (kernel_file_size < mb_kernel_text_offset) { +- fprintf(stderr, "invalid kernel_file_size\n"); ++ error_report("invalid kernel_file_size"); + exit(1); + } + mb_load_size = kernel_file_size - mb_kernel_text_offset; + } + if (mh_bss_end_addr) { + if (mh_bss_end_addr < (mh_load_addr + mb_load_size)) { +- fprintf(stderr, "invalid bss_end_addr address\n"); ++ error_report("invalid bss_end_addr address"); + exit(1); + } + mb_kernel_size = mh_bss_end_addr - mh_load_addr; +@@ -234,17 +236,17 @@ int load_multiboot(FWCfgState *fw_cfg, + mb_kernel_size = mb_load_size; + } + +- mb_debug("multiboot: header_addr = %#x\n", mh_header_addr); +- mb_debug("multiboot: load_addr = %#x\n", mh_load_addr); +- mb_debug("multiboot: load_end_addr = %#x\n", mh_load_end_addr); +- mb_debug("multiboot: bss_end_addr = %#x\n", mh_bss_end_addr); +- mb_debug("qemu: loading multiboot kernel (%#x bytes) at %#x\n", ++ mb_debug("multiboot: header_addr = %#x", mh_header_addr); ++ mb_debug("multiboot: load_addr = %#x", mh_load_addr); ++ mb_debug("multiboot: load_end_addr = %#x", mh_load_end_addr); ++ mb_debug("multiboot: bss_end_addr = %#x", mh_bss_end_addr); ++ mb_debug("qemu: loading multiboot kernel (%#x bytes) at %#x", + mb_load_size, mh_load_addr); + + mbs.mb_buf = g_malloc(mb_kernel_size); + fseek(f, mb_kernel_text_offset, SEEK_SET); + if (fread(mbs.mb_buf, 1, mb_load_size, f) != mb_load_size) { +- fprintf(stderr, "fread() failed\n"); ++ error_report("fread() failed"); + exit(1); + } + memset(mbs.mb_buf + mb_load_size, 0, mb_kernel_size - mb_load_size); +@@ -297,7 +299,7 @@ int load_multiboot(FWCfgState *fw_cfg, + mb_debug("multiboot loading module: %s\n", initrd_filename); + mb_mod_length = get_image_size(initrd_filename); + if (mb_mod_length < 0) { +- fprintf(stderr, "Failed to open file '%s'\n", initrd_filename); ++ error_report("Failed to open file '%s'\n", initrd_filename); + exit(1); + } + +@@ -308,7 +310,7 @@ int load_multiboot(FWCfgState *fw_cfg, + mb_add_mod(&mbs, mbs.mb_buf_phys + offs, + mbs.mb_buf_phys + offs + mb_mod_length, c); + +- mb_debug("mod_start: %p\nmod_end: %p\n cmdline: "TARGET_FMT_plx"\n", ++ mb_debug("mod_start: %p\nmod_end: %p\n cmdline: "TARGET_FMT_plx, + (char *)mbs.mb_buf + offs, + (char *)mbs.mb_buf + offs + mb_mod_length, c); + initrd_filename = next_initrd+1; +@@ -335,10 +337,11 @@ int load_multiboot(FWCfgState *fw_cfg, + stl_p(bootinfo + MBI_BOOT_DEVICE, 0x8000ffff); /* XXX: use the -boot switch? */ + stl_p(bootinfo + MBI_MMAP_ADDR, ADDR_E820_MAP); + +- mb_debug("multiboot: entry_addr = %#x\n", mh_entry_addr); +- mb_debug(" mb_buf_phys = "TARGET_FMT_plx"\n", mbs.mb_buf_phys); +- mb_debug(" mod_start = "TARGET_FMT_plx"\n", mbs.mb_buf_phys + mbs.offset_mods); +- mb_debug(" mb_mods_count = %d\n", mbs.mb_mods_count); ++ mb_debug("multiboot: entry_addr = %#x", mh_entry_addr); ++ mb_debug(" mb_buf_phys = "TARGET_FMT_plx, mbs.mb_buf_phys); ++ mb_debug(" mod_start = "TARGET_FMT_plx, ++ mbs.mb_buf_phys + mbs.offset_mods); ++ mb_debug(" mb_mods_count = %d", mbs.mb_mods_count); + + /* save bootinfo off the stack */ + mb_bootinfo_data = g_malloc(sizeof(bootinfo)); +-- +1.8.3.1 + diff --git a/SOURCES/kvm-slirp-correct-size-computation-while-concatenating-m.patch b/SOURCES/kvm-slirp-correct-size-computation-while-concatenating-m.patch new file mode 100644 index 0000000..ab1a661 --- /dev/null +++ b/SOURCES/kvm-slirp-correct-size-computation-while-concatenating-m.patch @@ -0,0 +1,113 @@ +From 58416c6786fa972314cb699a7df28d8c09268f03 Mon Sep 17 00:00:00 2001 +From: Xiao Wang +Date: Mon, 30 Jul 2018 06:31:57 +0200 +Subject: [PATCH 8/8] slirp: correct size computation while concatenating mbuf + +RH-Author: Xiao Wang +Message-id: <1532932317-6100-3-git-send-email-jasowang@redhat.com> +Patchwork-id: 81543 +O-Subject: [RHEL7.6/7.5.z qemu-kvm PATCH 2/2] slirp: correct size computation while concatenating mbuf +Bugzilla: 1586248 +RH-Acked-by: wexu@redhat.com +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Michael S. Tsirkin + +From: Prasad J Pandit + +Upstream: 70f2e64e4dde slirp: Convert mbufs to use g_malloc() and g_free() +Notes: Conflict since we lacks 70f2e64e4dde + ("slirp: Convert mbufs to use g_malloc() and g_free()") + +While reassembling incoming fragmented datagrams, 'm_cat' routine +extends the 'mbuf' buffer, if it has insufficient room. It computes +a wrong buffer size, which leads to overwriting adjacent heap buffer +area. Correct this size computation in m_cat. + +Reported-by: ZDI Disclosures +Signed-off-by: Prasad J Pandit +Signed-off-by: Samuel Thibault +Signed-off-by: Jason Wang +Signed-off-by: Miroslav Rezanina +--- + slirp/mbuf.c | 11 +++++------ + slirp/mbuf.h | 8 +++----- + 2 files changed, 8 insertions(+), 11 deletions(-) + +diff --git a/slirp/mbuf.c b/slirp/mbuf.c +index 5565fd1..ced2033 100644 +--- a/slirp/mbuf.c ++++ b/slirp/mbuf.c +@@ -139,7 +139,7 @@ m_cat(struct mbuf *m, struct mbuf *n) + * If there's no room, realloc + */ + if (M_FREEROOM(m) < n->m_len) +- m_inc(m,m->m_size+MINCSIZE); ++ m_inc(m, m->m_len + n->m_len); + + memcpy(m->m_data+m->m_len, n->m_data, n->m_len); + m->m_len += n->m_len; +@@ -148,7 +148,7 @@ m_cat(struct mbuf *m, struct mbuf *n) + } + + +-/* make m size bytes large */ ++/* make m 'size' bytes large from m_data */ + void + m_inc(struct mbuf *m, int size) + { +@@ -159,12 +159,12 @@ m_inc(struct mbuf *m, int size) + + if (m->m_flags & M_EXT) { + datasize = m->m_data - m->m_ext; +- m->m_ext = (char *)realloc(m->m_ext,size); ++ m->m_ext = (char *)realloc(m->m_ext, size + datasize); + m->m_data = m->m_ext + datasize; + } else { + char *dat; + datasize = m->m_data - m->m_dat; +- dat = (char *)malloc(size); ++ dat = (char *)malloc(size + datasize); + memcpy(dat, m->m_dat, m->m_size); + + m->m_ext = dat; +@@ -172,8 +172,7 @@ m_inc(struct mbuf *m, int size) + m->m_flags |= M_EXT; + } + +- m->m_size = size; +- ++ m->m_size = size + datasize; + } + + +diff --git a/slirp/mbuf.h b/slirp/mbuf.h +index b144f1c..32e5120 100644 +--- a/slirp/mbuf.h ++++ b/slirp/mbuf.h +@@ -33,8 +33,6 @@ + #ifndef _MBUF_H_ + #define _MBUF_H_ + +-#define MINCSIZE 4096 /* Amount to increase mbuf if too small */ +- + /* + * Macros for type conversion + * mtod(m,t) - convert mbuf pointer to data pointer of correct type +@@ -72,11 +70,11 @@ struct mbuf { + struct mbuf *m_prevpkt; /* Flags aren't used in the output queue */ + int m_flags; /* Misc flags */ + +- int m_size; /* Size of data */ ++ int m_size; /* Size of mbuf, from m_dat or m_ext */ + struct socket *m_so; + +- caddr_t m_data; /* Location of data */ +- int m_len; /* Amount of data in this mbuf */ ++ caddr_t m_data; /* Current location of data */ ++ int m_len; /* Amount of data in this mbuf, from m_data */ + + Slirp *slirp; + bool arp_requested; +-- +1.8.3.1 + diff --git a/SOURCES/kvm-slirp-remove-mbuf-m_hdr-m_dat-indirection.patch b/SOURCES/kvm-slirp-remove-mbuf-m_hdr-m_dat-indirection.patch new file mode 100644 index 0000000..f55b4f2 --- /dev/null +++ b/SOURCES/kvm-slirp-remove-mbuf-m_hdr-m_dat-indirection.patch @@ -0,0 +1,159 @@ +From 07fe03ab45fdc201fdfdd8e45809c86dbd0ab116 Mon Sep 17 00:00:00 2001 +From: Xiao Wang +Date: Mon, 30 Jul 2018 06:31:56 +0200 +Subject: [PATCH 7/8] slirp: remove mbuf(m_hdr, m_dat) indirection + +RH-Author: Xiao Wang +Message-id: <1532932317-6100-2-git-send-email-jasowang@redhat.com> +Patchwork-id: 81542 +O-Subject: [RHEL7.6/7.5.z qemu-kvm PATCH 1/2] slirp: remove mbuf(m_hdr, m_dat) indirection +Bugzilla: 1586248 +RH-Acked-by: wexu@redhat.com +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Michael S. Tsirkin + +From: Michael Tokarev + +(cherry picked from commit 0e44486cdccb4c1f9e5fad390cfd7186850c7204) +Signed-off-by: Miroslav Rezanina +--- + slirp/mbuf.h | 51 ++++++++++++++++++--------------------------------- + slirp/tcp_subr.c | 12 ++++++------ + 2 files changed, 24 insertions(+), 39 deletions(-) + +diff --git a/slirp/mbuf.h b/slirp/mbuf.h +index 3f3ab09..b144f1c 100644 +--- a/slirp/mbuf.h ++++ b/slirp/mbuf.h +@@ -49,22 +49,6 @@ + * free the m_ext. This is inefficient memory-wise, but who cares. + */ + +-/* XXX should union some of these! */ +-/* header at beginning of each mbuf: */ +-struct m_hdr { +- struct mbuf *mh_next; /* Linked list of mbufs */ +- struct mbuf *mh_prev; +- struct mbuf *mh_nextpkt; /* Next packet in queue/record */ +- struct mbuf *mh_prevpkt; /* Flags aren't used in the output queue */ +- int mh_flags; /* Misc flags */ +- +- int mh_size; /* Size of data */ +- struct socket *mh_so; +- +- caddr_t mh_data; /* Location of data */ +- int mh_len; /* Amount of data in this mbuf */ +-}; +- + /* + * How much room is in the mbuf, from m_data to the end of the mbuf + */ +@@ -80,29 +64,30 @@ struct m_hdr { + #define M_TRAILINGSPACE M_FREEROOM + + struct mbuf { +- struct m_hdr m_hdr; ++ /* XXX should union some of these! */ ++ /* header at beginning of each mbuf: */ ++ struct mbuf *m_next; /* Linked list of mbufs */ ++ struct mbuf *m_prev; ++ struct mbuf *m_nextpkt; /* Next packet in queue/record */ ++ struct mbuf *m_prevpkt; /* Flags aren't used in the output queue */ ++ int m_flags; /* Misc flags */ ++ ++ int m_size; /* Size of data */ ++ struct socket *m_so; ++ ++ caddr_t m_data; /* Location of data */ ++ int m_len; /* Amount of data in this mbuf */ ++ + Slirp *slirp; + bool arp_requested; + uint64_t expiration_date; + /* start of dynamic buffer area, must be last element */ +- union M_dat { +- char m_dat_[1]; /* ANSI don't like 0 sized arrays */ +- char *m_ext_; +- } M_dat; ++ union { ++ char m_dat[1]; /* ANSI don't like 0 sized arrays */ ++ char *m_ext; ++ }; + }; + +-#define m_next m_hdr.mh_next +-#define m_prev m_hdr.mh_prev +-#define m_nextpkt m_hdr.mh_nextpkt +-#define m_prevpkt m_hdr.mh_prevpkt +-#define m_flags m_hdr.mh_flags +-#define m_len m_hdr.mh_len +-#define m_data m_hdr.mh_data +-#define m_size m_hdr.mh_size +-#define m_dat M_dat.m_dat_ +-#define m_ext M_dat.m_ext_ +-#define m_so m_hdr.mh_so +- + #define ifq_prev m_prev + #define ifq_next m_next + #define ifs_prev m_prevpkt +diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c +index e98ce1a..043f28f 100644 +--- a/slirp/tcp_subr.c ++++ b/slirp/tcp_subr.c +@@ -647,7 +647,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + n4 = (laddr & 0xff); + + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len, ++ m->m_len += snprintf(bptr, m->m_size - m->m_len, + "ORT %d,%d,%d,%d,%d,%d\r\n%s", + n1, n2, n3, n4, n5, n6, x==7?buff:""); + return 1; +@@ -680,7 +680,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + n4 = (laddr & 0xff); + + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len, ++ m->m_len += snprintf(bptr, m->m_size - m->m_len, + "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", + n1, n2, n3, n4, n5, n6, x==7?buff:""); + +@@ -706,7 +706,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + if (m->m_data[m->m_len-1] == '\0' && lport != 0 && + (so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr, + htons(lport), SS_FACCEPTONCE)) != NULL) +- m->m_len = snprintf(m->m_data, m->m_hdr.mh_size, "%d", ++ m->m_len = snprintf(m->m_data, m->m_size, "%d", + ntohs(so->so_fport)) + 1; + return 1; + +@@ -726,7 +726,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, m->m_hdr.mh_size, ++ m->m_len += snprintf(bptr, m->m_size, + "DCC CHAT chat %lu %u%c\n", + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), 1); +@@ -737,7 +737,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, m->m_hdr.mh_size, ++ m->m_len += snprintf(bptr, m->m_size, + "DCC SEND %s %lu %u %u%c\n", buff, + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), n1, 1); +@@ -748,7 +748,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, m->m_hdr.mh_size, ++ m->m_len += snprintf(bptr, m->m_size, + "DCC MOVE %s %lu %u %u%c\n", buff, + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), n1, 1); +-- +1.8.3.1 + diff --git a/SOURCES/kvm-target-i386-introduce-kvm_put_one_msr.patch b/SOURCES/kvm-target-i386-introduce-kvm_put_one_msr.patch new file mode 100644 index 0000000..406e6de --- /dev/null +++ b/SOURCES/kvm-target-i386-introduce-kvm_put_one_msr.patch @@ -0,0 +1,98 @@ +From 608f71fea5a9cc79483d0b66aa59cd652ee5bf9c Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Thu, 28 Jun 2018 17:57:06 +0200 +Subject: [PATCH 1/5] target-i386: introduce kvm_put_one_msr + +RH-Author: Dr. David Alan Gilbert +Message-id: <20180628175710.56848-2-dgilbert@redhat.com> +Patchwork-id: 81144 +O-Subject: [RHEL-7.5.z/RHEL-7.4.z/RHEL-7.3.z qemu-kvm PATCH 1/5] target-i386: introduce kvm_put_one_msr +Bugzilla: 1596302 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Laurent Vivier +RH-Acked-by: Michael S. Tsirkin + +From: "Dr. David Alan Gilbert" + +RH-Author: Dr. David Alan Gilbert +Message-id: <20180515115634.24469-2-dgilbert@redhat.com> +Patchwork-id: 80272 +O-Subject: [RHEL-7.6 qemu-kvm PATCH v2 1/5] target-i386: introduce kvm_put_one_msr +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Eduardo Habkost + +From: "Dr. David Alan Gilbert" + +Avoid further code duplication in the next patch. + +Signed-off-by: Paolo Bonzini +(cherry picked from commit 73e1b8f2f9b8a90361f9c1af306ee17bfcfd592d) +(cherry picked from commit e9e26236af6a858961280cd4997c437eab27c1e9) + Merge conflict: + We don't yet have Eduardo's patch where kvm_msr_entry_add + was added, so rework to the older kvm_msr_entry_set. + + No msr_feature_control in this world + +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Miroslav Rezanina +(cherry picked from commit 596e3e7f77a1570aff586199e7bb34de0b4e0ba6) +Signed-off-by: Miroslav Rezanina +--- + target-i386/kvm.c | 28 +++++++++++++++++++++------- + 1 file changed, 21 insertions(+), 7 deletions(-) + +diff --git a/target-i386/kvm.c b/target-i386/kvm.c +index 656e24b..8544e52 100644 +--- a/target-i386/kvm.c ++++ b/target-i386/kvm.c +@@ -1141,24 +1141,38 @@ static void kvm_msr_entry_set(struct kvm_msr_entry *entry, + entry->data = value; + } + +-static int kvm_put_tscdeadline_msr(X86CPU *cpu) ++static int kvm_put_one_msr(X86CPU *cpu, int index, uint64_t value) + { +- CPUX86State *env = &cpu->env; + struct { + struct kvm_msrs info; + struct kvm_msr_entry entries[1]; + } msr_data; +- struct kvm_msr_entry *msrs = msr_data.entries; ++ ++ kvm_msr_entry_set(&msr_data.entries[0], index, value); ++ ++ msr_data.info = (struct kvm_msrs) { ++ .nmsrs = 1, ++ }; ++ ++ return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data); ++} ++ ++static int kvm_put_tscdeadline_msr(X86CPU *cpu) ++{ ++ CPUX86State *env = &cpu->env; ++ int ret; + + if (!has_msr_tsc_deadline) { + return 0; + } + +- kvm_msr_entry_set(&msrs[0], MSR_IA32_TSCDEADLINE, env->tsc_deadline); +- +- msr_data.info.nmsrs = 1; ++ ret = kvm_put_one_msr(cpu, MSR_IA32_TSCDEADLINE, env->tsc_deadline); ++ if (ret < 0) { ++ return ret; ++ } + +- return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data); ++ assert(ret == 1); ++ return 0; + } + + static int kvm_put_msrs(X86CPU *cpu, int level) +-- +1.8.3.1 + diff --git a/SOURCES/kvm-x86-lapic-Load-LAPIC-state-at-post_load.patch b/SOURCES/kvm-x86-lapic-Load-LAPIC-state-at-post_load.patch new file mode 100644 index 0000000..c39f91b --- /dev/null +++ b/SOURCES/kvm-x86-lapic-Load-LAPIC-state-at-post_load.patch @@ -0,0 +1,160 @@ +From 0076f45c587331bb0b49a6b643377d8522789456 Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Thu, 28 Jun 2018 17:57:08 +0200 +Subject: [PATCH 3/5] x86/lapic: Load LAPIC state at post_load + +RH-Author: Dr. David Alan Gilbert +Message-id: <20180628175710.56848-4-dgilbert@redhat.com> +Patchwork-id: 81143 +O-Subject: [RHEL-7.5.z/RHEL-7.4.z/RHEL-7.3.z qemu-kvm PATCH 3/5] x86/lapic: Load LAPIC state at post_load +Bugzilla: 1596302 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Laurent Vivier +RH-Acked-by: Michael S. Tsirkin + +From: "Dr. David Alan Gilbert" + +RH-Author: Dr. David Alan Gilbert +Message-id: <20180515115634.24469-4-dgilbert@redhat.com> +Patchwork-id: 80273 +O-Subject: [RHEL-7.6 qemu-kvm PATCH v2 3/5] x86/lapic: Load LAPIC state at post_load +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Eduardo Habkost + +From: "Dr. David Alan Gilbert" + +Load the LAPIC state during post_load (rather than when the CPU +starts). + +This allows an interrupt to be delivered from the ioapic to +the lapic prior to cpu loading, in particular the RTC that starts +ticking as soon as we load it's state. + +Fixes a case where Windows hangs after migration due to RTC interrupts +disappearing. + +Signed-off-by: Dr. David Alan Gilbert +Suggested-by: Paolo Bonzini +Signed-off-by: Paolo Bonzini +(cherry picked from commit 78d6a05d2f69cbfa6e95f0a4a24a2c934969913b) +Signed-off-by: Miroslav Rezanina +(cherry picked from commit f0254b84d490273e922d04b01a7b48f0ac370185) +Signed-off-by: Miroslav Rezanina +--- + hw/i386/kvm/apic.c | 27 ++++++++++++++++++++++++--- + include/sysemu/kvm.h | 1 - + target-i386/kvm.c | 18 ------------------ + 3 files changed, 24 insertions(+), 22 deletions(-) + +diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c +index 6ead17c..0f3a80c 100644 +--- a/hw/i386/kvm/apic.c ++++ b/hw/i386/kvm/apic.c +@@ -25,9 +25,8 @@ static inline uint32_t kvm_apic_get_reg(struct kvm_lapic_state *kapic, + return *((uint32_t *)(kapic->regs + (reg_id << 4))); + } + +-void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic) ++static void kvm_put_apic_state(APICCommonState *s, struct kvm_lapic_state *kapic) + { +- APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + int i; + + memset(kapic, 0, sizeof(*kapic)); +@@ -122,6 +121,27 @@ static void kvm_apic_vapic_base_update(APICCommonState *s) + } + } + ++static void kvm_apic_put(void *data) ++{ ++ APICCommonState *s = data; ++ struct kvm_lapic_state kapic; ++ int ret; ++ ++ kvm_put_apic_state(s, &kapic); ++ ++ ret = kvm_vcpu_ioctl(CPU(s->cpu), KVM_SET_LAPIC, &kapic); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_SET_LAPIC failed: %s\n", strerror(ret)); ++ abort(); ++ } ++} ++ ++static void kvm_apic_post_load(APICCommonState *s) ++{ ++ fprintf(stderr, "%s: Yeh\n", __func__); ++ run_on_cpu(CPU(s->cpu), kvm_apic_put, s); ++} ++ + static void do_inject_external_nmi(void *data) + { + APICCommonState *s = data; +@@ -173,7 +193,7 @@ static const MemoryRegionOps kvm_apic_io_ops = { + + static void kvm_apic_reset(APICCommonState *s) + { +- /* This function intentionally left blank, for now */ ++ run_on_cpu(CPU(s->cpu), kvm_apic_put, s); + } + + static void kvm_apic_init(APICCommonState *s) +@@ -195,6 +215,7 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data) + k->set_base = kvm_apic_set_base; + k->set_tpr = kvm_apic_set_tpr; + k->get_tpr = kvm_apic_get_tpr; ++ k->post_load = kvm_apic_post_load; + k->enable_tpr_reporting = kvm_apic_enable_tpr_reporting; + k->vapic_base_update = kvm_apic_vapic_base_update; + k->external_nmi = kvm_apic_external_nmi; +diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h +index 0c6833f..49cfc42 100644 +--- a/include/sysemu/kvm.h ++++ b/include/sysemu/kvm.h +@@ -216,7 +216,6 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg); + + void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin); + +-void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic); + void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic); + + struct kvm_guest_debug; +diff --git a/target-i386/kvm.c b/target-i386/kvm.c +index 8544e52..1658621 100644 +--- a/target-i386/kvm.c ++++ b/target-i386/kvm.c +@@ -1876,20 +1876,6 @@ static int kvm_get_apic(X86CPU *cpu) + return 0; + } + +-static int kvm_put_apic(X86CPU *cpu) +-{ +- CPUX86State *env = &cpu->env; +- DeviceState *apic = env->apic_state; +- struct kvm_lapic_state kapic; +- +- if (apic && kvm_irqchip_in_kernel()) { +- kvm_put_apic_state(apic, &kapic); +- +- return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_LAPIC, &kapic); +- } +- return 0; +-} +- + static int kvm_put_vcpu_events(X86CPU *cpu, int level) + { + CPUX86State *env = &cpu->env; +@@ -2071,10 +2057,6 @@ int kvm_arch_put_registers(CPUState *cpu, int level) + if (ret < 0) { + return ret; + } +- ret = kvm_put_apic(x86_cpu); +- if (ret < 0) { +- return ret; +- } + } + + ret = kvm_put_tscdeadline_msr(x86_cpu); +-- +1.8.3.1 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index 1a3ecbb..384543a 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -76,7 +76,7 @@ Obsoletes: %1 < %{obsoletes_version} \ Summary: QEMU is a machine emulator and virtualizer Name: %{pkgname}%{?pkgsuffix} Version: 1.5.3 -Release: 156%{?dist}.3 +Release: 156%{?dist}.5 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 10 License: GPLv2+ and LGPLv2+ and BSD @@ -3875,6 +3875,32 @@ Patch1908: kvm-i386-define-the-ssbd-CPUID-feature-bit-CVE-2018-3639.patch Patch1909: kvm-i386-Define-the-Virt-SSBD-MSR-and-handling-of-it-CVE.patch # For bz#1584363 - CVE-2018-3639 qemu-kvm: hw: cpu: AMD: speculative store bypass [rhel-7.5.z] Patch1910: kvm-i386-define-the-AMD-virt-ssbd-CPUID-feature-bit-CVE-.patch +# For bz#1596302 - Windows 2012 Guest hangs after live migration with RTC clock stopped. [rhel-7.5.z] +Patch1911: kvm-target-i386-introduce-kvm_put_one_msr.patch +# For bz#1596302 - Windows 2012 Guest hangs after live migration with RTC clock stopped. [rhel-7.5.z] +Patch1912: kvm-apic-fix-2.2-2.1-migration.patch +# For bz#1596302 - Windows 2012 Guest hangs after live migration with RTC clock stopped. [rhel-7.5.z] +Patch1913: kvm-x86-lapic-Load-LAPIC-state-at-post_load.patch +# For bz#1596302 - Windows 2012 Guest hangs after live migration with RTC clock stopped. [rhel-7.5.z] +Patch1914: kvm-apic-drop-debugging.patch +# For bz#1596302 - Windows 2012 Guest hangs after live migration with RTC clock stopped. [rhel-7.5.z] +Patch1915: kvm-apic-set-APIC-base-as-part-of-kvm_apic_put.patch +# For bz#1549824 - CVE-2018-7550 qemu-kvm: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.5.z] +Patch1916: kvm-multiboot-bss_end_addr-can-be-zero.patch +# For bz#1549824 - CVE-2018-7550 qemu-kvm: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.5.z] +Patch1917: kvm-multiboot-Remove-unused-variables-from-multiboot.c.patch +# For bz#1549824 - CVE-2018-7550 qemu-kvm: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.5.z] +Patch1918: kvm-multiboot-Use-header-names-when-displaying-fields.patch +# For bz#1549824 - CVE-2018-7550 qemu-kvm: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.5.z] +Patch1919: kvm-multiboot-fprintf-stderr.-error_report.patch +# For bz#1549824 - CVE-2018-7550 qemu-kvm: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.5.z] +Patch1920: kvm-multiboot-Reject-kernels-exceeding-the-address-space.patch +# For bz#1549824 - CVE-2018-7550 qemu-kvm: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.5.z] +Patch1921: kvm-multiboot-Check-validity-of-mh_header_addr.patch +# For bz#1586248 - CVE-2018-11806 qemu-kvm: QEMU: slirp: heap buffer overflow while reassembling fragmented datagrams [rhel-7.5.z] +Patch1922: kvm-slirp-remove-mbuf-m_hdr-m_dat-indirection.patch +# For bz#1586248 - CVE-2018-11806 qemu-kvm: QEMU: slirp: heap buffer overflow while reassembling fragmented datagrams [rhel-7.5.z] +Patch1923: kvm-slirp-correct-size-computation-while-concatenating-m.patch BuildRequires: zlib-devel @@ -5963,6 +5989,19 @@ tar -xf %{SOURCE21} %patch1908 -p1 %patch1909 -p1 %patch1910 -p1 +%patch1911 -p1 +%patch1912 -p1 +%patch1913 -p1 +%patch1914 -p1 +%patch1915 -p1 +%patch1916 -p1 +%patch1917 -p1 +%patch1918 -p1 +%patch1919 -p1 +%patch1920 -p1 +%patch1921 -p1 +%patch1922 -p1 +%patch1923 -p1 %build buildarch="%{kvm_target}-softmmu" @@ -6408,6 +6447,29 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_mandir}/man8/qemu-nbd.8* %changelog +* Wed Aug 01 2018 Miroslav Rezanina - 1.5.3-156.el7_5.5 +- kvm-multiboot-bss_end_addr-can-be-zero.patch [bz#1549824] +- kvm-multiboot-Remove-unused-variables-from-multiboot.c.patch [bz#1549824] +- kvm-multiboot-Use-header-names-when-displaying-fields.patch [bz#1549824] +- kvm-multiboot-fprintf-stderr.-error_report.patch [bz#1549824] +- kvm-multiboot-Reject-kernels-exceeding-the-address-space.patch [bz#1549824] +- kvm-multiboot-Check-validity-of-mh_header_addr.patch [bz#1549824] +- kvm-slirp-remove-mbuf-m_hdr-m_dat-indirection.patch [bz#1586248] +- kvm-slirp-correct-size-computation-while-concatenating-m.patch [bz#1586248] +- Resolves: bz#1549824 + (CVE-2018-7550 qemu-kvm: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.5.z]) +- Resolves: bz#1586248 + (CVE-2018-11806 qemu-kvm: QEMU: slirp: heap buffer overflow while reassembling fragmented datagrams [rhel-7.5.z]) + +* Mon Jul 23 2018 Miroslav Rezanina - 1.5.3-156.el7_5.4 +- kvm-target-i386-introduce-kvm_put_one_msr.patch [bz#1596302] +- kvm-apic-fix-2.2-2.1-migration.patch [bz#1596302] +- kvm-x86-lapic-Load-LAPIC-state-at-post_load.patch [bz#1596302] +- kvm-apic-drop-debugging.patch [bz#1596302] +- kvm-apic-set-APIC-base-as-part-of-kvm_apic_put.patch [bz#1596302] +- Resolves: bz#1596302 + (Windows 2012 Guest hangs after live migration with RTC clock stopped. [rhel-7.5.z]) + * Fri Jun 08 2018 Miroslav Rezanina - 1.5.3-156.el7_5.3 - kvm-i386-Define-the-Virt-SSBD-MSR-and-handling-of-it-CVE.patch [bz#1584363] - kvm-i386-define-the-AMD-virt-ssbd-CPUID-feature-bit-CVE-.patch [bz#1584363]