summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Grall <jgrall@amazon.com>2022-01-25 13:34:55 +0100
committerJan Beulich <jbeulich@suse.com>2022-01-25 13:34:55 +0100
commitacdb6744460c6264785c031a37d99b8557c56195 (patch)
treeade47dedaa29c954986d282220e25c00e932ad98
parent243026a2c5ad64c05281dc8ed2f1f57c0ee5988c (diff)
xen/arm: p2m: Always clear the P2M entry when the mapping is removed
Commit 2148a125b73b ("xen/arm: Track page accessed between batch of Set/Way operations") allowed an entry to be invalid from the CPU PoV (lpae_is_valid()) but valid for Xen (p2m_is_valid()). This is useful to track which page is accessed and only perform an action on them (e.g. clean & invalidate the cache after a set/way instruction). Unfortunately, __p2m_set_entry() is only zeroing the P2M entry when lpae_is_valid() returns true. This means the entry will not be zeroed if the entry was valid from Xen PoV but invalid from the CPU PoV for tracking purpose. As a consequence, this will allow a domain to continue to access the page after it was removed. Resolve the issue by always zeroing the entry if it the LPAE bit is set or the entry is about to be removed. This is CVE-2022-23033 / XSA-393. Reported-by: Dmytro Firsov <Dmytro_Firsov@epam.com> Fixes: 2148a125b73b ("xen/arm: Track page accessed between batch of Set/Way operations") Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Signed-off-by: Julien Grall <jgrall@amazon.com> master commit: a428b913a002eb2b7425b48029c20a52eeee1b5a master date: 2022-01-25 13:25:01 +0100
-rw-r--r--xen/arch/arm/p2m.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 8b20b43077..fb71fa4c1c 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -1016,7 +1016,7 @@ static int __p2m_set_entry(struct p2m_domain *p2m,
* sequence when updating the translation table (D4.7.1 in ARM DDI
* 0487A.j).
*/
- if ( lpae_is_valid(orig_pte) )
+ if ( lpae_is_valid(orig_pte) || removing_mapping )
p2m_remove_pte(entry, p2m->clean_pte);
if ( removing_mapping )