public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Michael Young <m.a.young@durham.ac.uk>
To: git-commits@fedoraproject.org
Subject: [rpms/xen] f43: 5 security updates
Date: Thu, 17 Sep 2026 20:03:52 GMT [thread overview]
Message-ID: <178967543260.1.17959382269866225845.rpms-xen-942ba477bb71@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : rpms/xen
Branch : f43
Commit : 942ba477bb716b9129875637627211b1251fe6dc
Author : Michael Young <m.a.young@durham.ac.uk>
Date : 2026-09-17T21:02:04+01:00
Stats : +451/-89 in 7 file(s)
URL : https://src.fedoraproject.org/rpms/xen/c/942ba477bb716b9129875637627211b1251fe6dc?branch=f43
Log:
5 security updates
x86: DMs may cause mem leak by IRQ binding [XSA-509, CVE-2026-62437]
x86: improper handling of HVM emulation return codes
[XSA-510, CVE-2026-79602]
Unconditionally do TLB flushing ahead of page scrubbing
[XSA-511, CVE-2026-79603]
oxenstored: Unbounded accumulation of watches [XSA-512, CVE-2026-79604]
---
diff --git a/xen.git-c403cf9e742a20e0aadbe04c1ab0ce9621184037.patch b/xen.git-c403cf9e742a20e0aadbe04c1ab0ce9621184037.patch
deleted file mode 100644
index ab1ac2c..0000000
--- a/xen.git-c403cf9e742a20e0aadbe04c1ab0ce9621184037.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From c403cf9e742a20e0aadbe04c1ab0ce9621184037 Mon Sep 17 00:00:00 2001
-From: Andrew Cooper <andrew.cooper3@citrix.com>
-Date: Fri, 10 Apr 2026 21:55:46 +0100
-Subject: [PATCH] x86/amd: Mitigate AMD-SN-7053 / FP-DSS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=utf8
-Content-Transfer-Encoding: 8bit
-
-This is XSA-488 / CVE-2025-54505
-
-Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-(cherry picked from commit 99912d346009fda1e7fb1510c9501fbab17e92a0)
----
- xen/arch/x86/cpu/amd.c | 37 ++++++++++++++++++++++++++++
- xen/arch/x86/include/asm/msr-index.h | 1 +
- 2 files changed, 38 insertions(+)
-
-diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
-index d5069a7ec1..43883e04db 100644
---- a/xen/arch/x86/cpu/amd.c
-+++ b/xen/arch/x86/cpu/amd.c
-@@ -982,6 +982,42 @@ void amd_init_de_cfg(const struct cpuinfo_x86 *c)
- wrmsrl(MSR_AMD64_DE_CFG, val | new);
- }
-
-+static void amd_init_fp_cfg(const struct cpuinfo_x86 *c)
-+{
-+ uint64_t val, new = 0;
-+
-+ /* If virtualised, we won't have mutable access even if we can read it. */
-+ if ( cpu_has_hypervisor )
-+ return;
-+
-+ /*
-+ * On Zen1, mitigate SB-7053 / FP-DSS Floating Point Divider State
-+ * Sampling by setting bit 9 as instructed.
-+ */
-+ if ( c->x86 == 0x17 && is_zen1_uarch() )
-+ new |= 1 << 9;
-+
-+ /*
-+ * Avoid reading FP_CFG if we don't intend to change anything. The
-+ * register doesn't exist on all families.
-+ */
-+ if ( !new )
-+ return;
-+
-+ rdmsrl(MSR_AMD64_FP_CFG, val);
-+
-+ if ( (val & new) == new )
-+ return;
-+
-+ /*
-+ * FP_CFG is a Core-scoped MSR, and this write is racy. However, both
-+ * threads calculate the new value from state which expected to be
-+ * consistent across CPUs and unrelated to the old value, so the result
-+ * should be consistent.
-+ */
-+ wrmsrl(MSR_AMD64_FP_CFG, val | new);
-+}
-+
- void __init amd_init_lfence_dispatch(void)
- {
- struct cpuinfo_x86 *c = &boot_cpu_data;
-@@ -1055,6 +1091,7 @@ static void cf_check init_amd(struct cpuinfo_x86 *c)
- unsigned long long value;
-
- amd_init_de_cfg(c);
-+ amd_init_fp_cfg(c);
-
- if (c == &boot_cpu_data)
- amd_init_lfence_dispatch(); /* Needs amd_init_de_cfg() */
-diff --git a/xen/arch/x86/include/asm/msr-index.h b/xen/arch/x86/include/asm/msr-index.h
-index 6f2c3147e3..70e5f09a2d 100644
---- a/xen/arch/x86/include/asm/msr-index.h
-+++ b/xen/arch/x86/include/asm/msr-index.h
-@@ -411,6 +411,7 @@
- #define MSR_AMD64_LS_CFG 0xc0011020U
- #define MSR_AMD64_IC_CFG 0xc0011021U
- #define MSR_AMD64_DC_CFG 0xc0011022U
-+#define MSR_AMD64_FP_CFG 0xc0011028U
- #define MSR_AMD64_DE_CFG 0xc0011029U
- #define AMD64_DE_CFG_LFENCE_SERIALISE (_AC(1, ULL) << 1)
- #define MSR_AMD64_EX_CFG 0xc001102cU
---
-2.39.5
-
diff --git a/xen.spec b/xen.spec
index eef64c5..ff717e3 100644
--- a/xen.spec
+++ b/xen.spec
@@ -51,7 +51,7 @@
Summary: Xen is a virtual machine monitor
Name: xen
Version: 4.20.4
-Release: 1%{?dist}
+Release: 2%{?dist}
# Automatically converted from old format: GPLv2+ and LGPLv2+ and BSD - review is highly recommended.
License: GPL-2.0-or-later AND LicenseRef-Callaway-LGPLv2+ AND LicenseRef-Callaway-BSD
URL: http://xen.org/
@@ -78,6 +78,11 @@ Patch43: xen.gcc11.fixes.patch
Patch45: xen.gcc12.fixes.patch
Patch46: xen.efi.build.patch
Patch49: xen.python3.12.patch
+Patch50: xsa509.patch
+Patch51: xsa510.patch
+Patch52: xsa511-4.20.patch
+Patch53: xsa512-1.patch
+Patch54: xsa512-2.patch
# build using Fedora seabios and ipxe packages for roms
@@ -256,6 +261,12 @@ manage Xen virtual machines.
%patch 43 -p1
%patch 45 -p1
%patch 46 -p1
+%patch 49 -p1
+%patch 50 -p1
+%patch 51 -p1
+%patch 52 -p1
+%patch 53 -p1
+%patch 54 -p1
# stubdom sources
cp -v %{SOURCE10} %{SOURCE11} %{SOURCE12} %{SOURCE13} %{SOURCE14} %{SOURCE15} stubdom
@@ -805,6 +816,14 @@ fi
%endif
%changelog
+* Thu Sep 17 2026 Michael Young <m.a.young@durham.ac.uk> - 4.20.4-2
+- x86: DMs may cause mem leak by IRQ binding [XSA-509, CVE-2026-62437]
+ x86: improper handling of HVM emulation return codes
+ [XSA-510, CVE-2026-79602]
+ Unconditionally do TLB flushing ahead of page scrubbing [XSA-511,
+ CVE-2026-79603]
+ oxenstored: Unbounded accumulation of watches [XSA-512, CVE-2026-79604]
+
* Thu Jul 30 2026 Michael Young <m.a.young@durham.ac.uk> - 4.20.4-1
- update to xen 4.20.4
- includes security fixes
diff --git a/xsa509.patch b/xsa509.patch
new file mode 100644
index 0000000..51cae81
--- /dev/null
+++ b/xsa509.patch
@@ -0,0 +1,33 @@
+From: Jan Beulich <jbeulich@suse.com>
+Subject: 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: 7a26b541a202 ("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>
+
+--- a/xen/drivers/passthrough/x86/hvm.c
++++ b/xen/drivers/passthrough/x86/hvm.c
+@@ -231,6 +231,12 @@ int pt_irq_create_bind(
+ restart:
+ write_lock(&d->event_lock);
+
++ if ( d->is_dying )
++ {
++ write_unlock(&d->event_lock);
++ return -ESRCH;
++ }
++
+ hvm_irq_dpci = domain_get_irq_dpci(d);
+ if ( !hvm_irq_dpci && !is_hardware_domain(d) )
+ {
diff --git a/xsa510.patch b/xsa510.patch
new file mode 100644
index 0000000..0ad3b49
--- /dev/null
+++ b/xsa510.patch
@@ -0,0 +1,39 @@
+From 796537311797d600c0c716d0c015531fc41abb92 Mon Sep 17 00:00:00 2001
+From: Roger Pau Monne <roger@xenproject.org>
+Date: Fri, 7 Aug 2026 11:03:48 +0200
+Subject: [PATCH] x86/emul: cope with internal handlers returning X86EMUL_RETRY
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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>
+---
+ xen/arch/x86/hvm/emulate.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
+index 2efb1d4f0823..c09ea002ec62 100644
+--- a/xen/arch/x86/hvm/emulate.c
++++ b/xen/arch/x86/hvm/emulate.c
+@@ -308,6 +308,7 @@ static int hvmemul_do_io(
+ switch ( rc )
+ {
+ case X86EMUL_OKAY:
++ case X86EMUL_RETRY:
+ vio->req.state = STATE_IOREQ_NONE;
+ break;
+ case X86EMUL_UNHANDLEABLE:
+--
+2.53.0
+
diff --git a/xsa511-4.20.patch b/xsa511-4.20.patch
new file mode 100644
index 0000000..36ca6f8
--- /dev/null
+++ b/xsa511-4.20.patch
@@ -0,0 +1,201 @@
+From 741ee5ab7303200098322ff5e8732d409f356981 Mon Sep 17 00:00:00 2001
+From: Roger Pau Monne <roger@xenproject.org>
+Date: Tue, 4 Aug 2026 12:23:19 +0200
+Subject: [PATCH] xen/page_alloc: ensure TLB flush is done ahead of page
+ scrubbing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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: 24f1a58d1954 ("mm: option to _always_ scrub freed domheap pages")
+Signed-off-by: Roger Pau Monné <roger@xenproject.org>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+---
+ xen/common/memory.c | 21 ---------------------
+ xen/common/page_alloc.c | 34 +++++++++++++++++++---------------
+ xen/include/xen/mm.h | 2 --
+ 3 files changed, 19 insertions(+), 38 deletions(-)
+
+diff --git a/xen/common/memory.c b/xen/common/memory.c
+index 7a00bf95ddcf..54d2d60fcc5f 100644
+--- a/xen/common/memory.c
++++ b/xen/common/memory.c
+@@ -163,8 +163,6 @@ static void populate_physmap(struct memop_args *a)
+ unsigned int i, j;
+ xen_pfn_t gpfn;
+ struct domain *d = a->domain, *curr_d = current->domain;
+- bool need_tlbflush = false;
+- uint32_t tlbflush_timestamp = 0;
+
+ if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done,
+ a->nr_extents-1) )
+@@ -176,15 +174,6 @@ static void populate_physmap(struct memop_args *a)
+
+ if ( unlikely(!d->creation_finished) )
+ {
+- /*
+- * With MEMF_no_tlbflush set, alloc_heap_pages() will ignore
+- * TLB-flushes. After VM creation, this is a security issue (it can
+- * make pages accessible to guest B, when guest A may still have a
+- * cached mapping to them). So we do this only during domain creation,
+- * when the domain itself has not yet been unpaused for the first
+- * time.
+- */
+- a->memflags |= MEMF_no_tlbflush;
+ /*
+ * With MEMF_no_icache_flush, alloc_heap_pages() will skip
+ * performing icache flushes. We do it only before domain
+@@ -284,13 +273,6 @@ static void populate_physmap(struct memop_args *a)
+ goto out;
+ }
+
+- if ( unlikely(a->memflags & MEMF_no_tlbflush) )
+- {
+- for ( j = 0; j < (1U << a->extent_order); j++ )
+- accumulate_tlbflush(&need_tlbflush, &page[j],
+- &tlbflush_timestamp);
+- }
+-
+ mfn = page_to_mfn(page);
+ }
+
+@@ -305,9 +287,6 @@ static void populate_physmap(struct memop_args *a)
+ }
+
+ out:
+- if ( need_tlbflush )
+- filtered_flush_tlb_mask(tlbflush_timestamp);
+-
+ if ( a->memflags & MEMF_no_icache_flush )
+ invalidate_icache();
+
+diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
+index 0a0ebc15981b..2682fff9ccbc 100644
+--- a/xen/common/page_alloc.c
++++ b/xen/common/page_alloc.c
+@@ -1068,15 +1068,17 @@ static struct page_info *alloc_heap_pages(
+ /* Preserve PGC_need_scrub so we can check it after lock is dropped. */
+ pg[i].count_info = PGC_state_inuse | (pg[i].count_info & PGC_need_scrub);
+
+- if ( !(memflags & MEMF_no_tlbflush) )
+- accumulate_tlbflush(&need_tlbflush, &pg[i],
+- &tlbflush_timestamp);
++ accumulate_tlbflush(&need_tlbflush, &pg[i], &tlbflush_timestamp);
+
+ init_free_page_fields(&pg[i]);
+ }
+
+ spin_unlock(&heap_lock);
+
++ /* Flush ahead of scrubbing: ensure no PV domain has a stale TLB entry. */
++ if ( need_tlbflush )
++ filtered_flush_tlb_mask(tlbflush_timestamp);
++
+ if ( first_dirty != INVALID_DIRTY_IDX ||
+ (scrub_debug && !(memflags & MEMF_no_scrub)) )
+ {
+@@ -1101,9 +1103,6 @@ static struct page_info *alloc_heap_pages(
+ }
+ }
+
+- if ( need_tlbflush )
+- filtered_flush_tlb_mask(tlbflush_timestamp);
+-
+ /*
+ * Ensure cache and RAM are consistent for platforms where the guest
+ * can control its own visibility of/through the cache.
+@@ -1357,6 +1356,13 @@ bool scrub_free_pages(void)
+ {
+ if ( test_bit(_PGC_need_scrub, &pg[i].count_info) )
+ {
++ bool need_tlbflush = false;
++ uint32_t tlbflush_ts = 0;
++
++ accumulate_tlbflush(&need_tlbflush, &pg[i], &tlbflush_ts);
++ if ( need_tlbflush )
++ filtered_flush_tlb_mask(tlbflush_ts);
++
+ scrub_one_page(&pg[i]);
+ /*
+ * We can modify count_info without holding heap
+@@ -2040,7 +2046,7 @@ static struct page_info *alloc_color_heap_page(unsigned int memflags,
+ uint32_t tlbflush_timestamp = 0;
+ bool need_scrub;
+
+- if ( memflags & ~(MEMF_no_refcount | MEMF_no_owner | MEMF_no_tlbflush |
++ if ( memflags & ~(MEMF_no_refcount | MEMF_no_owner |
+ MEMF_no_icache_flush | MEMF_no_scrub) )
+ return NULL;
+
+@@ -2069,13 +2075,16 @@ static struct page_info *alloc_color_heap_page(unsigned int memflags,
+ free_colored_pages[color]--;
+ page_list_del(pg, color_heap(color));
+
+- if ( !(memflags & MEMF_no_tlbflush) )
+- accumulate_tlbflush(&need_tlbflush, pg, &tlbflush_timestamp);
++ accumulate_tlbflush(&need_tlbflush, pg, &tlbflush_timestamp);
+
+ init_free_page_fields(pg);
+
+ spin_unlock(&heap_lock);
+
++ /* Flush ahead of scrubbing: ensure no PV domain has a stale TLB entry. */
++ if ( need_tlbflush )
++ filtered_flush_tlb_mask(tlbflush_timestamp);
++
+ if ( !(memflags & MEMF_no_scrub) )
+ {
+ if ( need_scrub )
+@@ -2084,9 +2093,6 @@ static struct page_info *alloc_color_heap_page(unsigned int memflags,
+ check_one_page(pg);
+ }
+
+- if ( need_tlbflush )
+- filtered_flush_tlb_mask(tlbflush_timestamp);
+-
+ flush_page_to_ram(mfn_x(page_to_mfn(pg)),
+ !(memflags & MEMF_no_icache_flush));
+
+@@ -2999,9 +3005,7 @@ static bool prepare_staticmem_pages(struct page_info *pg, unsigned long nr_mfns,
+ goto out_err;
+ }
+
+- if ( !(memflags & MEMF_no_tlbflush) )
+- accumulate_tlbflush(&need_tlbflush, &pg[i],
+- &tlbflush_timestamp);
++ accumulate_tlbflush(&need_tlbflush, &pg[i], &tlbflush_timestamp);
+
+ /*
+ * Preserve flag PGC_static and change page state
+diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
+index 16f733281af3..d128541e2cf8 100644
+--- a/xen/include/xen/mm.h
++++ b/xen/include/xen/mm.h
+@@ -202,8 +202,6 @@ struct npfec {
+ #define MEMF_exact_node (1U<<_MEMF_exact_node)
+ #define _MEMF_no_owner 5
+ #define MEMF_no_owner (1U<<_MEMF_no_owner)
+-#define _MEMF_no_tlbflush 6
+-#define MEMF_no_tlbflush (1U<<_MEMF_no_tlbflush)
+ #define _MEMF_no_icache_flush 7
+ #define MEMF_no_icache_flush (1U<<_MEMF_no_icache_flush)
+ #define _MEMF_no_scrub 8
+--
+2.53.0
+
diff --git a/xsa512-1.patch b/xsa512-1.patch
new file mode 100644
index 0000000..9d0256e
--- /dev/null
+++ b/xsa512-1.patch
@@ -0,0 +1,80 @@
+From 5332a2c46db4f96e5d5a57100c55076fe5610beb Mon Sep 17 00:00:00 2001
+From: Andrii Sultanov <andriy.sultanov@vates.tech>
+Date: Thu, 20 Aug 2026 16:00:02 +0100
+Subject: 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>
+
+diff --git a/tools/ocaml/xenstored/history.ml b/tools/ocaml/xenstored/history.ml
+index f03fb1832923..3474a62da230 100644
+--- a/tools/ocaml/xenstored/history.ml
++++ b/tools/ocaml/xenstored/history.ml
+@@ -39,10 +39,6 @@ let end_transaction txn con tid commit =
+ trim ~txn ();
+ success
+
+-let reconnect con =
+- trim ();
+- Connection.do_reconnect con
+-
+ let push (x: history_record) =
+ let dom = x.con.Connection.dom in
+ match dom with
+diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
+index 0c9c460a9915..bc68c54c9aba 100644
+--- a/tools/ocaml/xenstored/process.ml
++++ b/tools/ocaml/xenstored/process.ml
+@@ -350,6 +350,13 @@ let do_reset_watches con _t _domains cons _data =
+ Connections.del_watches cons con;
+ Connection.del_transactions con
+
++let do_reconnect cons con =
++ let domstr = Connection.get_domstr con in
++ info "%s requests a reconnect" domstr;
++ History.trim ();
++ Connection.do_reconnect con;
++ info "%s reconnection complete" domstr
++
+ (* only in >= xen3.3 *)
+ let do_set_target con _t _domains cons data =
+ if not (Connection.is_dom0 con)
+@@ -735,9 +742,7 @@ let do_input store cons doms con =
+ if Connection.can_input con then Connection.do_input con
+ else None
+ with Xenbus.Xb.Reconnect ->
+- info "%s requests a reconnect" (Connection.get_domstr con);
+- History.reconnect con;
+- info "%s reconnection complete" (Connection.get_domstr con);
++ do_reconnect cons con;
+ None
+ | Invalid_argument exp | Failure exp ->
+ error "caught exception %s" exp;
+@@ -760,7 +765,7 @@ let do_input store cons doms con =
+ write_access_log ~ty ~tid ~con:(Connection.get_domstr con) ~data;
+ Connection.incr_ops con
+
+-let do_output _store _cons _doms con =
++let do_output _store cons _doms con =
+ Connection.source_flush_watchevents con;
+ if Connection.has_output con then (
+ if Connection.has_new_output con then (
+@@ -775,8 +780,6 @@ let do_output _store _cons _doms con =
+ try
+ ignore (Connection.do_output con)
+ with Xenbus.Xb.Reconnect ->
+- info "%s requests a reconnect" (Connection.get_domstr con);
+- History.reconnect con;
+- info "%s reconnection complete" (Connection.get_domstr con)
++ do_reconnect cons con
+ )
+
diff --git a/xsa512-2.patch b/xsa512-2.patch
new file mode 100644
index 0000000..42252e8
--- /dev/null
+++ b/xsa512-2.patch
@@ -0,0 +1,78 @@
+From 8dc4ca50e62f2587a0213b078fc908fdfb54828b Mon Sep 17 00:00:00 2001
+From: Andrii Sultanov <andriy.sultanov@vates.tech>
+Date: Thu, 20 Aug 2026 15:00:02 +0000
+Subject: 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 491a077ed4c5
+("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: 674ad2be409d ("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>
+
+diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
+index d11011e16439..37eb2444b936 100644
+--- a/tools/ocaml/xenstored/connection.ml
++++ b/tools/ocaml/xenstored/connection.ml
+@@ -148,13 +148,11 @@ let mark_as_bad con =
+ let initial_next_tid = 1
+
+ let do_reconnect con =
++ (* transactions and watches handled by caller *)
+ Xenbus.Xb.reconnect con.xb;
+ (* dom is the same *)
+- Hashtbl.clear con.transactions;
+ con.next_tid <- initial_next_tid;
+- Hashtbl.clear con.watches;
+ (* anonid is the same *)
+- con.nb_watches <- 0;
+ con.stat_nb_ops <- 0;
+ (* perm is the same *)
+ ()
+diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
+index bc68c54c9aba..fc2558ac3d9b 100644
+--- a/tools/ocaml/xenstored/process.ml
++++ b/tools/ocaml/xenstored/process.ml
+@@ -345,15 +345,18 @@ let do_isintroduced con _t domains _cons data =
+ in
+ if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
+
+-(* only in xen >= 4.2 *)
+-let do_reset_watches con _t _domains cons _data =
++let reset_watches_and_transactions cons con =
+ Connections.del_watches cons con;
+- Connection.del_transactions con
++ Connection.del_transactions con;
++ History.trim ()
++
++let do_reset_watches con _t _domains cons _data =
++ reset_watches_and_transactions cons con
+
+ let do_reconnect cons con =
+ let domstr = Connection.get_domstr con in
+ info "%s requests a reconnect" domstr;
+- History.trim ();
++ reset_watches_and_transactions cons con;
+ Connection.do_reconnect con;
+ info "%s reconnection complete" domstr
+
reply other threads:[~2026-09-17 20:03 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178967543260.1.17959382269866225845.rpms-xen-942ba477bb71@fedoraproject.org \
--to=m.a.young@durham.ac.uk \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox