Bug 1332106

Summary: qemu: Infinite loop vulnerability in e1000_receive_iov()
Product: [Other] Security Response Reporter: Adam Mariš <amaris>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED DUPLICATE QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: unspecifiedCC: abaron, ailan, alonbl, aortega, apevec, areis, ayoung, bmcclain, chrisw, dblechte, drjones, eedri, gklein, imammedo, jen, jjoyce, jschluet, knoel, lhh, lpeer, markmc, mgoldboi, michal.skrivanek, mkenneth, mrezanin, mst, pbonzini, ppandit, rbalakri, rbryant, rkrcmar, sclewis, security-response-team, sherold, srevivo, tdecacqu, vkuznets, ykaul, ylavi
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-02-07 18:10:11 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1420080, 1420081    
Bug Blocks: 1326713    
Attachments:
Description Flags
DoS result none

Description Adam Mariš 2016-05-02 08:50:21 UTC
An infinite loop vulnerability in e1000_receive_iov() function was found.

Vulnerable code (hw/net/e1000.c):

static ssize_t
e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
{
...
do {
desc_size = total_size - desc_offset;
if (desc_size > s->rxbuf_size) {
desc_size = s->rxbuf_size;
}
base = rx_desc_base(s) + sizeof(desc) * s->mac_reg[RDH];// we can set base
pci_dma_read(d, base, &desc, sizeof(desc));
desc.special = vlan_special;
desc.status |= (vlan_status | E1000_RXD_STAT_DD);
if (desc.buffer_addr) {// set desc.buffer_addr = NULL
...
} else { // as per intel docs; skip descriptors with null buf addr
DBGOUT(RX, "Null RX descriptor!!\n");
}
pci_dma_write(d, base, &desc, sizeof(desc));

if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])//set this always to be true
s->mac_reg[RDH] = 0;
/* see comment in start_xmit; same here */
if (s->mac_reg[RDH] == rdh_start) {
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);
return -1;
}
} while (desc_offset < total_size);// desc_offset will always be 0, infinite loop
...
return size;
}

By setting desc.buffer_addr = NULL, lot of statements are to be ignored and by setting s->mac_reg[RDH], s->mac_reg[RDLEN] and some other variables properly, infinite loop in do while cycle can be reached.

Comment 1 Adam Mariš 2016-05-02 08:50:38 UTC
Acknowledgments:

Name: Li Qiang (Qihoo 360 Inc.)

Comment 3 Adam Mariš 2016-05-02 08:55:25 UTC
Created attachment 1152885 [details]
DoS result

Comment 4 Prasad Pandit 2017-02-07 18:08:35 UTC
Created xen tracking bugs for this issue:

Affects: fedora-all [bug 1420081]

Comment 5 Prasad Pandit 2017-02-07 18:08:57 UTC
Created xen tracking bugs for this issue:

Affects: fedora-all [bug 1420081]

Comment 6 Prasad Pandit 2017-02-07 18:09:17 UTC
Created xen tracking bugs for this issue:

Affects: fedora-all [bug 1420081]

Comment 7 Prasad Pandit 2017-02-07 18:10:11 UTC

*** This bug has been marked as a duplicate of bug 1298570 ***