Commit Graph
47760 Commits
Author SHA1 Message Date
Jan Beulich 3fce8895d9 gnttab: properly drop page ref on a GNTTAB_cache_flush error path
Ordinary domains always have a grant table. System domains don't, but they
also don't normally "own" pages - except for DOM_IO and DOM_COW on x86.

This is XSA-520 / CVE-2026-102700.

Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reported-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 6a355a772ca5205b8de29c58cfc3cef4f2ba8238)
2026-10-13 14:14:39 +01:00
Andrew Cooper 73e870d092 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 commit c89185286c)
2026-10-13 14:14:39 +01:00
Leonid Komarianskyi aa826e1378 xen/arm: page: fix size underflow in invalidate_dcache_va_range()
When the start address is not cacheline aligned, the bytes covered by
the first, partial cacheline are subtracted from 'size'. Nothing checks
that the region actually extends beyond that cacheline, so if it does
not, the unsigned subtraction underflows and the loop that follows walks
practically the entire address space.

For example, with a 64-byte cacheline, p = 0x40000001 and size = 1:

    p & cacheline_mask     -> 1, so the partial head is taken
    size -= 64 - 1         -> 1 - 63 underflows to 0xffffffffffffffc2

Instead of a single "dc civac" at 0x40000000, the loop then runs
288230376151711743 times, issuing "dc ivac" from 0x40000040 upwards.
Invalidating without cleaning discards dirty cachelines, so this
corrupts whatever is mapped along the way until Xen takes a data abort.

Moreover, _cache_flush() in common/grant_table.c, reachable from a guest
via GNTTABOP_cache_flush, bounds 'offset' and 'length' against the page
size but requires no alignment, so GNTTAB_CACHE_INVAL with offset = 1
and length = 1 is enough to trigger this. Note that the page may belong
to a different domain (the d != owner path), so the data being discarded
is not necessarily the caller's own.

The subtraction dates back to the fix for XSA-437, so this is a regression
in that change.

Fix this by detecting the underflow instead of letting it happen: if the
region ends inside the first cacheline, there is nothing left to flush
and the function bails out right after cleaning it. Partially covered
cachelines are still cleaned as well as invalidated, so that data outside
of the region is not discarded.

Additionally, drop 'idx' and advance 'p' directly instead. It simplifies
the logic while using fewer variables and less arithmetic.

Note that the partial head is now cleaned using the unaligned start of the
region instead of the start of its cacheline. This is permitted by the
architecture; the Arm ARM (DDI 0487) states:

  "When a DC instruction requires an address argument this takes the form
  of a 64-bit register that holds the VA argument. No alignment
  restrictions apply for this address."

The same applies on Arm32.

This is CVE-2026-102699, part of XSA-519.

Fixes: 9a216e92de ("xen/arm: page: Handle cache flush of an element at the top of the address space")
Signed-off-by: Leonid Komarianskyi <leonid_komarianskyi@epam.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Julien Grall <julien@xen.org>
2026-10-13 14:14:39 +01:00
Andrew Cooper cae3bfeb1e x86/vmx: Rework #DB intercept logic to fix VMEntry failure with BTF
The consistency checks in effect when Blocked-by-STI/MovSS are active includes
DEBUGCTL.BTF too.  Take this into account when editing PENDING_DBG.BS.

This ends up narrowing the cases where PENDING_DBG is modified.  Rework the
comment to be more precise.

This is XSA-518 / CVE-2026-79611.

Fixes: 1d3eb82598 ("x86/vtx: Work around SingleStep + STI/MovSS VMEntry failures")
Reported-by: Teddy Astie <teddy.astie@vates.tech>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
(cherry picked from commit 1017562ac0)
2026-10-13 14:14:39 +01:00
Jan Beulich 6199bad871 gnttab: address fallout from XSA-501
A v1 -> v2 change isn't the only scenario where "status" may go stale in
map_grant_ref(). Across a v2 -> v1 -> v2 change the status pages would
have been freed and re-populated, possibly changing the pages used for the
array. Check the pointer against the expected version-dependent value.

This is XSA-517 / CVE-2026-79610.

Fixes: 96dfeb4177 ("gnttab: cope with version changes racing other operations")
Assisted-by: Claude
Reported-by: Teddy Astie <teddy.astie@vates.tech>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
(cherry picked from commit e0a0823ee0)
2026-10-13 14:14:39 +01:00
George Dunlap 5d6c8688e9 x86/pv: map each vCPU's root page table in its per-domain area
For XPTI enabled VMs, restore_all_guest() copies most of the active L4
pagetable into the per-CPU root_pgt.  The L4 is read via the
directmap.

Unfortunately, there was no accounting for the fact that PV guests
have short directmaps.  For an L4 living beyond the 5T boundary (3.5T
for CONFIG_BIGMEM), Xen will copy arbitrary data from guest-controlled
virtual address space into the per-CPU root_pgt, instead of the
intended L4.

