From 549312692de1d22e70be75b9339ef1e575baa964 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/oxenstored/history.ml b/oxenstored/history.ml
index be1994f18020..490d7a0ee66e 100644
--- a/oxenstored/history.ml
+++ b/oxenstored/history.ml
@@ -41,10 +41,6 @@ let end_transaction txn con tid commit =
   let success = Connection.end_transaction con tid commit in
   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/oxenstored/process.ml b/oxenstored/process.ml
index 477b4e41b3be..523ad4faafd8 100644
--- a/oxenstored/process.ml
+++ b/oxenstored/process.ml
@@ -477,6 +477,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) then
@@ -976,10 +983,7 @@ let do_input store cons doms con =
         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) ;
-        None
+        do_reconnect cons con ; None
     | Invalid_argument exp | Failure exp ->
         error "caught exception %s" exp ;
         error "got a bad client %s" (sprintf "%-8s" (Connection.get_domstr con)) ;
@@ -1002,7 +1006,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
@@ -1015,8 +1019,5 @@ let do_output _store _cons _doms con =
         write_answer_log ~ty ~tid ~con:(Connection.get_domstr con) ~data
     ) ;
     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)
+    with Xenbus.Xb.Reconnect -> do_reconnect cons con
   )
