f432013602
CVE-2014-7188/XSA-108: x86/HVM: properly bound x2APIC MSR range, fixing: A buggy or malicious HVM guest can crash the host or read data relating to other guests or the hypervisor itself. CVE-2014-8594/XSA-109: x86: don't allow page table updates on non-PV page tables in do_mmu_update(), fixing: Malicious or buggy stub domain kernels or tool stacks otherwise living outside of Domain0 can mount a denial of service attack which, if successful, can affect the whole system. CVE-2014-8595/XSA-110: x86emul: enforce privilege level restrictions when loading CS, fixing: Malicious HVM guest user mode code may be able to elevate its privileges to guest supervisor mode, or to crash the guest. CVE-2014-8866/XSA-111: x86: limit checks in hypercall_xlat_continuation() to actual arguments, fixing: A buggy or malicious HVM guest can crash the host. CVE-2014-8867/XSA-112: x86/HVM: confine internally handled MMIO to solitary regions, fixing: A buggy or malicious HVM guest can crash the host. CVE-2014-9030/XSA-113: x86/mm: fix a reference counting error in MMU_MACHPHYS_UPDATE, fixing: Malicious or buggy stub domain kernels or tool stacks otherwise living outside of Domain0 can mount a denial of service attack which, if successful, can affect the whole system.
115 lines
4.3 KiB
Text
115 lines
4.3 KiB
Text
$NetBSD: patch-CVE-2014-8866,v 1.1 2014/11/27 15:36:02 bouyer Exp $
|
|
|
|
x86: limit checks in hypercall_xlat_continuation() to actual arguments
|
|
|
|
HVM/PVH guests can otherwise trigger the final BUG_ON() in that
|
|
function by entering 64-bit mode, setting the high halves of affected
|
|
registers to non-zero values, leaving 64-bit mode, and issuing a
|
|
hypercall that might get preempted and hence become subject to
|
|
continuation argument translation (HYPERVISOR_memory_op being the only
|
|
one possible for HVM, PVH also having the option of using
|
|
HYPERVISOR_mmuext_op). This issue got introduced when HVM code was
|
|
switched to use compat_memory_op() - neither that nor
|
|
hypercall_xlat_continuation() were originally intended to be used by
|
|
other than PV guests (which can't enter 64-bit mode and hence have no
|
|
way to alter the high halves of 64-bit registers).
|
|
|
|
This is XSA-111.
|
|
|
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
|
Reviewed-by: Tim Deegan <tim@xen.org>
|
|
|
|
--- xen/arch/x86/domain.c.orig
|
|
+++ xen/arch/x86/domain.c
|
|
@@ -1921,7 +1921,8 @@ unsigned long hypercall_create_continuat
|
|
}
|
|
|
|
#ifdef CONFIG_COMPAT
|
|
-int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...)
|
|
+int hypercall_xlat_continuation(unsigned int *id, unsigned int nr,
|
|
+ unsigned int mask, ...)
|
|
{
|
|
int rc = 0;
|
|
struct mc_state *mcs = ¤t->mc_state;
|
|
@@ -1930,7 +1931,10 @@ int hypercall_xlat_continuation(unsigned
|
|
unsigned long nval = 0;
|
|
va_list args;
|
|
|
|
- BUG_ON(id && *id > 5);
|
|
+ ASSERT(nr <= ARRAY_SIZE(mcs->call.args));
|
|
+ ASSERT(!(mask >> nr));
|
|
+
|
|
+ BUG_ON(id && *id >= nr);
|
|
BUG_ON(id && (mask & (1U << *id)));
|
|
|
|
va_start(args, mask);
|
|
@@ -1939,7 +1943,7 @@ int hypercall_xlat_continuation(unsigned
|
|
{
|
|
if ( !test_bit(_MCSF_call_preempted, &mcs->flags) )
|
|
return 0;
|
|
- for ( i = 0; i < 6; ++i, mask >>= 1 )
|
|
+ for ( i = 0; i < nr; ++i, mask >>= 1 )
|
|
{
|
|
if ( mask & 1 )
|
|
{
|
|
@@ -1967,7 +1971,7 @@ int hypercall_xlat_continuation(unsigned
|
|
else
|
|
{
|
|
regs = guest_cpu_user_regs();
|
|
- for ( i = 0; i < 6; ++i, mask >>= 1 )
|
|
+ for ( i = 0; i < nr; ++i, mask >>= 1 )
|
|
{
|
|
unsigned long *reg;
|
|
|
|
--- xen/common/compat/memory.c.orig
|
|
+++ xen/common/compat/memory.c
|
|
@@ -208,7 +208,7 @@ int compat_memory_op(unsigned int cmd, X
|
|
break;
|
|
|
|
cmd = 0;
|
|
- if ( hypercall_xlat_continuation(&cmd, 0x02, nat.hnd, compat) )
|
|
+ if ( hypercall_xlat_continuation(&cmd, 2, 0x02, nat.hnd, compat) )
|
|
{
|
|
BUG_ON(rc != __HYPERVISOR_memory_op);
|
|
BUG_ON((cmd & MEMOP_CMD_MASK) != op);
|
|
--- xen/include/xen/compat.h.orig 2013-09-10 08:42:18.000000000 +0200
|
|
+++ xen/include/xen/compat.h 2014-11-27 15:29:34.000000000 +0100
|
|
@@ -185,7 +185,8 @@
|
|
CHECK_FIELD_COMMON_(k, CHECK_NAME_(k, n ## __ ## f1 ## __ ## f2 ## __ ## \
|
|
f3, F2), n, f1.f2.f3)
|
|
|
|
-int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...);
|
|
+int hypercall_xlat_continuation(unsigned int *id, unsigned int nr,
|
|
+ unsigned int mask, ...);
|
|
|
|
/* In-place translation functons: */
|
|
struct start_info;
|
|
--- xen/arch/x86/x86_64/compat/mm.c.orig 2013-09-10 08:42:18.000000000 +0200
|
|
+++ xen/arch/x86/x86_64/compat/mm.c 2014-11-27 15:21:15.000000000 +0100
|
|
@@ -128,7 +128,7 @@
|
|
break;
|
|
|
|
if ( rc == __HYPERVISOR_memory_op )
|
|
- hypercall_xlat_continuation(NULL, 0x2, nat, arg);
|
|
+ hypercall_xlat_continuation(NULL, 2, 0x2, nat, arg);
|
|
|
|
XLAT_pod_target(&cmp, nat);
|
|
|
|
@@ -333,7 +333,7 @@
|
|
left = 1;
|
|
if ( arg1 != MMU_UPDATE_PREEMPTED )
|
|
{
|
|
- BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops,
|
|
+ BUG_ON(!hypercall_xlat_continuation(&left, 4, 0x01, nat_ops,
|
|
cmp_uops));
|
|
if ( !test_bit(_MCSF_in_multicall, &mcs->flags) )
|
|
regs->_ecx += count - i;
|
|
@@ -341,7 +341,7 @@
|
|
mcs->compat_call.args[1] += count - i;
|
|
}
|
|
else
|
|
- BUG_ON(hypercall_xlat_continuation(&left, 0));
|
|
+ BUG_ON(hypercall_xlat_continuation(&left, 4, 0));
|
|
BUG_ON(left != arg1);
|
|
}
|
|
else
|