Xen has per-domain mappings for the LDT and GDT, with two pages
reserved for Xen's use in the GDT but only one in use.  Reuse GDT page
15 to map the effective L4.  The GDT limit keeps implicit accesses out
of this page.

We update this mapping in make_cr3(), the only place a non-empty value
of v->arch.cr3 is written into a guest's vcpu struct, for two reasons.
First is reference counting: this makes it easier to argue that the
reference for v->arch.cr3 itself covers the reference for the mapping.

Secondly, this guarantees that all updates, even updates made in
shadow mode, result in an update to the mapping.  During live
migration, it's possible for guest_get_eff_kern_l1e() to result in a
modified value of v->arch.cr3 (sketch below); placing the mapping
update at make_cr3() catches this, while other candidate locations
like write_ptbase() and toggle_guest_mode() don't.

Note that we introduce the idea of an "effective L4" here, to mean
"guest L4 after any transformations": XPTI copies either the actual
guest L4 if not shadowed, or the shadow L4 (transformed) if shadowed.

Sketch: guest_get_eff_kern_l1e() has a pair of toggle_guest_pt() calls
which happen if the guest is in user mode.  During live migration, a
log-dirty clean will do a domain_pause and then call
shadow_blow_tables(), unpinning the shadow of the guest user root
pagetable.  After execution resumes, the first toggle_guest_pt() could
then cause that page to become unshadowed.  The second
toggle_guest_pt() would then re-shadow it, possibly with a different
backing shadow page.

This is XSA-516 / CVE-2026-79609.

Fixes: 5784de3e20 ("x86: Meltdown band-aid against malicious 64-bit PV guests")
Assisted-by: Claude Code:claude-fable-5-1
Signed-off-by: George Dunlap <gwd@xenproject.org>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 288fb61585)
2026-10-13 14:14:39 +01:00
Andrew Cooper d3dbd1d604 x86/amd: Fix inverted condition in zenbleed_use_chickenbit()
The identified commit inverted the condition under which Xen chooses
to set the Zenbleed chickenbit.

Undo that, and leave a better comment explaining why.

Found by AI review of the referenced commit.

This is XSA-515 / CVE-2026-79608.

Fixes: d0c75dc4c0 ("x86/amd: Fix race editing DE_CFG")
Assisted-by: Sashiko + Opus 5.0
Reported-by: George Dunlap <dunlapg@umich.edu>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 0c5ec39d91)
2026-10-13 14:14:39 +01:00
Jan Beulich 41d194bf86 EFI: don't use alias attribute for compat hypercall stubs
Recent Clang objects to types differing between alias and aliasee. Accept
the unnecessary overhead and make the two compat stubs real functions.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
master commit: 5df9425a73
master date: 2026-09-09 14:15:15 +0200
2026-10-13 14:14:39 +01:00
Jan Beulich b4fcad1301 build: also exclude .data.rel.ro in $(cmd_obj_init_o)
.data.rel.ro really is merely a special case of .rodata: r/o data, but
with runtime relocations (not relevant to Xen), i.e. r/o only after
relocations were performed (by the dynamic loader).

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
master commit: f7eab298bb
master date: 2026-09-08 09:50:48 +0200
2026-10-13 14:14:39 +01:00
Andrii Sultanov 3f22c5d131 oxenstored: Reset the watches trie on domain reconnect
oxenstored maintains two datastructures about watches; one global trie, and
one hashtable tracked per domain.  Both need keeping in sync, and right now
the global trie is not emptied when a xenbus reconnect is requested.

This is basically the same bug as XSA-330, commit 491a077ed4
("tools/ocaml/xenstored: delete watch from trie too when resetting watches"),
just tickled via another path.

Arrange for both Process.do_reset_watches() and Process.do_reconnect() to
share a common codepath for the resetting of watches and transactions.
Notably, this means that the latter now calls Connections.del_watches() which
clears the global trie too.

Connections.del_watches() already calls Connection.del_watches() so remove the
re-clearing of the state from Connection.do_reconnect().

Move History.trim() into reset_watches_and_transactions() so it's on the
common path, and place it after removing the transactions rather than before.

This is part of XSA-512 / CVE-2026-79604.

Reported-by: David Korczynski <David@Adalogics.com>
Fixes: 674ad2be40 ("xenstore: extend the xenstore ring with a 'closing' signal")
Signed-off-by: Andrii Sultanov <andriy.sultanov@vates.tech>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Andrii Sultanov <andriy.sultanov@vates.tech>
(cherry picked from commit a2ca4f8b98)
2026-08-26 17:50:14 +01:00
Andrii Sultanov 160e04b0be oxenstored: Factor out Process.do_reconnect()
The logic flow here is complicated.  In preparation to fix a bug, factor out
reconnecting a xenbus connection, and fold History.reconnect into it's single
caller.

No functional change.

This is part of XSA-512 / CVE-2026-79604.

