diff options
author | Irvine | 2017-12-26 08:38:50 +0000 |
---|---|---|
committer | Irvine | 2017-12-26 08:38:50 +0000 |
commit | eab8782a81b9b041bd97a0562ad76af20ba53997 (patch) | |
tree | 0b37f846ad3155dbe592574ae8681c70b70a0bb8 /CVE-2017-17741-KVM-Fix-stack-out-of-bounds-read-in-write_mmio.patch | |
parent | bc5422ab98ca44bb89a707d89c467211c623bd15 (diff) | |
download | aur-eab8782a81b9b041bd97a0562ad76af20ba53997.tar.gz |
Sync with linux-hardened-4.14.9.-1
Diffstat (limited to 'CVE-2017-17741-KVM-Fix-stack-out-of-bounds-read-in-write_mmio.patch')
-rw-r--r-- | CVE-2017-17741-KVM-Fix-stack-out-of-bounds-read-in-write_mmio.patch | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/CVE-2017-17741-KVM-Fix-stack-out-of-bounds-read-in-write_mmio.patch b/CVE-2017-17741-KVM-Fix-stack-out-of-bounds-read-in-write_mmio.patch new file mode 100644 index 000000000000..37182434e6d1 --- /dev/null +++ b/CVE-2017-17741-KVM-Fix-stack-out-of-bounds-read-in-write_mmio.patch @@ -0,0 +1,161 @@ +From e39d200fa5bf5b94a0948db0dae44c1b73b84a56 Mon Sep 17 00:00:00 2001 +From: Wanpeng Li <wanpeng.li@hotmail.com> +Date: Thu, 14 Dec 2017 17:40:50 -0800 +Subject: [PATCH] KVM: Fix stack-out-of-bounds read in write_mmio +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reported by syzkaller: + + BUG: KASAN: stack-out-of-bounds in write_mmio+0x11e/0x270 [kvm] + Read of size 8 at addr ffff8803259df7f8 by task syz-executor/32298 + + CPU: 6 PID: 32298 Comm: syz-executor Tainted: G OE 4.15.0-rc2+ #18 + Hardware name: LENOVO ThinkCentre M8500t-N000/SHARKBAY, BIOS FBKTC1AUS 02/16/2016 + Call Trace: + dump_stack+0xab/0xe1 + print_address_description+0x6b/0x290 + kasan_report+0x28a/0x370 + write_mmio+0x11e/0x270 [kvm] + emulator_read_write_onepage+0x311/0x600 [kvm] + emulator_read_write+0xef/0x240 [kvm] + emulator_fix_hypercall+0x105/0x150 [kvm] + em_hypercall+0x2b/0x80 [kvm] + x86_emulate_insn+0x2b1/0x1640 [kvm] + x86_emulate_instruction+0x39a/0xb90 [kvm] + handle_exception+0x1b4/0x4d0 [kvm_intel] + vcpu_enter_guest+0x15a0/0x2640 [kvm] + kvm_arch_vcpu_ioctl_run+0x549/0x7d0 [kvm] + kvm_vcpu_ioctl+0x479/0x880 [kvm] + do_vfs_ioctl+0x142/0x9a0 + SyS_ioctl+0x74/0x80 + entry_SYSCALL_64_fastpath+0x23/0x9a + +The path of patched vmmcall will patch 3 bytes opcode 0F 01 C1(vmcall) +to the guest memory, however, write_mmio tracepoint always prints 8 bytes +through *(u64 *)val since kvm splits the mmio access into 8 bytes. This +leaks 5 bytes from the kernel stack (CVE-2017-17741). This patch fixes +it by just accessing the bytes which we operate on. + +Before patch: + +syz-executor-5567 [007] .... 51370.561696: kvm_mmio: mmio write len 3 gpa 0x10 val 0x1ffff10077c1010f + +After patch: + +syz-executor-13416 [002] .... 51302.299573: kvm_mmio: mmio write len 3 gpa 0x10 val 0xc1010f + +Reported-by: Dmitry Vyukov <dvyukov@google.com> +Reviewed-by: Darren Kenny <darren.kenny@oracle.com> +Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> +Tested-by: Marc Zyngier <marc.zyngier@arm.com> +Cc: Paolo Bonzini <pbonzini@redhat.com> +Cc: Radim Krčmář <rkrcmar@redhat.com> +Cc: Marc Zyngier <marc.zyngier@arm.com> +Cc: Christoffer Dall <christoffer.dall@linaro.org> +Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com> +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> +--- + arch/x86/kvm/x86.c | 8 ++++---- + include/trace/events/kvm.h | 7 +++++-- + virt/kvm/arm/mmio.c | 6 +++--- + 3 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 3a82f2d4333b..1cec2c62a0b0 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -4384,7 +4384,7 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v) + addr, n, v)) + && kvm_io_bus_read(vcpu, KVM_MMIO_BUS, addr, n, v)) + break; +- trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, *(u64 *)v); ++ trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, v); + handled += n; + addr += n; + len -= n; +@@ -4643,7 +4643,7 @@ static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes) + { + if (vcpu->mmio_read_completed) { + trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes, +- vcpu->mmio_fragments[0].gpa, *(u64 *)val); ++ vcpu->mmio_fragments[0].gpa, val); + vcpu->mmio_read_completed = 0; + return 1; + } +@@ -4665,14 +4665,14 @@ static int write_emulate(struct kvm_vcpu *vcpu, gpa_t gpa, + + static int write_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val) + { +- trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val); ++ trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, val); + return vcpu_mmio_write(vcpu, gpa, bytes, val); + } + + static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, + void *val, int bytes) + { +- trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0); ++ trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, NULL); + return X86EMUL_IO_NEEDED; + } + +diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h +index e4b0b8e09932..2c735a3e6613 100644 +--- a/include/trace/events/kvm.h ++++ b/include/trace/events/kvm.h +@@ -211,7 +211,7 @@ TRACE_EVENT(kvm_ack_irq, + { KVM_TRACE_MMIO_WRITE, "write" } + + TRACE_EVENT(kvm_mmio, +- TP_PROTO(int type, int len, u64 gpa, u64 val), ++ TP_PROTO(int type, int len, u64 gpa, void *val), + TP_ARGS(type, len, gpa, val), + + TP_STRUCT__entry( +@@ -225,7 +225,10 @@ TRACE_EVENT(kvm_mmio, + __entry->type = type; + __entry->len = len; + __entry->gpa = gpa; +- __entry->val = val; ++ __entry->val = 0; ++ if (val) ++ memcpy(&__entry->val, val, ++ min_t(u32, sizeof(__entry->val), len)); + ), + + TP_printk("mmio %s len %u gpa 0x%llx val 0x%llx", +diff --git a/virt/kvm/arm/mmio.c b/virt/kvm/arm/mmio.c +index b6e715fd3c90..dac7ceb1a677 100644 +--- a/virt/kvm/arm/mmio.c ++++ b/virt/kvm/arm/mmio.c +@@ -112,7 +112,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) + } + + trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr, +- data); ++ &data); + data = vcpu_data_host_to_guest(vcpu, data, len); + vcpu_set_reg(vcpu, vcpu->arch.mmio_decode.rt, data); + } +@@ -182,14 +182,14 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, + data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rt), + len); + +- trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data); ++ trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, &data); + kvm_mmio_write_buf(data_buf, len, data); + + ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_ipa, len, + data_buf); + } else { + trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, len, +- fault_ipa, 0); ++ fault_ipa, NULL); + + ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_ipa, len, + data_buf); +-- +2.15.1 + |