qemu-irix/hw/net
Laszlo Ersek cb873eaa6d 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 dd793a7488)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:55:27 -05:00
..
fsl_etsec typofixes - v4 2015-09-11 10:45:43 +03:00
rocker net: rocker: fix an incorrect array bounds check 2016-03-15 12:39:32 -05:00
Makefile.objs i.MX: Add FEC Ethernet Emulator 2015-09-07 10:39:30 +01:00
allwinner_emac.c net: remove all cleanup methods from NIC NetClientInfos 2015-01-12 10:16:23 +00:00
cadence_gem.c net: cadence_gem: Set initial MAC address 2015-10-27 10:30:30 +08:00
dp8393x.c net/dp8393x: do not use memory_region_init_rom_device with NULL 2015-07-28 09:30:10 +01:00
e1000.c e1000: eliminate infinite loops on out-of-bounds transfer start 2016-03-17 16:55:27 -05:00
e1000_regs.h e1000: Trivial implementation of various MAC registers 2015-11-12 15:26:53 +08:00
eepro100.c eepro100: Prevent two endless loops 2015-11-27 10:39:55 +08:00
etraxfs_eth.c etraxfs_eth: Drop eth_can_receive 2015-07-20 17:47:24 +01:00
imx_fec.c i.MX: Standardize i.MX FEC debug 2015-10-27 15:59:46 +00:00
lan9118.c lan9118: log and ignore access to invalid registers, rather than aborting 2015-12-07 21:43:48 +08:00
lance.c pcnet: Drop pcnet_can_receive 2015-07-27 14:12:18 +01:00
mcf_fec.c hw/net: handle flow control in mcf_fec driver receiver 2015-07-28 11:27:53 +01:00
milkymist-minimac2.c Fix bad error handling after memory_region_init_ram() 2015-09-18 14:39:29 +02:00
mipsnet.c mipsnet: Flush queued packets when receiving is enabled 2015-07-27 14:12:18 +01:00
ne2000-isa.c ne2000: Drop ne2000_can_receive 2015-09-02 14:51:07 +01:00
ne2000.c net: ne2000: check ring buffer control registers 2016-03-17 16:34:56 -05:00
ne2000.h ne2000: Drop ne2000_can_receive 2015-09-02 14:51:07 +01:00
opencores_eth.c net: remove all cleanup methods from NIC NetClientInfos 2015-01-12 10:16:23 +00:00
pcnet-pci.c pcnet: Drop pcnet_can_receive 2015-07-27 14:12:18 +01:00
pcnet.c pcnet: fix rx buffer overflow(CVE-2015-7512) 2015-12-07 21:43:48 +08:00
pcnet.h pcnet: Drop pcnet_can_receive 2015-07-27 14:12:18 +01:00
rtl8139.c rtl8139: remove muldiv64() 2015-09-25 14:53:29 +02:00
smc91c111.c net: smc91c111: flush packets on RCR register changes 2015-09-17 12:36:03 +01:00
spapr_llan.c spapr: Merge sPAPREnvironment into sPAPRMachineState 2015-07-07 17:44:50 +02:00
stellaris_enet.c stellaris_enet: Flush queued packets when read done 2015-07-27 14:12:18 +01:00
vhost_net.c net: set endianness on all backend devices 2016-03-17 16:36:19 -05:00
virtio-net.c virtio-net: correctly drop truncated packets 2015-10-01 16:16:52 +03:00
vmware_utils.h exec: Make stb_phys input an AddressSpace 2014-02-11 22:57:38 +10:00
vmxnet3.c net: vmxnet3: avoid memory leakage in activate_device 2016-03-15 12:08:24 -05:00
vmxnet3.h vmxnet3: Add support for VMXNET3_CMD_GET_ADAPTIVE_RING_INFO command 2015-10-12 13:19:29 +08:00
vmxnet_debug.h
vmxnet_rx_pkt.c net/vmxnet3: Refactor 'vmxnet_rx_pkt_attach_data' 2015-07-20 17:39:05 +01:00
vmxnet_rx_pkt.h net/vmxnet3: Refactor 'vmxnet_rx_pkt_attach_data' 2015-07-20 17:39:05 +01:00
vmxnet_tx_pkt.c net/vmxnet3: Refine l2 header validation 2015-10-12 13:19:29 +08:00
vmxnet_tx_pkt.h
xen_nic.c maint: remove unused include for signal.h 2015-09-11 10:21:38 +03:00
xgmac.c xgmac: Drop packets with eth_can_rx is false. 2015-07-27 14:12:18 +01:00
xilinx_axienet.c axienet: Flush queued packets when rx is done 2015-07-27 14:12:18 +01:00
xilinx_ethlite.c xilinx_ethlite: Clean up after commit 2f991ad 2015-03-10 08:15:33 +03:00