Signed-off-by: Andrii Sultanov <andriy.sultanov@vates.tech>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Andrii Sultanov <andriy.sultanov@vates.tech>
(cherry picked from commit 9c5a46b120)
2026-08-26 17:50:14 +01:00
Roger Pau Monne 6dd278418c xen/page_alloc: ensure TLB flush is done ahead of page scrubbing
The current way in which idle TLB flush and TLB flushing when allocating a
page are done allows for the scrubbing to be done ahead of the TLB flush.
A PV domain can still have a TLB entry for the page after scrubbing, and
hence it may be able to modify it.  Such unintended page accessing allows
domains to possibly exchange information even when `xsm=silo scrub-domheap`
are in effect.

Remove the MEMF_no_tlbflush memory allocation flag, and reorder the
flushing so it's always done ahead of the scrubbing in
alloc_{,color_}heap_pages().  The sole user of MEMF_no_tlbflush is
populate_physmap(), and given the constrains above it's no longer safe
to defer the flush, hence the flag removal and the folding of the flush in
the allocator function itself.

This is XSA-511 / CVE-2026-79603.

Fixes: 24f1a58d19 ("mm: option to _always_ scrub freed domheap pages")
Signed-off-by: Roger Pau Monné <roger@xenproject.org>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit ed7e656e6c)
2026-08-26 17:50:14 +01:00
Roger Pau Monne aabdb184bb x86/emul: cope with internal handlers returning X86EMUL_RETRY
hvm_io_intercept() can return X86EMUL_RETRY, and as such it needs to be
handled in the switch in hvmemul_do_io() to avoid triggering the BUG() from
the default case.

Reset the vCPU state to no in-flight IOREQ and return X86EMUL_RETRY so that
the access is retried.

This is XSA-510 / CVE-2026-79602.

Reported-by: Jiqian Chen <Jiqian.Chen@amd.com>
Signed-off-by: Roger Pau Monné <roger@xenproject.org>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 62aff07326)
2026-08-26 17:50:14 +01:00
Jan Beulich 5dd29d6c94 x86/pass-through: disallow pt_irq_create_bind() on dying domains
DMs may invoke XEN_DOMCTL_bind_pt_irq for domains already under
destruction. When XEN_DOMCTL_bind_pt_irq is invoked after
pci_release_devices() (invoked from underneath domain_kill()) had already
completed, it would allocate hvm_domain_irq(d)->dpci anew, without that
ever being freed during subsequent domain cleanup.

Leverage evtchn_destroy()'s kind-of-spin-barrier, allowing to simply check
->is_dying with the domain's event lock held.

This is XSA-509 / CVE-2026-62437.

Fixes: 7a26b541a2 ("vtd: Dynamically allocate IRQ-tracking structures, only for those")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
(cherry picked from commit 328a146143)
2026-08-26 17:50:14 +01:00
Jan Beulich 54ee7c511a update Xen version to 4.19.6 RELEASE-4.19.6 2026-07-29 15:34:38 +02:00
Jan Beulich 95d66a8910 pygrub: security-supported only when run de-privileged
XSA-443 and XSA-497 addressed specific issues in specific file system
drivers (libfsimage) used by pygrub. Further issues were reported, and yet
more are to be expected. XSA-443 introduced a means to run pygrub de-
privileged. Only this mode of operation is security supported from now on.

This is XSA-508.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
(cherry picked from commit 75f920bd47)
2026-07-28 13:08:52 +01:00
Roger Pau Monne 4c7248d1cf x86/pod: do not reclaim special pages for PoD cache
When doing PoD cache reclaim as part of a decrease reservation call, avoid
reclaiming special pages for the PoD cache.  Otherwise such pages get moved
from the domain ->xenpage_list to the ->page_list, while still being
referenced in ->shared_info domain field.

Prevent PoD cache from reclaiming special pages, as nothing good can come
out of it.

This is XSA-507 / CVE-2026-62434.

Fixes: 41aa0b6269 ("PoD memory 4/9: Decrease reservation")
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 372497ce42)
2026-07-28 13:08:52 +01:00
Roger Pau Monne 875c1baf3a xen/dmop: check number of input buffers
The hypercall requires at least one input buffer, as both arch-specific
implementations of dm_op() unconditionally assume ->buf[0] to be valid (and
not stack rubble).

Additionally, XEN_DMOP_modified_memory requires two input buffers, yet the
code was assuming the second buffer to always be provided by the user when
checking for the number of extents.  In case the caller sets nr_bufs to 1,
the code in modified_memory() will read stack garbage as the size of the
buffer, thus allowing the caller some degree of insight on the contents of
the stack by probing whether the hypercall returns -EINVAL or -EFAULT as a
result of such bogus call.

This is XSA-506 / CVE-2026-62433.

Fixes: e3b93b3c59 ("dmop: add xendevicemodel_modified_memory_bulk()")
Fixes: 85cb15dfe4 ("x86/hvm/dmop: only copy what is needed to/from the guest")
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit aef948a300)
2026-07-28 13:08:52 +01:00
Roger Pau Monne 011509a0c2 xen/evtchn: fix race between FIFO expand and reset operations
evtchn_fifo_expand_array() will check for the domain evtchn_fifo being
populated without holding the event_lock, which can lead to a race with a
concurrent evtchn_reset().

