summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '0041-tools-xenstored-domain_entry_fix-Handle-conflicting-.patch')
-rw-r--r--0041-tools-xenstored-domain_entry_fix-Handle-conflicting-.patch64
1 files changed, 64 insertions, 0 deletions
diff --git a/0041-tools-xenstored-domain_entry_fix-Handle-conflicting-.patch b/0041-tools-xenstored-domain_entry_fix-Handle-conflicting-.patch
new file mode 100644
index 0000000..1edecc8
--- /dev/null
+++ b/0041-tools-xenstored-domain_entry_fix-Handle-conflicting-.patch
@@ -0,0 +1,64 @@
+From c4e05c97f57d236040d1da5c1fbf6e3699dc86ea Mon Sep 17 00:00:00 2001
+From: Julien Grall <jgrall@amazon.com>
+Date: Fri, 22 Sep 2023 11:32:16 +0100
+Subject: [PATCH 41/55] tools/xenstored: domain_entry_fix(): Handle conflicting
+ transaction
+
+The function domain_entry_fix() will be initially called to check if the
+quota is correct before attempt to commit any nodes. So it would be
+possible that accounting is temporarily negative. This is the case
+in the following sequence:
+
+ 1) Create 50 nodes
+ 2) Start two transactions
+ 3) Delete all the nodes in each transaction
+ 4) Commit the two transactions
+
+Because the first transaction will have succeed and updated the
+accounting, there is no guarantee that 'd->nbentry + num' will still
+be above 0. So the assert() would be triggered.
+The assert() was introduced in dbef1f748289 ("tools/xenstore: simplify
+and fix per domain node accounting") with the assumption that the
+value can't be negative. As this is not true revert to the original
+check but restricted to the path where we don't update. Take the
+opportunity to explain the rationale behind the check.
+
+This CVE-2023-34323 / XSA-440.
+
+Fixes: dbef1f748289 ("tools/xenstore: simplify and fix per domain node accounting")
+Signed-off-by: Julien Grall <jgrall@amazon.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+---
+ tools/xenstore/xenstored_domain.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
+index aa86892fed..6074df210c 100644
+--- a/tools/xenstore/xenstored_domain.c
++++ b/tools/xenstore/xenstored_domain.c
+@@ -1094,10 +1094,20 @@ int domain_entry_fix(unsigned int domid, int num, bool update)
+ }
+
+ cnt = d->nbentry + num;
+- assert(cnt >= 0);
+
+- if (update)
++ if (update) {
++ assert(cnt >= 0);
+ d->nbentry = cnt;
++ } else if (cnt < 0) {
++ /*
++ * In a transaction when a node is being added/removed AND
++ * the same node has been added/removed outside the
++ * transaction in parallel, the result value may be negative.
++ * This is no problem, as the transaction will fail due to
++ * the resulting conflict. So override 'cnt'.
++ */
++ cnt = 0;
++ }
+
+ return domid_is_unprivileged(domid) ? cnt : 0;
+ }
+--
+2.42.0
+