Bug 2120631 (CVE-2022-2962)

Summary: CVE-2022-2962 QEMU: tulip: DMA reentrancy issue leads to stack or heap overflow
Product: [Other] Security Response Reporter: Mauro Matteo Cascella <mcascell>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED NOTABUG QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: unspecifiedCC: berrange, cfergeau, crobinso, ddepaula, eglynn, jen, jferlan, jjoyce, jmaloy, knoel, lhh, lkundrak, mburns, mcascell, mgarciac, mkenneth, mrezanin, mst, ondrejj, pbonzini, philmd, rjones, spower, virt-maint, virt-maint
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: qemu 7.2.0-rc0 Doc Type: If docs needed, set a value
Doc Text:
A DMA reentrancy issue was found in the Tulip device emulation in QEMU. When Tulip reads or writes to the rx/tx descriptor or copies the rx/tx frame, it doesn't check whether the destination address is its MMIO address. This issue can cause the device to trigger MMIO handlers multiple times, possibly leading to a stack or heap overflow. This flaw allows a malicious guest to crash the QEMU process on the host, resulting in a denial of service condition.
Story Points: ---
Clone Of: Environment:
Last Closed: 2022-09-02 17:33:02 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Bug Depends On: 2120641    
Bug Blocks: 1997699    

Description Mauro Matteo Cascella 2022-08-23 12:25:48 UTC
When tulip reads or writes to the rx/tx descriptor or copies the rx/tx frame, it doesn't check whether the destination address is its own MMIO address. So crafted content can cause the device to trigger MMIO handlers again to modify some global variables and cause stack or heap overflow.

-- [ QEMU command line:

./qemu-system-x86_64 -machine type=q35,accel=qtest -nodefaults -device tulip -qtest stdio -nographic


-- [ POC:

outl 0xcf8 0x80000804             /* PCICMD—PCI Command Register */
outl 0xcfc 0x107                  /* Enables accesses*/
outl 0xcf8 0x80000814             /* Memory Bar 1*/
outl 0xcfc 0xfebf1000             /* Set MMIO Address to 0xfebf1000*/
writel 0xfebf1000 0               /* tulip_reset */
writel 0xfebf1030 0x2001          /* set csr6 flags  CSR6_ST|CSR6_SR */
writel 0xfebf1020 0xfebf1008      /* set current_tx_desc to its MMIO address,and trigger tulip_desc_write */

-- [ Analysis

(1) setting s->current_rx_desc to tulip MMIO address + CSR(1).
(2) Then tulip_xmit_list_update was executed, and tulip_desc_write wrote a descriptor to its MMIO address+CSR(1).
(3) Tulip_xmit_list_update was called again.  
Then,(2)(3) was executed thousands of times until the stack overflowed.

I found that the same problem could occur in tulip_receive (it can be called by mmio write) and may cause heap overflow:
(1) In tulip_copy_rx_bytes set s->current_rx_desc to its mmio address + CSR(1) via pci_dma_write, then s->rx_frame_len is set to 0.
(2) When tulip_desc_write executes, another tulip_receive is called, s->rx_frame_len  can be set to a big value.
(3) But the first tulip_receive does not end,and  s->rx_frame_len is bigger than s->rx_frame_size, so tulip_copy_rx_bytes causes heap overflow.

-- [ Reporter
Siqi Chen (Shanghai Jiaotong University)

Comment 1 Mauro Matteo Cascella 2022-08-23 12:59:07 UTC
Created qemu tracking bugs for this issue:

Affects: fedora-all [bug 2120641]

Comment 2 Mauro Matteo Cascella 2022-08-24 08:42:47 UTC
Upstream issue:
https://gitlab.com/qemu-project/qemu/-/issues/1171

Comment 3 Mauro Matteo Cascella 2022-08-24 12:46:09 UTC
Upstream patch:
https://lists.nongnu.org/archive/html/qemu-devel/2022-08/msg03033.html

Comment 4 Product Security DevOps Team 2022-09-02 17:32:59 UTC
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s):

https://access.redhat.com/security/cve/cve-2022-2962

Comment 5 Mauro Matteo Cascella 2022-11-18 10:27:33 UTC
Upstream commit:
https://gitlab.com/qemu-project/qemu/-/commit/36a894ae