Ensure the checking for evtchn_fifo presence is done while holding the
event_lock.

This is XSA-505 / CVE-2026-62432.

Fixes: 400b3bd642 ("evtchn: make EVTCHNOP_reset suitable for kexec")
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
(cherry picked from commit 0e9d647aca)
2026-07-28 13:08:52 +01:00
Roger Pau Monne ba2f7f3309 x86/viridian: ensure count is always set when starting a timer
Otherwise in periodic mode a division by 0 would happen on the second call
to start_stimer() when using periodic mode.

Note that the HyperV specification states: "Writing the value zero to the
Count register will stop the counter, thereby disabling the timer,
independent of the setting of AutoEnable in the configuration register."
so a timer with a 0 count should never be in the enabled state.

This is XSA-504 / CVE-2026-62431.

Fixes: 26fba3c855 ("viridian: add implementation of synthetic timers")
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit ff7d9aa77e)
2026-07-28 13:08:52 +01:00
Roger Pau Monne ffe6e364c7 x86/vrtc: fix race in CMOS index checking
Do the checking for a valid CMOS index while holding the spinlock,
otherwise the value could be changed by the guest after having been
checked.

This is XSA-503 / CVE-2026-62430.

Fixes: 34bef0e6d5 ("hvm: Add locking to platform timers.")
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 52350da926)
2026-07-28 13:08:52 +01:00
Jan Beulich d1aebc7005 vNUMA: close race window in domain cleanup
Calling vnuma_destroy() without any locking can race the handling of both
XENMEM_get_vnumainfo and XEN_DOMCTL_setvnumainfo. While the latter is,
without Flask, strictly only exposed to the control domain, the former
can also be invoked by a stubdom DM or a de-privileged DM running in the
control domain. Isolate the logic used by XEN_DOMCTL_setvnumainfo into a
new helper function, which then is also used from domain_kill(). While
doing so also move the vnuma_destroy() invocation out of the locked
region.

With d->vnuma properly cleared by domain_kill(), XENMEM_get_vnumainfo now
really only needs to check for the field being NULL. That check needs
repeating, though, after re-acquiring the lock.

This is CVE-2026-62429 / XSA-502.

Fixes: 9695014966 ("xen: vnuma topology and subop hypercalls")
Reported-by: Teddy Astie <teddy.astie@vates.tech>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
(cherry picked from commit 2afa6fea9d)
2026-07-28 13:08:52 +01:00
Jan Beulich ee202319ef gnttab: cope with version changes racing other operations
Dropping and re-acquiring the grant table lock for a particular operation
requires special care, as in the meantime the grant table version can
change.

