diff options
Diffstat (limited to '0041-tools-xenstored-domain_entry_fix-Handle-conflicting-.patch')
-rw-r--r-- | 0041-tools-xenstored-domain_entry_fix-Handle-conflicting-.patch | 64 |
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 + |