qemu/hw
Laszlo Ersek dd793a7488 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>
2016-02-04 14:13:11 +08:00
..
9pfs 9pfs: Clean up includes 2016-01-29 15:07:23 +00:00
acpi x86: Clean up includes 2016-01-29 15:07:22 +00:00
alpha alpha: Clean up includes 2016-01-29 15:07:23 +00:00
arm hw/arm/virt: Add always-on property to the virt board timer 2016-01-21 14:15:07 +00:00
audio audio: Clean up includes 2016-02-02 13:57:31 +01:00
block virtio-blk: Functions for op blocker management 2016-02-02 17:50:46 +01:00
bt hw: Clean up includes 2016-01-29 15:07:25 +00:00
char hw: Clean up includes 2016-01-29 15:07:25 +00:00
core hw/core: Clean up includes 2016-01-29 15:07:25 +00:00
cpu hw: Clean up includes 2016-01-29 15:07:25 +00:00
cris cris: Clean up includes 2016-01-29 15:07:24 +00:00
display virtio-gpu: block any rendering until client (ui) is done 2016-02-03 10:41:36 +01:00
dma hw: Clean up includes 2016-01-29 15:07:25 +00:00
gpio hw: Clean up includes 2016-01-29 15:07:25 +00:00
i2c hw: Clean up includes 2016-01-29 15:07:25 +00:00
i386 x86: Clean up includes 2016-01-29 15:07:22 +00:00
ide macio: add dma_active to VMStateDescription 2016-01-30 23:37:36 +11:00
input hw: Clean up includes 2016-01-29 15:07:25 +00:00
intc hw/intc: Clean up includes 2016-01-29 15:07:24 +00:00
ipack hw: Clean up includes 2016-01-29 15:07:25 +00:00
ipmi hw: Clean up includes 2016-01-29 15:07:25 +00:00
isa hw: Clean up includes 2016-01-29 15:07:25 +00:00
lm32 lm32: Clean up includes 2016-01-29 15:07:22 +00:00
m68k m68k: Clean up includes 2016-01-29 15:07:24 +00:00
mem hw: Clean up includes 2016-01-29 15:07:25 +00:00
microblaze microblaze: Clean up includes 2016-01-28 11:13:13 +00:00
mips mips: Clean up includes 2016-01-23 14:30:04 +00:00
misc ivshmem: use a single eventfd callback, get rid of CharDriver 2016-02-02 13:28:58 +01:00
moxie moxie: Clean up includes 2016-01-29 15:07:25 +00:00
net e1000: eliminate infinite loops on out-of-bounds transfer start 2016-02-04 14:13:11 +08:00
nvram hw: Clean up includes 2016-01-29 15:07:25 +00:00
openrisc openrisc: Clean up includes 2016-01-29 15:07:24 +00:00
pci pci: Clean up includes 2016-01-29 15:07:24 +00:00
pci-bridge pci: Clean up includes 2016-01-29 15:07:24 +00:00
pci-host uninorth.c: add support for UniNorth kMacRISCPCIAddressSelect (0x48) register 2016-01-30 23:37:38 +11:00
pcmcia hw: Clean up includes 2016-01-29 15:07:25 +00:00
ppc target-ppc: Helper to determine page size information from hpte alone 2016-01-30 23:49:27 +11:00
s390x s390: Clean up includes 2016-01-29 15:07:22 +00:00
scsi virtio-scsi: Catch BDS-BB removal/insertion 2016-02-02 17:50:46 +01:00
sd hw: Clean up includes 2016-01-29 15:07:25 +00:00
sh4 sh4: Clean up includes 2016-01-29 15:07:24 +00:00
smbios hw: Clean up includes 2016-01-29 15:07:25 +00:00
sparc sparc: Clean up includes 2016-01-29 15:07:22 +00:00
sparc64 sparc: Clean up includes 2016-01-29 15:07:22 +00:00
ssi hw: Clean up includes 2016-01-29 15:07:25 +00:00
timer hw/timer: Clean up includes 2016-01-29 15:07:24 +00:00
tpm hw: Clean up includes 2016-01-29 15:07:25 +00:00
tricore tricore: Clean up includes 2016-01-29 15:07:25 +00:00
unicore32 unicore: Clean up includes 2016-01-29 15:07:22 +00:00
usb ehci: update irq on reset 2016-02-02 14:11:01 +01:00
vfio hw/vfio: Clean up includes 2016-01-29 15:07:24 +00:00
virtio virtio: Clean up includes 2016-01-29 15:07:23 +00:00
watchdog hw: Clean up includes 2016-01-29 15:07:25 +00:00
xen xen: Clean up includes 2016-01-29 15:07:23 +00:00
xenpv xen: Clean up includes 2016-01-29 15:07:23 +00:00
xtensa xtensa: Clean up includes 2016-01-29 15:07:24 +00:00
Makefile.objs Add a base IPMI interface 2015-12-22 18:39:19 +02:00