During a v2 -> v1 change, status frames going away means that pre-
calculated status pointers go stale, referencing freed (and possibly
already re-used) memory. Record in-flight v2 operations, permitting the
version change only when there are none of them. Recalculate "status" in
the one place (map_grant_ref()'s error path) where it could be stale, but
confine this to reserved entries.

This is CVE-2026-62436.

Reported-by: Mark Esler <mark@hexproof.dev>

During a v1 -> v2 change, the number of shared table entries reduces,
meaning that previously validated grant references may now be out of
bounds. Because of the checking of pin counts in gnttab_set_version()
(with the grant table lock held for writing), for now-out-of-bounds gref-s
neither active mappings can exist, nor can there be in-progress copy
operations. Nevertheless bounds checks are added there, just to be on the
safe side.

For gnttab_transfer(), to cover the gap between the lock being dropped by
gnttab_prepare_for_transfer() and it being re-acquired, have the helper
return the version it found, and fail the operation if the version turns
out to have changed after re-acquiring the lock.

Further avoid needless use of shared_entry_header(), as it involves
pointer arithmetic which, when using an out-of-bounds ref, is UB.

This is CVE-2026-62435.

Everything together is XSA-501.

Fixes: a98dc13703 ("Introduce a grant_entry_v2 structure")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Mark Esler <mark@hexproof.dev>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
(cherry picked from commit 96dfeb4177)
2026-07-28 13:08:52 +01:00
Jan Beulich 7dfed62794 gnttab: check values against active entry when copying an already-pinned one
acquire_grant_for_copy() passes to its caller both an MFN and a struct
page_info *. The two really need to be in sync for the get_page()
underlying get_paged_frame() and get_page_type() (both acting on the
passed back struct page_info *) and the map_domain_page() (acting on the
passed back MFN) to achieve the intended effect.

Go further and also check other properties: GTF_transitive / GTF_sub_page
may have been flipped in the shared entry, so respective fields / values
also may not match.

The one field which we can be sure does match (as it was checked earlier
in the function) is ->domid. Add an assertion nevertheless.

This is CVE-2026-62428 / XSA-500.

Fixes: d8cbecb1ee ("grant-tables: Use get_page_from_gfn() instead of get_gfn()/put_gfn")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
(cherry picked from commit 61b0a59ce2)
2026-07-28 13:08:52 +01:00
Jan Beulich fc159bcd70 sysctl/XSM: drop .page_offline() hook
Integrate the checking with xsm_sysctl(), now that it has the full op
struct passed. As a positive side effect, permissions are then checked at
the same early point with and without Flask.

This is part of CVE-2026-62426 / XSA-499.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-By: Daniel P. Smith <dpsmith@apertussolutions.com>
(cherry picked from commit 299de2aeda)
2026-07-28 13:08:52 +01:00
Jan Beulich 628cd49525 sysctl/XSM: drop .resource_{,un}plug_core() hooks
Integrate the checking with xsm_sysctl(), now that it has the full op
struct passed. As a positive side effect, permissions are then checked at
the same early point with and without Flask. Note that these were x86-
only, i.e. some dead/unreachable code gets eliminated for (in particular)
Arm.

This is part of CVE-2026-62426 / XSA-499.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-By: Daniel P. Smith <dpsmith@apertussolutions.com>
(cherry picked from commit 0501e1dc04)
2026-07-28 13:08:52 +01:00
Jan Beulich f2c03a8606 sysctl/XSM: drop .readconsole() hook
Integrate the checking with xsm_sysctl(), now that it has the full op
struct passed. As a positive side effect, permissions are then checked at
the same early point with and without Flask.

This is part of CVE-2026-62426 / XSA-499.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-By: Daniel P. Smith <dpsmith@apertussolutions.com>
(cherry picked from commit 4b249cba4b)
2026-07-28 13:08:52 +01:00
Jan Beulich 6159d36e76 sysctl/Flask: add preliminary check for XEN_SYSCTL_getdomaininfolist
To shield the sysctl lock from abuse by unauthorized domains, follow what
5154fdda11 ("domctl: protect locking for get_domain_state") did: Check
for permission to issue the operation against DOM_XEN in flask_sysctl().
The finer-grained xsm_getdomaininfo() later in the handling of the sub-op
remains unaltered.

In the in-tree policy respective permission therefore needs granting.

This is part of CVE-2026-62426 / XSA-499.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
(cherry picked from commit 3179bf2931)
2026-07-28 13:08:52 +01:00
Jan Beulich 4e7fdceee8 sysctl/XSM: drop .scheduler_op() hook
Integrate the checking with xsm_sysctl(), now that it has the full op
struct passed. As a positive side effect, permissions are then checked at
the same early point with and without Flask.

This is part of CVE-2026-62426 / XSA-499.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-By: Daniel P. Smith <dpsmith@apertussolutions.com>
(cherry picked from commit 751e371c91)
2026-07-28 13:08:52 +01:00
Jan Beulich 7592e51ca7 sysctl/XSM: pass full struct xen_sysctl to xsm_sysctl()
Subsequently some sub-ops will want to inspect their sub-sub-ops.

This is part of CVE-2026-62426 / XSA-499.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
(cherry picked from commit 9f4aa6d00a)
2026-07-28 13:08:52 +01:00
Jan Beulich 6e278ffe62 platform-op/XSM: move resource-{,un}plug-core checks
Integrate the checking with flask_platform_op(); there never really was a
need to defer these checks, as the sub-op has always been known to the
function. As a positive side effect, permissions are then checked at the
same early point with and without Flask.

This is CVE-2026-62427 / part of XSA-499.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-By: Daniel P. Smith <dpsmith@apertussolutions.com>
(cherry picked from commit 4ef45cbe31)
2026-07-28 13:08:52 +01:00
Syed Abdul Khaliq 21e31cc315 libfsimage/iso9660: harden Rock Ridge SUSP parsing against malformed lengths
The directory and Rock Ridge / SUSP walk in iso9660_dir() derives several
lengths directly from attacker-controlled on-disk fields without validating
them.  libfsimage is used by pygrub, which parses the filesystem of an
untrusted guest disk image from dom0, so these are reachable across a trust
boundary.

Five related problems are addressed:

  * The directory record loop advances by

        idr = (char *)idr + idr->length.l

    and only stops on length.l == 0.  A record whose length is smaller than
    the fixed part of the on-disk layout cannot hold its own mandatory
    fields, yet the body still reads name_len/extent/size and computes the
    System Use area length from it.  Require length to cover at least the
    fixed record (sizeof(*idr) - sizeof(idr->name)) before entering the body.

    This is CVE-2026-42494.

  * The System Use area length is computed before the inner loop as

        rr_len = idr->length.l - idr->name_len.l
                 - sizeof(struct iso_directory_record) + sizeof(idr->name);

    in unsigned arithmetic.  If length.l is smaller than name_len.l plus the
    fixed record size, rr_len underflows to a huge value and the whole SUSP
    walk runs off the directory buffer.  Guard the subtraction and treat such
    records as having no System Use area.

    This is CVE-2026-42495.

  * Inside the loop, each entry is consumed with

        rr_len -= rr_ptr.rr->len;
        rr_ptr.ptr += rr_ptr.rr->len;

    with no lower or upper bound on the entry's own len byte.  A len of 0
    spins forever; a len greater than the remaining rr_len underflows it and
    walks past the buffer.  Validate 4 <= len <= rr_len at the top of the
    loop and stop on violation: a structurally broken entry stream cannot be
    advanced reliably, so continuing is not meaningful.

    This is CVE-2026-62423.

  * The NM handler subtracted the 5-byte SUSP/NM header from len without a
    lower-bound check, underflowing name_len (the original report).  The
    generic check above only guarantees len >= 4; NM has an extra flags byte,
    so keep an NM-specific len >= 5 check.

    This is CVE-2026-62424.

  * The CE continuation resets rr_ptr/rr_len from ce.offset and ce.size, both
    image-controlled, into the fixed single-sector RRCONT_BUF with no bounds
    check.  Reject a window that does not fit in the buffer.

    This is CVE-2026-62425.

This is XSA-497.

Signed-off-by: Syed Abdul Khaliq <abdul@bugqore.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit fd11acab3d)
2026-07-28 13:08:52 +01:00
Jan Beulich 6cb914cb59 x86: SHADOW_PAGING is deprecated
Addressing certain issues, in particular related to operations which may
take excessively long and therefore would need preemption, has turned out
overly costly. Since alternatives (HVM/PVH: HAP, PV: shim) are commonly
available, the decision was to deprecate the functionality, while still
retaining it for people to use at their own (security) risk. Memory-wise
small enough guests may still be okay to run.

