Xen Security Advisory 89 (CVE-2014-2599) - HVMOP_set_mem_access is not preemptible
Xen.org security team <[email protected]>
| Newsgroups | gmane.comp.emulators.xen.announce |
|---|---|
| Message-ID | <E1WVJeh-00063L-MQ__15491.1624770195$1396525000$gmane$org@xenbits.xen.org> |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Xen Security Advisory CVE-2014-2599 / XSA-89
version 3
HVMOP_set_mem_access is not preemptible
UPDATES IN VERSION 3
====================
This issue has been assigned CVE-2014-2599.
ISSUE DESCRIPTION
=================
Processing of the HVMOP_set_mem_access HVM control operations does not
check the size of its input and can tie up a physical CPU for extended
periods of time.
IMPACT
======
In a configuration where device models run with limited privilege (for
example, stubdom device models), a guest attacker who successfully
finds and exploits an unfixed security flaw in qemu-dm could leverage
the other flaw into a Denial of Service affecting the whole host.
In the more general case, in more abstract terms: a malicious
administrator of a domain privileged with regard to an HVM guest can
cause Xen to become unresponsive leading to a Denial of Service.
VULNERABLE SYSTEMS
==================
All Xen versions from 4.1 onwards are vulnerable. In 4.2 only 64-bit
versions of the hypervisor are vulnerable (HVMOP_set_mem_access is not
available in 32-bit hypervisors).
The vulnerability is only exposed to service domains for HVM guests
which have privilege over the guest. In a usual configuration that
means only device model emulators (qemu-dm).
In the case of HVM guests whose device model is running in an
unrestricted dom0 process, qemu-dm already has the ability to cause
problems for the whole system. So in that case the vulnerability is
not applicable.
The situation is more subtle for an HVM guest with a stub qemu-dm.
That is, where the device model runs in a separate domain (in the case
of xl, as requested by "device_model_stubdomain_override=1" in the xl
domain configuration file). The same applies with a qemu-dm in a dom0
process subjected to some kind kernel-based process privilege
limitation (eg the chroot technique as found in some versions of
XCP/XenServer).
In those latter situations this issue means that the extra isolation
does not provide as good a defence (against denial of service) as
intended. That is the essence of this vulnerability.
However, the security is still better than with a qemu-dm running as
an unrestricted dom0 process. Therefore users with these
configurations should not switch to an unrestricted dom0 qemu-dm.
Finally, in a radically disaggregated system: where the HVM service
domain software (probably, the device model domain image) is not
always supplied by the host administrator, a malicious service domain
administrator can excercise this vulnerability.
MITIGATION
==========
Running only PV guests will avoid this vulnerability.
In a radically disaggregated system, restricting HVM service domains
to software images approved by the host administrator will avoid the
vulnerability.
CREDITS
=======
This issue was discovered by Jan Beulich.
RESOLUTION
==========
Applying the appropriate attached patch resolves this issue.
xsa89.patch xen-unstable, Xen 4.4.x, Xen 4.3.x, Xen 4.2.x
xsa89-4.1.patch Xen 4.1.x
$ sha256sum xsa89*.patch
741c8fbbfa8e425d8debba17135d4c2e1e962d15717769bc93d68a65b5dc5ea6 xsa89.patch
7d965e9bf1894b7d909bfaddbc6b7bdcee0ba91b86942ce85e0ae80464f2463e xsa89-4.1.patch
$
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
iQEcBAEBAgAGBQJTO+8wAAoJEIP+FMlX6CvZ5esH/3T+ajm7vltauel3SR3+wQAw
nmxJR+CIaIRhIdjER/EPJ8HRqCl8DvY1yY8MM9qo70RIGu9eHSxkKbPQzNa1ye8/
sdqLT+TIVXElukse1CxSPnHkw0NYOjysdTxDs9XGFzTA2qzYj9cLu6qKbh8wKOqa
4UhqMzU5zXnRi+53Ljn3dBximU2Fch7ibN5Ea5C2e4uPJHR8aNn31lCESnsUfwbK
/ZrxoP89VRiSZq0GiGrSouF6FjU6fWyP3pTfvrFtQ0/K7a+HuA3ZgT35iGVdVW2C
dV35iNqIn+yC8vUrcEZkdfp/KapRP3WqCetoW63MT1tACToCf8ObT3RMTuAgfa0=
=vHm/
-----END PGP SIGNATURE-----
_______________________________________________
Xen-announce mailing list
[email protected]
http://lists.xen.org/xen-announce
xsa89.patch
(application/octet-stream, 2.9 KB)
x86: enforce preemption in HVM_set_mem_access / p2m_set_mem_access() Processing up to 4G PFNs may take almost arbitrarily long, so preemption is needed here. This is XSA-89. Signed-off-by: Jan Beulich <[email protected]> Reviewed-by: Tim Deegan <[email protected]> --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -4593,6 +4593,15 @@ long do_hvm_op(unsigned long op, XEN_GUE goto param_fail5; rc = p2m_set_mem_access(d, a.first_pfn, a.nr, a.hvmmem_access); + if ( rc > 0 ) + { + a.first_pfn += a.nr - rc; + a.nr = rc; + if ( __copy_to_guest(arg, &a, 1) ) + rc = -EFAULT; + else + rc = -EAGAIN; + } param_fail5: rcu_unlock_domain(d); --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1333,15 +1333,14 @@ void p2m_mem_access_resume(struct domain /* Set access type for a region of pfns. * If start_pfn == -1ul, sets the default access type */ -int p2m_set_mem_access(struct domain *d, unsigned long start_pfn, - uint32_t nr, hvmmem_access_t access) +long p2m_set_mem_access(struct domain *d, unsigned long pfn, uint32_t nr, + hvmmem_access_t access) { struct p2m_domain *p2m = p2m_get_hostp2m(d); - unsigned long pfn; p2m_access_t a, _a; p2m_type_t t; mfn_t mfn; - int rc = 0; + long rc; /* N.B. _not_ static: initializer depends on p2m->default_access */ p2m_access_t memaccess[] = { @@ -1364,14 +1363,17 @@ int p2m_set_mem_access(struct domain *d, a = memaccess[access]; /* If request to set default access */ - if ( start_pfn == ~0ull ) + if ( pfn == ~0ul ) { p2m->default_access = a; return 0; } + if ( !nr ) + return 0; + p2m_lock(p2m); - for ( pfn = start_pfn; pfn < start_pfn + nr; pfn++ ) + for ( ; ; ++pfn ) { mfn = p2m->get_entry(p2m, pfn, &t, &_a, 0, NULL); if ( p2m->set_entry(p2m, pfn, mfn, PAGE_ORDER_4K, t, a) == 0 ) @@ -1379,6 +1381,13 @@ int p2m_set_mem_access(struct domain *d, rc = -ENOMEM; break; } + + /* Check for continuation if it's not the last interation. */ + if ( !--nr || hypercall_preempt_check() ) + { + rc = nr; + break; + } } p2m_unlock(p2m); return rc; --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -576,8 +576,8 @@ void p2m_mem_access_resume(struct domain /* Set access type for a region of pfns. * If start_pfn == -1ul, sets the default access type */ -int p2m_set_mem_access(struct domain *d, unsigned long start_pfn, - uint32_t nr, hvmmem_access_t access); +long p2m_set_mem_access(struct domain *d, unsigned long start_pfn, + uint32_t nr, hvmmem_access_t access); /* Get access type for a pfn * If pfn == -1ul, gets the default access type */
xsa89-4.1.patch
(application/octet-stream, 1.2 KB)
x86: enforce preemption in HVM_set_mem_access / p2m_set_mem_access() Processing up to 4G PFNs may take almost arbitrarily long, so preemption is needed here. This is XSA-89. Signed-off-by: Jan Beulich <[email protected]> Reviewed-by: Tim Deegan <[email protected]> --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3755,7 +3755,7 @@ long do_hvm_op(unsigned long op, XEN_GUE ((a.first_pfn + a.nr - 1) > domain_get_maximum_gpfn(d)) ) goto param_fail5; - for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ ) + for ( pfn = a.first_pfn; a.nr; ++pfn ) { p2m_type_t t; mfn_t mfn; @@ -3768,6 +3768,17 @@ long do_hvm_op(unsigned long op, XEN_GUE p2m_unlock(p2m); if ( !success ) goto param_fail5; + + /* Check for continuation if it's not the last interation. */ + if ( --a.nr && hypercall_preempt_check() ) + { + a.first_pfn = pfn + 1; + if ( copy_to_guest(arg, &a, 1) ) + rc = -EFAULT; + else + rc = -EAGAIN; + goto param_fail5; + } } rc = 0;