diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2019-09-19 18:49:02 +0100 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2019-09-19 19:01:21 +0100 |
commit | 4af779db91e5c588265aaa2b545abb43c33fb767 (patch) | |
tree | 152d43e63bcabdf7e87bd904891a42d39466370b | |
parent | b9f9d00c104a9a77144bb4b077379d5c64ed26e5 (diff) | |
download | linux-stable-queue-4af779db91e5c588265aaa2b545abb43c33fb767.tar.gz |
Add fix for CVE-2019-14821
-rw-r--r-- | queue-3.16/kvm-coalesced_mmio-add-bounds-checking.patch | 80 | ||||
-rw-r--r-- | queue-3.16/series | 1 |
2 files changed, 81 insertions, 0 deletions
diff --git a/queue-3.16/kvm-coalesced_mmio-add-bounds-checking.patch b/queue-3.16/kvm-coalesced_mmio-add-bounds-checking.patch new file mode 100644 index 00000000..f6002ed9 --- /dev/null +++ b/queue-3.16/kvm-coalesced_mmio-add-bounds-checking.patch @@ -0,0 +1,80 @@ +From: Matt Delco <delco@chromium.org> +Date: Mon, 16 Sep 2019 14:16:54 -0700 +Subject: KVM: coalesced_mmio: add bounds checking + +commit b60fe990c6b07ef6d4df67bc0530c7c90a62623a upstream. + +The first/last indexes are typically shared with a user app. +The app can change the 'last' index that the kernel uses +to store the next result. This change sanity checks the index +before using it for writing to a potentially arbitrary address. + +This fixes CVE-2019-14821. + +Fixes: 5f94c1741bdc ("KVM: Add coalesced MMIO support (common part)") +Signed-off-by: Matt Delco <delco@chromium.org> +Signed-off-by: Jim Mattson <jmattson@google.com> +Reported-by: syzbot+983c866c3dd6efa3662a@syzkaller.appspotmail.com +[Use READ_ONCE. - Paolo] +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> +[bwh: Backported to 3.16: + - Use ACCESS_ONCE() instead of READ_ONCE() + - kvm_coalesced_mmio_zone::pio field is not supported] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + virt/kvm/coalesced_mmio.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +--- a/virt/kvm/coalesced_mmio.c ++++ b/virt/kvm/coalesced_mmio.c +@@ -39,7 +39,7 @@ static int coalesced_mmio_in_range(struc + return 1; + } + +-static int coalesced_mmio_has_room(struct kvm_coalesced_mmio_dev *dev) ++static int coalesced_mmio_has_room(struct kvm_coalesced_mmio_dev *dev, u32 last) + { + struct kvm_coalesced_mmio_ring *ring; + unsigned avail; +@@ -51,7 +51,7 @@ static int coalesced_mmio_has_room(struc + * there is always one unused entry in the buffer + */ + ring = dev->kvm->coalesced_mmio_ring; +- avail = (ring->first - ring->last - 1) % KVM_COALESCED_MMIO_MAX; ++ avail = (ring->first - last - 1) % KVM_COALESCED_MMIO_MAX; + if (avail == 0) { + /* full */ + return 0; +@@ -65,24 +65,27 @@ static int coalesced_mmio_write(struct k + { + struct kvm_coalesced_mmio_dev *dev = to_mmio(this); + struct kvm_coalesced_mmio_ring *ring = dev->kvm->coalesced_mmio_ring; ++ __u32 insert; + + if (!coalesced_mmio_in_range(dev, addr, len)) + return -EOPNOTSUPP; + + spin_lock(&dev->kvm->ring_lock); + +- if (!coalesced_mmio_has_room(dev)) { ++ insert = ACCESS_ONCE(ring->last); ++ if (!coalesced_mmio_has_room(dev, insert) || ++ insert >= KVM_COALESCED_MMIO_MAX) { + spin_unlock(&dev->kvm->ring_lock); + return -EOPNOTSUPP; + } + + /* copy data in first free entry of the ring */ + +- ring->coalesced_mmio[ring->last].phys_addr = addr; +- ring->coalesced_mmio[ring->last].len = len; +- memcpy(ring->coalesced_mmio[ring->last].data, val, len); ++ ring->coalesced_mmio[insert].phys_addr = addr; ++ ring->coalesced_mmio[insert].len = len; ++ memcpy(ring->coalesced_mmio[insert].data, val, len); + smp_wmb(); +- ring->last = (ring->last + 1) % KVM_COALESCED_MMIO_MAX; ++ ring->last = (insert + 1) % KVM_COALESCED_MMIO_MAX; + spin_unlock(&dev->kvm->ring_lock); + return 0; + } diff --git a/queue-3.16/series b/queue-3.16/series index 71f58ec4..1e6bfee3 100644 --- a/queue-3.16/series +++ b/queue-3.16/series @@ -127,3 +127,4 @@ scsi-libsas-delete-sas-port-if-expander-discover-failed.patch bluetooth-hci_ldisc-fix-null-pointer-derefence-in-case-of-early.patch bluetooth-hci_ldisc-postpone-hci_uart_proto_ready-bit-set-in.patch ath6kl-add-some-bounds-checking.patch +kvm-coalesced_mmio-add-bounds-checking.patch |