Some CI testing depends on SHADOW_PAGING.  Explicitly enable it when needed.

This is CVE-2026-42493 / XSA-495.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
(cherry picked from commit f2cac32029)
2026-07-28 13:08:52 +01:00
Andrew Cooper ecf0e89c29 CI: Use more specific Xilinx runner tags
In order to avoid serialising the testing on both boards, the runner
configuration is being adjusted.

Have the .xilinx-arm64 and .xilinx-x86_64 templates choose the board directly
using a more specific tag.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Victor Lira <victorm.lira@amd.com>
(cherry picked from commit efcb4c5e2f)
2026-06-16 18:17:45 +01:00
Andrew Cooper 96a8a2750a Revert local CI adjustments
This reverts commit e1eae714bf.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
2026-06-09 13:09:08 +01:00
Roger Pau Monne 376de64772 x86/mm: accurately track which vCPU page-tables are loaded
Neither current nor curr_vcpu per-CPU fields accurately track which
page-tables are loaded.  There are corner cases when dealing with shadow
paging failures that switch to the idle vCPU page-tables without changing
current or curr_vcpu per-CPU fields.

Introduce a new per-CPU field that attempts to track which vCPU page-tables
are loaded.  Update such tracking when cr3 is changed, and do so in a
region with interrupts disabled, as to avoid handling interrupts with a
mismatch between the vCPU tracking field and the loaded page-tables.

As a result of this newly more accurate tracking the mapcache override
functionality can be removed: the dom0 PV builder was the only user of it,
and it's updated here to properly signal which vCPU page-tables are loaded
in the calls to switch_cr3_cr4().

Note the EFI page-tables have the Xen owned L4 slots copied from the idle
page-tables, so for the effects of the mapcache the EFI page-tables could
use the idle mapcache if it had one.  Pass the idle vCPU in the
switch_cr3_cr4() call that switches to the runtime EFI page-tables.

There are known issues with the use of mapcache in NMI context.  This patch
does not alter the behaviour.

This is CVE-2026-42488 / XSA-494.

Fixes: fb0ff49fe9 ("x86/shadow: defer releasing of PV's top-level shadow reference")
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
(cherry picked from commit 622c9a5ba9)
2026-06-04 21:47:50 +01:00
Michal Orzel a9c8547cc8 xen/arm: Mitigate TLBI errata on various Arm CPUs
A number of CPUs developed by Arm suffer from errata whereby a broadcast
TLBI + DSB sequence may complete before the global observation of writes
which are translated by an affected TLB entry. This can lead to memory
corruption and potential privilege escalation.

These errata ONLY affect the completion of memory accesses which have
been translated by an invalidated TLB entry, and these errata DO NOT
affect the actual invalidation of TLB entries. TLB entries are removed
correctly.

To mitigate this issue, Arm recommends that software follows each
TLBI+DSB sequence with an additional TLBI+DSB, which will ensure that
all memory write effects affected by the first TLBI have been globally
observed.

The ARM64_WORKAROUND_REPEAT_TLBI workaround is sufficient to mitigate the
issue. Enable this workaround for affected CPUs.

This is XSA-493 / CVE-2025-10263.

Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Julien Grall <julien@xen.org>
(cherry picked from commit 161e8f61b5)
2026-06-04 21:47:50 +01:00
Michal Orzel 52b28b0cf7 xen/arm: Add C1-Premium definitions
Add processor definitions for C1-Premium. These will be used for errata
detection in subsequent patches.

These values can be found in the C1-Premium TRM:

  https://developer.arm.com/documentation/109416/0100/

