|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] x86/pagewalk: Read guest PTEs with ACCESS_ONCE()
commit 0345b835dc97dcd995e24df21c5ad6183907926e
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Thu Aug 6 23:35:49 2026 +0100
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Tue Sep 1 22:33:57 2026 +0100
x86/pagewalk: Read guest PTEs with ACCESS_ONCE()
This has been a plain C read for as far back as I can trace in history.
Research into invented-loads has flagged it as a possible vulnerability.
After analysis, it is believed to be a bug only, not a security
vulnerability.
The analysis suggests that we can read one value out of the guest, operate
on
another, and that this could be an in-guest privliege escalation. Any
entity
in the guest able to modify the pagetables already has full privilege, so
while Xen can potentially malfunction, the effects don't cross a privilege
boundary.
The analysis also suggests that this is worse for shadow guests because we
may
put the TOCTOU entry in the shadows, but this is inaccurate. What we put in
the shadows is still translated under the P2M and refers to guest physical
address space.
Either way, the code fits the pattern for invented loads, and it is a risk;
harden the accesses.
Link:
https://github.com/xoreaxeaxeax/schrodingers-toctou/blob/main/observer-effect/audits/audit-xen-ptwalk-RELEASE-4.21.1.md#86-per-candidate-finding
Fixes: 49f7c7364e0a ("Replace shadow pagetable code with shadow2.")
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Acked-by: Roger Pau Monné <roger@xxxxxxxxxxxxxx>
---
xen/arch/x86/mm/guest_walk.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/xen/arch/x86/mm/guest_walk.c b/xen/arch/x86/mm/guest_walk.c
index f48c3ef75f..df2ccaa674 100644
--- a/xen/arch/x86/mm/guest_walk.c
+++ b/xen/arch/x86/mm/guest_walk.c
@@ -129,7 +129,7 @@ guest_walk_tables(const struct vcpu *v, struct p2m_domain
*p2m,
guest_l4_table_offset(va) * sizeof(gw->l4e);
if ( !hvmemul_read_cache(v, l4gpa, &gw->l4e, sizeof(gw->l4e)) )
{
- gw->l4e = l4p[guest_l4_table_offset(va)];
+ gw->l4e = (guest_l4e_t){
ACCESS_ONCE(l4p[guest_l4_table_offset(va)].l4) };
hvmemul_write_cache(v, l4gpa, &gw->l4e, sizeof(gw->l4e));
}
gflags = guest_l4e_get_flags(gw->l4e);
@@ -164,7 +164,7 @@ guest_walk_tables(const struct vcpu *v, struct p2m_domain
*p2m,
guest_l3_table_offset(va) * sizeof(gw->l3e);
if ( !hvmemul_read_cache(v, l3gpa, &gw->l3e, sizeof(gw->l3e)) )
{
- gw->l3e = l3p[guest_l3_table_offset(va)];
+ gw->l3e = (guest_l3e_t){
ACCESS_ONCE(l3p[guest_l3_table_offset(va)].l3) };
hvmemul_write_cache(v, l3gpa, &gw->l3e, sizeof(gw->l3e));
}
gflags = guest_l3e_get_flags(gw->l3e);
@@ -264,7 +264,7 @@ guest_walk_tables(const struct vcpu *v, struct p2m_domain
*p2m,
l2gpa += guest_l2_table_offset(va) * sizeof(gw->l2e);
if ( !hvmemul_read_cache(v, l2gpa, &gw->l2e, sizeof(gw->l2e)) )
{
- gw->l2e = l2p[guest_l2_table_offset(va)];
+ gw->l2e = (guest_l2e_t){
ACCESS_ONCE(l2p[guest_l2_table_offset(va)].l2) };
hvmemul_write_cache(v, l2gpa, &gw->l2e, sizeof(gw->l2e));
}
@@ -353,7 +353,7 @@ guest_walk_tables(const struct vcpu *v, struct p2m_domain
*p2m,
guest_l1_table_offset(va) * sizeof(gw->l1e);
if ( !hvmemul_read_cache(v, l1gpa, &gw->l1e, sizeof(gw->l1e)) )
{
- gw->l1e = l1p[guest_l1_table_offset(va)];
+ gw->l1e = (guest_l1e_t){
ACCESS_ONCE(l1p[guest_l1_table_offset(va)].l1) };
hvmemul_write_cache(v, l1gpa, &gw->l1e, sizeof(gw->l1e));
}
--
generated by git-patchbot for /home/xen/git/xen.git#staging
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |