xen/arm: Reject pseudo-domain foreign mappings in xenmem_add_to_physmap_one()

A privileged domain on Arm64 can trigger a data abort in the hypervisor
by issuing memory_op's XENMEM_add_to_physmap_batch sub-op with
space=XENMAPSPACE_gmfn_foreign, idx=0 and foreign_domid=DOMID_IO.

get_pg_owner(DOMID_IO) succeeds, returning a pointer to the dom_io
pseudo-domain. The subsequent get_page_from_gfn(dom_io, ...) then
attempts to walk dom_io's P2M table, which is not initialized for
pseudo-domains, resulting in a data abort in p2m_get_entry() when
it dereferences the invalid pointer returned by p2m_get_root_pointer().

Replace get_pg_owner() with explicit domain lookup logic matching
the x86 implementation: handle DOMID_XEN via rcu_lock_domain(dom_xen),
and resolve all other domain IDs via rcu_lock_remote_domain_by_id(),
which rejects pseudo-domains (DOMID_IO, etc.) that are not present in
the domain hash, returning -ESRCH before any P2M access occurs.

Fixes: 615897bc6c ("xen/arm: Allow a privileged domain to map foreign page from DOMID_XEN")
Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
Release-Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
This commit is contained in:
Oleksandr Tyshchenko authored and Michal Orzel committed 2026-07-23 09:03:17 +02:00
1 parent 99794c8a8f
commit f795a9c491
1 file changed
+16 -11
+16 -11
View File
@@ -191,20 +191,25 @@ int xenmem_add_to_physmap_one(
struct domain *od;
p2m_type_t p2mt;
od = get_pg_owner(extra.foreign_domid);
if ( od == NULL )
return -ESRCH;
if ( od == d )
if ( extra.foreign_domid == DOMID_XEN )
od = rcu_lock_domain(dom_xen);
else
{
put_pg_owner(od);
return -EINVAL;
rc = rcu_lock_remote_domain_by_id(extra.foreign_domid, &od);
if ( rc )
return rc;
if ( od == d )
{
rcu_unlock_domain(od);
return -EINVAL;
}
}
rc = xsm_map_gmfn_foreign(XSM_TARGET, d, od);
if ( rc )
{
put_pg_owner(od);
rcu_unlock_domain(od);
return rc;
}
@@ -213,7 +218,7 @@ int xenmem_add_to_physmap_one(
page = get_page_from_gfn(od, idx, &p2mt, P2M_ALLOC);
if ( !page )
{
put_pg_owner(od);
rcu_unlock_domain(od);
return -EINVAL;
}
@@ -222,13 +227,13 @@ int xenmem_add_to_physmap_one(
else
{
put_page(page);
put_pg_owner(od);
rcu_unlock_domain(od);
return -EINVAL;
}
mfn = page_to_mfn(page);
put_pg_owner(od);
rcu_unlock_domain(od);
break;
}
case XENMAPSPACE_dev_mmio:
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.