mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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, commit491a077ed4("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 commita2ca4f8b98)
This commit is contained in:
1 parent
160e04b0be
commit
3f22c5d131
2 files changed
+8
-7
No files matched your search
@@ -148,13 +148,11 @@ let mark_as_bad con =
|
|||||||
let initial_next_tid = 1
|
let initial_next_tid = 1
|
||||||
|
|
||||||
let do_reconnect con =
|
let do_reconnect con =
|
||||||
|
(* transactions and watches handled by caller *)
|
||||||
Xenbus.Xb.reconnect con.xb;
|
Xenbus.Xb.reconnect con.xb;
|
||||||
(* dom is the same *)
|
(* dom is the same *)
|
||||||
Hashtbl.clear con.transactions;
|
|
||||||
con.next_tid <- initial_next_tid;
|
con.next_tid <- initial_next_tid;
|
||||||
Hashtbl.clear con.watches;
|
|
||||||
(* anonid is the same *)
|
(* anonid is the same *)
|
||||||
con.nb_watches <- 0;
|
|
||||||
con.stat_nb_ops <- 0;
|
con.stat_nb_ops <- 0;
|
||||||
(* perm is the same *)
|
(* perm is the same *)
|
||||||
()
|
()
|
||||||
|
|||||||
@@ -345,15 +345,18 @@ let do_isintroduced con _t domains _cons data =
|
|||||||
in
|
in
|
||||||
if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
|
if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
|
||||||
|
|
||||||
(* only in xen >= 4.2 *)
|
let reset_watches_and_transactions cons con =
|
||||||
let do_reset_watches con _t _domains cons _data =
|
|
||||||
Connections.del_watches 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 do_reconnect cons con =
|
||||||
let domstr = Connection.get_domstr con in
|
let domstr = Connection.get_domstr con in
|
||||||
info "%s requests a reconnect" domstr;
|
info "%s requests a reconnect" domstr;
|
||||||
History.trim ();
|
reset_watches_and_transactions cons con;
|
||||||
Connection.do_reconnect con;
|
Connection.do_reconnect con;
|
||||||
info "%s reconnection complete" domstr
|
info "%s reconnection complete" domstr
|
||||||
|
|
||||||
|
|||||||