mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/HAP: adjust monitor table related error handling
hap_make_monitor_table() will return INVALID_MFN if it encounters an
error condition, but hap_update_paging_modes() wasn’t handling this
value, resulting in an inappropriate value being stored in
monitor_table. This would subsequently misguide at least
hap_vcpu_teardown(). Avoid this by bailing early.
Further, when a domain has/was already crashed or (perhaps less
important as there's no such path known to lead here) is already dying,
avoid calling domain_crash() on it again - that's at best confusing.
This is part of CVE-2022-33746 / XSA-410.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
master commit: 5b44a61180
master date: 2022-10-11 14:21:56 +0200
This commit is contained in:
1 parent
8fc19c143b
commit
3422c19d85
1 file changed
+12
-2
@@ -39,6 +39,7 @@
|
||||
#include <asm/domain.h>
|
||||
#include <xen/numa.h>
|
||||
#include <asm/hvm/nestedhvm.h>
|
||||
#include <public/sched.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
@@ -405,8 +406,13 @@ static mfn_t hap_make_monitor_table(struct vcpu *v)
|
||||
return m4mfn;
|
||||
|
||||
oom:
|
||||
printk(XENLOG_G_ERR "out of memory building monitor pagetable\n");
|
||||
domain_crash(d);
|
||||
if ( !d->is_dying &&
|
||||
(!d->is_shutting_down || d->shutdown_code != SHUTDOWN_crash) )
|
||||
{
|
||||
printk(XENLOG_G_ERR "%pd: out of memory building monitor pagetable\n",
|
||||
d);
|
||||
domain_crash(d);
|
||||
}
|
||||
return INVALID_MFN;
|
||||
}
|
||||
|
||||
@@ -766,6 +772,9 @@ static void hap_update_paging_modes(struct vcpu *v)
|
||||
if ( pagetable_is_null(v->arch.hvm.monitor_table) )
|
||||
{
|
||||
mfn_t mmfn = hap_make_monitor_table(v);
|
||||
|
||||
if ( mfn_eq(mmfn, INVALID_MFN) )
|
||||
goto unlock;
|
||||
v->arch.hvm.monitor_table = pagetable_from_mfn(mmfn);
|
||||
make_cr3(v, mmfn);
|
||||
hvm_update_host_cr3(v);
|
||||
@@ -774,6 +783,7 @@ static void hap_update_paging_modes(struct vcpu *v)
|
||||
/* CR3 is effectively updated by a mode change. Flush ASIDs, etc. */
|
||||
hap_update_cr3(v, 0, false);
|
||||
|
||||
unlock:
|
||||
paging_unlock(d);
|
||||
put_gfn(d, cr3_gfn);
|
||||
}
|
||||
|
||||