diff options
Diffstat (limited to 'gnu/packages/patches/qemu-CVE-2016-1981.patch')
-rw-r--r-- | gnu/packages/patches/qemu-CVE-2016-1981.patch | 95 |
1 files changed, 0 insertions, 95 deletions
diff --git a/gnu/packages/patches/qemu-CVE-2016-1981.patch b/gnu/packages/patches/qemu-CVE-2016-1981.patch deleted file mode 100644 index 03e7b333c9..0000000000 --- a/gnu/packages/patches/qemu-CVE-2016-1981.patch +++ /dev/null @@ -1,95 +0,0 @@ -From: Laszlo Ersek <lersek@redhat.com> -Date: Tue, 19 Jan 2016 14:17:20 +0100 -Subject: [PATCH] e1000: eliminate infinite loops on out-of-bounds transfer - start - -The start_xmit() and e1000_receive_iov() functions implement DMA transfers -iterating over a set of descriptors that the guest's e1000 driver -prepares: - -- the TDLEN and RDLEN registers store the total size of the descriptor - area, - -- while the TDH and RDH registers store the offset (in whole tx / rx - descriptors) into the area where the transfer is supposed to start. - -Each time a descriptor is processed, the TDH and RDH register is bumped -(as appropriate for the transfer direction). - -QEMU already contains logic to deal with bogus transfers submitted by the -guest: - -- Normally, the transmit case wants to increase TDH from its initial value - to TDT. (TDT is allowed to be numerically smaller than the initial TDH - value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe - that QEMU currently has here is a check against reaching the original - TDH value again -- a complete wraparound, which should never happen. - -- In the receive case RDH is increased from its initial value until - "total_size" bytes have been received; preferably in a single step, or - in "s->rxbuf_size" byte steps, if the latter is smaller. However, null - RX descriptors are skipped without receiving data, while RDH is - incremented just the same. QEMU tries to prevent an infinite loop - (processing only null RX descriptors) by detecting whether RDH assumes - its original value during the loop. (Again, wrapping from RDLEN to 0 is - normal.) - -What both directions miss is that the guest could program TDLEN and RDLEN -so low, and the initial TDH and RDH so high, that these registers will -immediately be truncated to zero, and then never reassume their initial -values in the loop -- a full wraparound will never occur. - -The condition that expresses this is: - - xdh_start >= s->mac_reg[XDLEN] / sizeof(desc) - -i.e., TDH or RDH start out after the last whole rx or tx descriptor that -fits into the TDLEN or RDLEN sized area. - -This condition could be checked before we enter the loops, but -pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for -bogus DMA addresses, so we just extend the existing failsafes with the -above condition. - -This is CVE-2016-1981. - -Cc: "Michael S. Tsirkin" <mst@redhat.com> -Cc: Petr Matousek <pmatouse@redhat.com> -Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com> -Cc: Prasad Pandit <ppandit@redhat.com> -Cc: Michael Roth <mdroth@linux.vnet.ibm.com> -Cc: Jason Wang <jasowang@redhat.com> -Cc: qemu-stable@nongnu.org -RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044 -Signed-off-by: Laszlo Ersek <lersek@redhat.com> -Reviewed-by: Jason Wang <jasowang@redhat.com> -Signed-off-by: Jason Wang <jasowang@redhat.com> -(cherry picked from commit dd793a74882477ca38d49e191110c17dfee51dcc) ---- - hw/net/e1000.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/hw/net/e1000.c b/hw/net/e1000.c -index bec06e9..34d0823 100644 ---- a/hw/net/e1000.c -+++ b/hw/net/e1000.c -@@ -908,7 +908,8 @@ start_xmit(E1000State *s) - * bogus values to TDT/TDLEN. - * there's nothing too intelligent we could do about this. - */ -- if (s->mac_reg[TDH] == tdh_start) { -+ if (s->mac_reg[TDH] == tdh_start || -+ tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) { - DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n", - tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]); - break; -@@ -1165,7 +1166,8 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) - if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN]) - s->mac_reg[RDH] = 0; - /* see comment in start_xmit; same here */ -- if (s->mac_reg[RDH] == rdh_start) { -+ if (s->mac_reg[RDH] == rdh_start || -+ rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) { - DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n", - rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]); - set_ics(s, 0, E1000_ICS_RXO); |