summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '0082-tools-ocaml-xenstored-Fix-quota-bypass-on-domain-shu.patch')
-rw-r--r--0082-tools-ocaml-xenstored-Fix-quota-bypass-on-domain-shu.patch93
1 files changed, 93 insertions, 0 deletions
diff --git a/0082-tools-ocaml-xenstored-Fix-quota-bypass-on-domain-shu.patch b/0082-tools-ocaml-xenstored-Fix-quota-bypass-on-domain-shu.patch
new file mode 100644
index 0000000..1cdc2b2
--- /dev/null
+++ b/0082-tools-ocaml-xenstored-Fix-quota-bypass-on-domain-shu.patch
@@ -0,0 +1,93 @@
+From 5b0919f2c0e5060f6e0bc328f100abae0a9f07b8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Edwin=20T=C3=B6r=C3=B6k?= <edvin.torok@citrix.com>
+Date: Wed, 12 Oct 2022 19:13:06 +0100
+Subject: [PATCH 82/87] tools/ocaml/xenstored: Fix quota bypass on domain
+ shutdown
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+XSA-322 fixed a domid reuse vulnerability by assigning Dom0 as the owner of
+any nodes left after a domain is shutdown (e.g. outside its /local/domain/N
+tree).
+
+However Dom0 has no quota on purpose, so this opened up another potential
+attack vector. Avoid it by deleting these nodes instead of assigning them to
+Dom0.
+
+This is part of XSA-419 / CVE-2022-42323.
+
+Fixes: c46eff921209 ("tools/ocaml/xenstored: clean up permissions for dead domains")
+Signed-off-by: Edwin Török <edvin.torok@citrix.com>
+Acked-by: Christian Lindig <christian.lindig@citrix.com>
+(cherry picked from commit db471408edd46af403b8bd44d180a928ad7fbb80)
+---
+ tools/ocaml/xenstored/perms.ml | 3 +--
+ tools/ocaml/xenstored/store.ml | 29 +++++++++++++++++++++--------
+ 2 files changed, 22 insertions(+), 10 deletions(-)
+
+diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
+index e8a16221f8fa..84f2503e8e29 100644
+--- a/tools/ocaml/xenstored/perms.ml
++++ b/tools/ocaml/xenstored/perms.ml
+@@ -64,8 +64,7 @@ let get_owner perm = perm.owner
+ * *)
+ let remove_domid ~domid perm =
+ let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+- let owner = if perm.owner = domid then 0 else perm.owner in
+- { perm with acl; owner }
++ if perm.owner = domid then None else Some { perm with acl; owner = perm.owner }
+
+ let default0 = create 0 NONE []
+
+diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
+index 20e67b142746..70f0c83de404 100644
+--- a/tools/ocaml/xenstored/store.ml
++++ b/tools/ocaml/xenstored/store.ml
+@@ -87,10 +87,21 @@ let check_owner node connection =
+
+ let rec recurse fct node = fct node; SymbolMap.iter (fun _ -> recurse fct) node.children
+
+-(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+-let recurse_map f =
++(** [recurse_filter_map f tree] applies [f] on each node in the tree recursively,
++ possibly removing some nodes.
++ Note that the nodes removed this way won't generate watch events.
++*)
++let recurse_filter_map f =
++ let invalid = -1 in
++ let is_valid _ node = node.perms.owner <> invalid in
+ let rec walk node =
+- f { node with children = SymbolMap.map walk node.children }
++ (* Map.filter_map is Ocaml 4.11+ only *)
++ let node =
++ { node with children =
++ SymbolMap.map walk node.children |> SymbolMap.filter is_valid } in
++ match f node with
++ | Some keep -> keep
++ | None -> { node with perms = {node.perms with owner = invalid } }
+ in
+ walk
+
+@@ -444,11 +455,13 @@ let setperms store perm path nperms =
+
+ let reset_permissions store domid =
+ Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+- store.root <- Node.recurse_map (fun node ->
+- let perms = Perms.Node.remove_domid ~domid node.perms in
+- if perms <> node.perms then
+- Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+- { node with perms }
++ store.root <- Node.recurse_filter_map (fun node ->
++ match Perms.Node.remove_domid ~domid node.perms with
++ | None -> None
++ | Some perms ->
++ if perms <> node.perms then
++ Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
++ Some { node with perms }
+ ) store.root
+
+ type ops = {
+--
+2.37.4
+