Quick Emulator (or QEMU) is a cross-platform open-source emulator that performs hardware virtualization. QEMU is a free alternative to VMware. It is used by Xen, VirtualBox, KVM and is available for most Linux distributions.
Vishnu Dev, a security researcher, discovered that an attacker can break out of a guest operating system and attack the host operating system. This vulnerability leads to a heap-based buffer overflow or arbitrary code execution and identified with CVE-2019-14378. The researcher explains that this flaw is due to pointer miscalculation in-network backend of QEMU.
QEMU creates a SLiRP user network backend by default. The bug gets triggered when large ipv4 packets are reassembled for processing in SLiRP.
There are two buffers allocated for IP fragments :
m_ext is used when
m_dat is insufficient to hold the incoming packets.
m_ext is allocated on the heap. When a large fragmented packet arrives and space inside
m_dat is not sufficient, then the
m_ext is allocated.
But, the code does not handle the case when the very first fragmented packet is large and is allocated the
m_ext buffer. The code assumes that the packets are present in
m_dat . This leads to a miscalculation in value of the pointer.
The newly obtained value of the pointer is used in further calculations and modified, which now points to a wrong location. Attackers can use the values of
ip_dst to write controlled data onto the calculated location. If the calculated values point to an unmapped location, QEMU can be crashed.
The researcher explains that certain conditions should be met to achieve arbitrary code execution,
- Precise control over the heap is required to write controlled data relative to m->m_ext
- Bypassing of ASLR and PIE requires leaks
- The available function pointers do not support code execution. Hence arbitrary write has to be used.
When a new packet arrives,
mbuf object is allocated to store the packets until all the fragments have arrived. When all the packets have arrived, they are concatenated to one
mbuf object. The attacker tries to spray the heap to increase chances of exploitation by using this mechanism.
Now an attacker tries arbitrary write in 4 steps:
- Send a packet with id
0xdeadand MF bit set (1)
- Send a packet with id
0xcafeand MF bit set (1)
- The m_len(amount of data in the buffer) of
0xcafeis overwritten to point to
- Trigger the reassembly by sending packet with id
0xcafeand MF bit set (0). This overwrites
0xdead‘s m_data with target address.
- Send packet with id
0xdeadand MF bit unset(0) to trigger the reassembly. This writes the required content to m_data.
Before code execution, we have to bypass security implementations such as ASLR(Address Space Layout Randomization) and PIE(Proportional Integral controller Enhanced). SLiRP gateway responds to ICMP echo requests which bring back the data(payload) to the guest. To receive the leaks from the host, fake ICMP requests are sent to the host. The ICMP header is created with arbitrary write and the request is sent with the MF bit set (1). m_data is overwritten to point to a fake header on heap. And, a packet with MF bit set(0) is sent to end the ICMP request. We can achieve code execution using a fake QEMUTimer.
A QEMU developer has confirmed that this is not a host ring-0 exploit. As most production VM environments use tap networking and not SLiRP, this CVE would not be applicable to them. He also added that getting the root would require further exploitation to elevate privileges and escape SELinux confinement.
QEMU with libslirp library version 4.0.0 on all platforms.
Successful exploitation of this vulnerability leads to denial of service or arbitrary code execution.
QEMU has released updates for all platforms. Please refer to this KB Article to patch using SecPod SanerNow.