... in section A.5.1 ("MIDR_EL1, Main ID Register").

Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Julien Grall <julien@xen.org>
(cherry picked from commit 0315d10321)
2026-06-04 21:47:50 +01:00
Michal Orzel 618173c131 xen/arm: Add C1-Ultra definitions
Add processor definitions for C1-Ultra. These will be used for errata
detection in subsequent patches.

These values can be found in the C1-Ultra TRM:

  https://developer.arm.com/documentation/108014/0100/

... in section A.5.1 ("MIDR_EL1, Main ID Register").

Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Julien Grall <julien@xen.org>
(cherry picked from commit 36ddaa7918)
2026-06-04 21:47:50 +01:00
Michal Orzel 1ea95e237d xen/arm: Sync missing definitions for Arm CPUs with Linux
Synchronize with Linux kernel 7.0 definitions for the following CPUs:
 - Cortex-A76AE,
 - Cortex-A78AE,
 - Cortex-X1C,
 - Cortex-X3,
 - Neoverse-V2,
 - Cortex-X4,
 - Neoverse-V3AE,
 - Neoverse-V3,
 - Cortex-X925.

These will be used for errata detection in subsequent patches.

Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Julien Grall <julien@xen.org>
(cherry picked from commit d54682a5b2)
2026-06-04 21:47:50 +01:00
Michal Orzel 54bb4e9972 xen/arm64: flushtlb: Optimize ARM64_WORKAROUND_REPEAT_TLBI
The ARM64_WORKAROUND_REPEAT_TLBI workaround is used to mitigate several
errata where broadcast TLBI;DSB sequences don't provide all the
architecturally required synchronization. The workaround performs more
work than necessary, and can have significant overhead. This patch
optimizes the workaround, as explained below.

1. All relevant errata only affect the ordering and/or completion of
   memory accesses which have been translated by an invalidated TLB
   entry. The actual invalidation of TLB entries is unaffected.

2. The existing workaround is applied to both broadcast and local TLB
   invalidation, whereas for all relevant errata it is only necessary to
   apply a workaround for broadcast invalidation.

3. The existing workaround replaces every TLBI with a TLBI;DSB;TLBI
   sequence, whereas for all relevant errata it is only necessary to
   execute a single additional TLBI;DSB sequence after any number of
   TLBIs are completed by a DSB.

   For example, for a sequence of batched TLBIs:

       TLBI <op1>[, <arg1>]
       TLBI <op2>[, <arg2>]
       TLBI <op3>[, <arg3>]
       DSB ISH

   ... the existing workaround will expand this to:

       TLBI <op1>[, <arg1>]
       DSB ISH                  // additional
       TLBI <op1>[, <arg1>]     // additional
       TLBI <op2>[, <arg2>]
       DSB ISH                  // additional
       TLBI <op2>[, <arg2>]     // additional
       TLBI <op3>[, <arg3>]
       DSB ISH                  // additional
       TLBI <op3>[, <arg3>]     // additional
       DSB ISH

   ... whereas it is sufficient to have:

       TLBI <op1>[, <arg1>]
       TLBI <op2>[, <arg2>]
       TLBI <op3>[, <arg3>]
       DSB ISH
       TLBI <opX>[, <argX>]     // additional
       DSB ISH                  // additional

   Using a single additional TLBI and DSB at the end of the sequence can
   have significantly lower overhead as each DSB which completes a TLBI
   must synchronize with other PEs in the system, with potential
   performance effects both locally and system-wide.

4. The existing workaround repeats each specific TLBI operation, whereas
   for all relevant errata it is sufficient for the additional TLBI to
   use *any* operation which will be broadcast, regardless of which
   translation regime or stage of translation the operation applies to.

   For example, for a single TLBI:

       TLBI ALLE2IS
       DSB ISH

   ... the existing workaround will expand this to:

       TLBI ALLE2IS
       DSB ISH
       TLBI ALLE2IS             // additional
       DSB ISH                  // additional

   ... whereas it is sufficient to have:

       TLBI ALLE2IS
       DSB ISH
       TLBI VALE1IS, XZR        // additional
       DSB ISH                  // additional

   As the additional TLBI doesn't have to match a specific earlier TLBI,
   the additional TLBI can be implemented in separate code, with no
   memory of the earlier TLBIs. The additional TLBI can also use a
   cheaper TLBI operation.

5. The existing workaround is applied to both Stage-1 and Stage-2 TLB
   invalidation, whereas for all relevant errata it is only necessary to
   apply a workaround for Stage-1 invalidation.

   Architecturally, TLBI operations which invalidate only Stage-2
   information (e.g. IPAS2E1IS) are not required to invalidate TLB
   entries which combine information from Stage-1 and Stage-2
   translation table entries, and consequently may not complete memory
   accesses translated by those combined entries. In these cases,
   completion of memory accesses is only guaranteed after subsequent
   invalidation of Stage-1 information (e.g. VMALLE1IS).

