summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '0114-tools-xenstore-simplify-check_store.patch')
-rw-r--r--0114-tools-xenstore-simplify-check_store.patch114
1 files changed, 114 insertions, 0 deletions
diff --git a/0114-tools-xenstore-simplify-check_store.patch b/0114-tools-xenstore-simplify-check_store.patch
new file mode 100644
index 0000000..6247114
--- /dev/null
+++ b/0114-tools-xenstore-simplify-check_store.patch
@@ -0,0 +1,114 @@
+From 4096512a70fd0bb65e40ed4269a1ca74dbb16220 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Tue, 13 Sep 2022 07:35:12 +0200
+Subject: [PATCH 114/126] tools/xenstore: simplify check_store()
+
+check_store() is using a hash table for storing all node names it has
+found via walking the tree. Additionally it using another hash table
+for all children of a node to detect duplicate child names.
+
+Simplify that by dropping the second hash table as the first one is
+already holding all the needed information.
+
+This is part of XSA-418 / CVE-2022-42321.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Julien Grall <jgrall@amazon.com>
+(cherry picked from commit 70f719f52a220bc5bc987e4dd28e14a7039a176b)
+---
+ tools/xenstore/xenstored_core.c | 47 +++++++++++----------------------
+ 1 file changed, 15 insertions(+), 32 deletions(-)
+
+diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
+index 7463d0a002d7..a48255c64cad 100644
+--- a/tools/xenstore/xenstored_core.c
++++ b/tools/xenstore/xenstored_core.c
+@@ -2378,50 +2378,34 @@ static int check_store_(const char *name, struct hashtable *reachable)
+ if (node) {
+ size_t i = 0;
+
+- struct hashtable * children =
+- create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+- if (!children) {
+- log("check_store create table: ENOMEM");
+- return ENOMEM;
+- }
+-
+ if (!remember_string(reachable, name)) {
+- hashtable_destroy(children, 0);
+ log("check_store: ENOMEM");
+ return ENOMEM;
+ }
+
+ while (i < node->childlen && !ret) {
+- struct node *childnode;
++ struct node *childnode = NULL;
+ size_t childlen = strlen(node->children + i);
+- char * childname = child_name(NULL, node->name,
+- node->children + i);
++ char *childname = child_name(NULL, node->name,
++ node->children + i);
+
+ if (!childname) {
+ log("check_store: ENOMEM");
+ ret = ENOMEM;
+ break;
+ }
++
++ if (hashtable_search(reachable, childname)) {
++ log("check_store: '%s' is duplicated!",
++ childname);
++ i = rm_child_entry(node, i, childlen);
++ goto next;
++ }
++
+ childnode = read_node(NULL, childname, childname);
+-
++
+ if (childnode) {
+- if (hashtable_search(children, childname)) {
+- log("check_store: '%s' is duplicated!",
+- childname);
+- i = rm_child_entry(node, i, childlen);
+- }
+- else {
+- if (!remember_string(children,
+- childname)) {
+- log("check_store: ENOMEM");
+- talloc_free(childnode);
+- talloc_free(childname);
+- ret = ENOMEM;
+- break;
+- }
+- ret = check_store_(childname,
+- reachable);
+- }
++ ret = check_store_(childname, reachable);
+ } else if (errno != ENOMEM) {
+ log("check_store: No child '%s' found!\n",
+ childname);
+@@ -2431,19 +2415,18 @@ static int check_store_(const char *name, struct hashtable *reachable)
+ ret = ENOMEM;
+ }
+
++ next:
+ talloc_free(childnode);
+ talloc_free(childname);
+ i += childlen + 1;
+ }
+
+- hashtable_destroy(children, 0 /* Don't free values (they are
+- all (void *)1) */);
+ talloc_free(node);
+ } else if (errno != ENOMEM) {
+ /* Impossible, because no database should ever be without the
+ root, and otherwise, we've just checked in our caller
+ (which made a recursive call to get here). */
+-
++
+ log("check_store: No child '%s' found: impossible!", name);
+ } else {
+ log("check_store: ENOMEM");
+--
+2.37.4
+