diff options
Diffstat (limited to '0072-tools-xenstore-remove-recursion-from-construct_node.patch')
-rw-r--r-- | 0072-tools-xenstore-remove-recursion-from-construct_node.patch | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/0072-tools-xenstore-remove-recursion-from-construct_node.patch b/0072-tools-xenstore-remove-recursion-from-construct_node.patch new file mode 100644 index 0000000..72aebfd --- /dev/null +++ b/0072-tools-xenstore-remove-recursion-from-construct_node.patch @@ -0,0 +1,125 @@ +From 074b32e47174a30bb751f2e2c07628eb56117eb8 Mon Sep 17 00:00:00 2001 +From: Juergen Gross <jgross@suse.com> +Date: Tue, 13 Sep 2022 07:35:11 +0200 +Subject: [PATCH 72/87] tools/xenstore: remove recursion from construct_node() + +In order to reduce stack usage due to recursion, switch +construct_node() to use a loop instead. + +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 da8ee25d02a5447ba39a9800ee2a710ae1f54222) +--- + tools/xenstore/xenstored_core.c | 86 +++++++++++++++++++++------------ + 1 file changed, 55 insertions(+), 31 deletions(-) + +diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c +index c676ee4e4e4f..3907c35643e9 100644 +--- a/tools/xenstore/xenstored_core.c ++++ b/tools/xenstore/xenstored_core.c +@@ -1377,45 +1377,69 @@ static int add_child(const void *ctx, struct node *parent, const char *name) + static struct node *construct_node(struct connection *conn, const void *ctx, + const char *name) + { +- struct node *parent, *node; +- char *parentname = get_parent(ctx, name); ++ const char **names = NULL; ++ unsigned int levels = 0; ++ struct node *node = NULL; ++ struct node *parent = NULL; ++ const char *parentname = talloc_strdup(ctx, name); + + if (!parentname) + return NULL; + +- /* If parent doesn't exist, create it. */ +- parent = read_node(conn, parentname, parentname); +- if (!parent && errno == ENOENT) +- parent = construct_node(conn, ctx, parentname); +- if (!parent) +- return NULL; ++ /* Walk the path up until an existing node is found. */ ++ while (!parent) { ++ names = talloc_realloc(ctx, names, const char *, levels + 1); ++ if (!names) ++ goto nomem; + +- /* Add child to parent. */ +- if (add_child(ctx, parent, name)) +- goto nomem; ++ /* ++ * names[0] is the name of the node to construct initially, ++ * names[1] is its parent, and so on. ++ */ ++ names[levels] = parentname; ++ parentname = get_parent(ctx, parentname); ++ if (!parentname) ++ return NULL; + +- /* Allocate node */ +- node = talloc(ctx, struct node); +- if (!node) +- goto nomem; +- node->name = talloc_strdup(node, name); +- if (!node->name) +- goto nomem; ++ /* Try to read parent node until we found an existing one. */ ++ parent = read_node(conn, ctx, parentname); ++ if (!parent && (errno != ENOENT || !strcmp(parentname, "/"))) ++ return NULL; + +- /* Inherit permissions, except unprivileged domains own what they create */ +- node->perms.num = parent->perms.num; +- node->perms.p = talloc_memdup(node, parent->perms.p, +- node->perms.num * sizeof(*node->perms.p)); +- if (!node->perms.p) +- goto nomem; +- if (domain_is_unprivileged(conn)) +- node->perms.p[0].id = conn->id; ++ levels++; ++ } ++ ++ /* Walk the path down again constructing the missing nodes. */ ++ for (; levels > 0; levels--) { ++ /* Add child to parent. */ ++ if (add_child(ctx, parent, names[levels - 1])) ++ goto nomem; ++ ++ /* Allocate node */ ++ node = talloc(ctx, struct node); ++ if (!node) ++ goto nomem; ++ node->name = talloc_steal(node, names[levels - 1]); ++ ++ /* Inherit permissions, unpriv domains own what they create. */ ++ node->perms.num = parent->perms.num; ++ node->perms.p = talloc_memdup(node, parent->perms.p, ++ node->perms.num * ++ sizeof(*node->perms.p)); ++ if (!node->perms.p) ++ goto nomem; ++ if (domain_is_unprivileged(conn)) ++ node->perms.p[0].id = conn->id; ++ ++ /* No children, no data */ ++ node->children = node->data = NULL; ++ node->childlen = node->datalen = 0; ++ node->acc.memory = 0; ++ node->parent = parent; ++ ++ parent = node; ++ } + +- /* No children, no data */ +- node->children = node->data = NULL; +- node->childlen = node->datalen = 0; +- node->acc.memory = 0; +- node->parent = parent; + return node; + + nomem: +-- +2.37.4 + |