Rework the workaround logic as follows:
 - add TLB_HELPER_LOCAL() to be used for local TLB ops without a
   workaround,
 - modify TLB_HELPER() workaround to use tlbi vale2is, xzr as a second
   TLBI,
 - drop TLB_HELPER_VA(). It's used only by __flush_xen_tlb_one_local
   which is local and does not need workaround and by
   __flush_xen_tlb_one. In the latter case, since it's used in a loop,
   we don't need a workaround in the middle. Add __tlb_repeat_sync with
   a workaround to be used at the end after DSB and before final ISB,
 - TLBI VALE2IS passing XZR is used as an additional TLBI. While there is
   an identity mapping there, it's used very rarely. The performance
   impact is therefore negligible. If things change in the future, we
   can revisit the decision.

Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
(cherry picked from commit 7c502d7591)
2026-06-04 21:47:50 +01:00
Jan Beulich 17bce447ad domctl: handle XEN_DOMCTL_set_target without acquiring domctl lock
The only locking required here is that between checking d->target and
setting it. To avoid the need for an explicit lock, use cmpxchgptr() to
update d->target.

Move the handling not only ahead of acquiring the lock, but also ahead
of the XSM check, leveraging that the sub-op has its own hook.

This is part of XSA-492.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
(cherry picked from commit 4a93d1fb4f)
2026-06-04 21:47:50 +01:00
Jan Beulich 923d69856a domctl/XSM: drop {,de}assign_{,dt}device hooks
Integrate the checking with xsm_domctl(). As a positive side effect,
permissions are then checked at the same early point with and without
Flask. As the DT device path needs fetching earlier (but must not be
double fetched), cache it in a private field of the public interface
struct.

This is part of XSA-492.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
(cherry picked from commit eab54f074f)
2026-06-04 21:47:50 +01:00
Jan Beulich 4618e73b25 domctl: handle XEN_DOMCTL_get_device_group without acquiring domctl lock
iommu_get_device_group() uses its own locking. Thus, with caller side
locking irrelevant, it can as well be called with the domctl lock not
held.

Move the handling not only ahead of acquiring the lock, but also ahead
of the XSM check, leveraging that the sub-op has its own hook.

This is part of XSA-492.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
(cherry picked from commit 471b377747)
2026-06-04 21:47:50 +01:00
Jan Beulich 7fcb12d520 domctl/XSM: drop shadow_control_op hook
Integrate the checking with xsm_domctl(), now that it has the full op
struct passed. As a positive side effect, permissions are then checked at
the same early point with and without Flask.

This is part of XSA-492.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
(cherry picked from commit d9d2758622)
2026-06-04 21:47:50 +01:00
Jan Beulich c581c40088 domctl/XSM: drop scheduler_op hook
Integrate the checking with xsm_domctl(), now that it has the full op
struct passed. As a positive side effect, permissions are then checked at
the same early point with and without Flask.

This is part of XSA-492.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
(cherry picked from commit 3ba374d388)
2026-06-04 21:47:50 +01:00
Jan Beulich 5c86d123d7 domctl/XSM: pass full struct xen_domctl to xsm_domctl()
Subsequently some sub-ops will want to inspect their sub-sub-ops. Plus
this way we don't need to pass SSIDref separately anymore for
domain_create.

This is part of XSA-492.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
(cherry picked from commit 83f0e11ed1)
2026-06-04 21:47:50 +01:00
Jan Beulich fc86e21be9 domctl/XSM: drop vm_event_control hook
Integrate the checking with xsm_domctl(). Care needs to be taken with the
GET_VERSION sub-op, which may be invoked with DOMID_INVALID, and which has
been (and continues to be) bypassing XSM checking.

Since the latter two parameters were unused, monitor_domctl() invoking the
hook was actually redundant with the earlier xsm_domctl() (as can be seen
nicely from the hunks changing xsm/flask/hooks.c).

As a positive side effect, permissions are then checked at the same early
point with and without Flask.

While folding XEN_DOMCTL_monitor_op and XEN_DOMCTL_vm_event_op in
flask_domctl(), also fold in XEN_DOMCTL_set_access_required.

This is part of XSA-492.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
(cherry picked from commit b4a7c17146)
2026-06-04 21:47:50 +01:00
Jan Beulich 2ff10f2acd domctl: handle XEN_DOMCTL_irq_permission without acquiring domctl lock
With dedicated locking added, the domctl lock isn't required here anymore.
Move the re-purposed (XSM_HOOK -> XSM_PRIV, as xsm_domctl() is now
bypassed) dedicated XSM checks as early as possible.

This is part of XSA-492.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
2026-06-04 21:47:50 +01:00
Jan Beulich 3ca879ff74 domctl: handle XEN_DOMCTL_io{mem,port}_permission without acquiring domctl lock
With dedicated locking added, the domctl lock isn't required here anymore.
As the I/O port handling is in arch-specific code (x86 only), no code is
being moved, but the 2nd invocation of arch_do_domctl() is re-used. Move
the re-purposed dedicated XSM checks as early as possible.

This is part of XSA-492.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
(cherry picked from commit 9f54e10bf3)
2026-06-04 21:47:50 +01:00