Triple whammy of bugs in popular open-source platform. Analysis The Xen project has today patched four security bugs in its open-source hypervisor – three potentially allowing guest virtual machines to take over their host servers. The other programming cockup allows a guest to crash the underlying machine.
This is not great news for cloud providers or anyone else running untrusted VMs on their hardware and relying on Xen, because the three holes can be exploited by malicious guests to escape their confines and attack other virtual machines or the system beneath. Linode, for example, has had to patch and reboot its Xen-powered servers today to address the aforementioned flaws. Amazon’s AWSis not affected.
Xen suffered similar security failings in July. Let’s take a look at what’s going wrong this time.
The first one, XSA-186 aka CVE-2016-7093, is a doozy. It affects Xen 4.5.3, 4.6.3, and 4.7.0 and later, when running a HVM guest on x86. When emulating certain instructions, Xen maintains a small cache of code for the guest. Unfortunately, when filling this cache with instructions, it doesn’t always check that the memory it is writing to actually holds the cache.
This means it’s possible for a carefully constructed guest VM to trick the hypervisor into overwriting its own memory and exploit this to take control of the system. To realistically pull this off, the virtualized processor has to be running in 16-bit mode and the program counter has to roll over from 0xffff to 0x0. Xen addresses this by preventing this wrapping from accessing memory outside the cache:
When emulating HVM instructions, Xen uses a small i-cache for fetches from guest memory. The code that handles cache misses does not check if the address from which it fetched lies within the cache before blindly writing to it. As such it is possible for the guest to overwrite hypervisor memory.
It is currently believed that the only way to trigger this bug is to use the way that Xen currently incorrectly wraps CS:IP in 16 bit modes. The included patch prevents such wrapping. A malicious HVM guest administrator can escalate their privilege to that of the host.
In practice it means ripping out sticky code like this:
/* Truncate rIP to def_ad_bytes (2 or 4) if necessary. */
if ( def_ad_bytes < sizeof(_regs.eip) )
_regs.eip &= (1UL << (def_ad_bytes * 8)) - 1;
ip = _regs.eip;
_regs.eip = ctxt->regs->eip;
*(uint16_t *)&_regs.eip = ip;
…and replacing it with code like this:
/* Zero the upper 32 bits of %rip if not in long mode. */
if ( def_ad_bytes < sizeof(_regs.eip) )
_regs.eip = (uint32_t)_regs.eip;
The next one is XSA-185 aka CVE-2016-7092, which is a little more involved. It affects all versions of 64-bit Xen on x86 when running 32-bit paravirtualized guests.
Operating systems running in PV virtual machines must ask Xen via hypercalls to manipulate their page tables – which are the data structures that control the memory the guest can access. The 32-bit guests run inside what’s called ring 1 to prevent them from directly altering the page tables.
The page table entries feature, among others, control bits to allow non-ring-0 user code to read from and write to pages of memory. Xen can be fooled into setting these flags so that the guest can read and write at will to its level-three page directory via recursive mapping. This in turn allows it to gain full read and write access to the system’s physical RAM by mapping the memory into its virtual address space. This can be exploited by a malicious guest to escape to the host and cause havoc:
On real hardware, a 32-bit PAE guest must leave the USER and RW bit clear in L3 pagetable entries, but the pagetable walk behaves as if they were set. (The L3 entries are cached in processor registers, and don’t actually form part of the pagewalk.)
When running a 32-bit PV guest on a 64-bit Xen, Xen must always OR in the USER and RW bits for L3 updates for the guest to observe architectural behaviour. This is unsafe in combination with recursive pagetables.
A malicious 32-bit PV guest administrator can escalate their privilege to that of the host.
Xen’s solution is to stop 32-bit paravirtualized guests from constructing recursive page mappings.
Next, we’ve got XSA-188 aka CVE-2016-7154, which affects just Xen 4.4. A guest can use the
EVTCHNOP_init_control hypercall [PDF] to set up an events channel for a virtual CPU; the channel is used to deliver things like interrupts.
If you pass a bad parameter to the call, Xen realizes something’s gone wrong and cancels the initialization mid-way through and frees up a memory allocation. However, it doesn’t remove the pointer to the allocation from a data structure, which means subsequent hypercalls to the event system will see the pointer, assume it’s OK to use, and access the memory being pointed to. This will either crash the hypervisor or, through crafty heap manipulation, potentially allow the guest to peek at Xen’s memory or execute arbitrary code:
When the EVTCHNOP_init_control operation is called with a bad guest frame number, it takes an error path which frees a control structure without also clearing the corresponding pointer. Certain subsequent operations (EVTCHNOP_expand_array or another EVTCHNOP_init_control), upon finding the non-NULL pointer, continue operation assuming it points to allocated memory.
A malicious guest administrator can crash the host, leading to a DoS. Arbitrary code execution (and therefore privilege escalation), and information leaks, cannot be excluded.
The solution to this classic use-after-free() problem is to overwrite the pointer with NULL after freeing it:
for ( i = 0; i < EVTCHN_FIFO_MAX_EVENT_ARRAY_PAGES; i++ )
d->evtchn_fifo = NULL;
Finally, there’s XSA-187 aka CVE-2016-7094, which is a denial-of-service flaw that affects all versions of Xen running HVM guests on x86 with shadow paging enabled. A virtual machine can overflow memory set aside by the hypervisor to store its state, causing crashes:
x86 HVM guests running with shadow paging use a subset of the x86 emulator to handle the guest writing to its own pagetables. There are situations a guest can provoke which result in exceeding the space allocated for internal state. A malicious HVM guest administrator can cause Xen to fail a bug check, causing a denial of service to the host.
The programming blunders were discovered and reported by Intel Security’s Mikhail Gorobets, Andrew Cooper of Citrix, Brian Marcotte, Jérémie Boutoille of Quarkslab and Shangcong Luan of Alibaba Cloud.