mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/gnttab: Prevent GNTTABOP_cache_flush from corrupting RO grants
Grants can be offered read-only by the owning domain. While a domain mapping a RO grant may have a need to invalidate the cache, it must not modify the other-guests data while doing so. Force-upgrade to a clean operation in this case. This is CVE-2026-102702, part of XSA-519. Fixes:18e8d22fe7("introduce GNTTABOP_cache_flush") Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> (cherry picked from commitc89185286c)
This commit is contained in:
1 parent
56deb42ba4
commit
b734d29eea
1 file changed
+26
-1
@@ -983,6 +983,13 @@ static struct active_grant_entry *grant_map_exists(const struct domain *ld,
|
|||||||
|
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool grant_map_is_ro(struct active_grant_entry *act)
|
||||||
|
{
|
||||||
|
ASSERT(spin_is_locked(&act->lock));
|
||||||
|
|
||||||
|
return (act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) == 0;
|
||||||
|
}
|
||||||
#endif /* CONFIG_HAS_GRANT_CACHE_FLUSH */
|
#endif /* CONFIG_HAS_GRANT_CACHE_FLUSH */
|
||||||
|
|
||||||
union maptrack_node {
|
union maptrack_node {
|
||||||
@@ -3598,7 +3605,7 @@ gnttab_swap_grant_ref(XEN_GUEST_HANDLE_PARAM(gnttab_swap_grant_ref_t) uop,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HAS_GRANT_CACHE_FLUSH
|
#ifdef CONFIG_HAS_GRANT_CACHE_FLUSH
|
||||||
static int _cache_flush(const gnttab_cache_flush_t *cflush, grant_ref_t *cur_ref)
|
static int _cache_flush(gnttab_cache_flush_t *cflush, grant_ref_t *cur_ref)
|
||||||
{
|
{
|
||||||
struct domain *d, *owner;
|
struct domain *d, *owner;
|
||||||
struct page_info *page;
|
struct page_info *page;
|
||||||
@@ -3649,6 +3656,24 @@ static int _cache_flush(const gnttab_cache_flush_t *cflush, grant_ref_t *cur_ref
|
|||||||
put_page(page);
|
put_page(page);
|
||||||
return act ? PTR_ERR(act) : 1;
|
return act ? PTR_ERR(act) : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the grant mapping is read-only, it must be cleaned as well as
|
||||||
|
* invalidated. Invalidation without cleaning may modify memory the
|
||||||
|
* granter is expecting not to change.
|
||||||
|
*
|
||||||
|
* It is highly unlikely but legal to have multiple grant mappings of
|
||||||
|
* differing read-only-ness. If a read-write grant mapping is found
|
||||||
|
* first, then it's fine to invalidate without clean.
|
||||||
|
*
|
||||||
|
* If a read-only grant mapping is found first, a later read-write
|
||||||
|
* mapping could be missed. Assume that the read-only mapping is the
|
||||||
|
* only mapping. The cost is a clean of up to 4k, while the saving is
|
||||||
|
* not requiring the search of grant maps to be exhaustive in order to
|
||||||
|
* spot a corner-case expected not to exist in practice.
|
||||||
|
*/
|
||||||
|
if ( grant_map_is_ro(act) )
|
||||||
|
cflush->op |= GNTTAB_CACHE_CLEAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
v = map_domain_page(mfn);
|
v = map_domain_page(mfn);
|
||||||
|
|||||||