From: Julien Grall <jgrall@amazon.com>
The maximum path length supported by Xenstored protocol is
XENSTORE_ABS_PATH_MAX (i.e 3072). This doesn't take into account the
NUL at the end of the path.
However, the code to dump the nodes will allocate a buffer
of XENSTORE_ABS_PATH. As a result it may not be possible to live-update
if there is a node name of XENSTORE_ABS_PATH.
Fix it by allocating a buffer of XENSTORE_ABS_PATH_MAX + 1 characters.
Take the opportunity to pass the max length of the buffer as a
parameter of dump_state_node_tree(). This will be clearer that the
check in the function is linked to the allocation in dump_state_nodes().
Signed-off-by: Julien Grall <jgrall@amazon.com>
---
This was spotted when backporting Live-Update to 4.11 because the
commit 924bf8c793 "tools/xenstore: rework path length check" is
not present. On the latest upstream, this is looks more a latent bug
because I didn't manage to create such large node.
(4.11)
42sh# xenstore-write $(python -c "print('/' + 'A' * 3071)") ""
42sh# xenstore-control live-update /usr/local/sbin/xenstored
Starting live update failed:
Dump node path length error
---
tools/xenstore/xenstored_core.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 16c856730c55..0d4c73d6e20c 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -2574,7 +2574,8 @@ const char *dump_state_node_perms(FILE *fp, const struct xs_permissions *perms,
return NULL;
}
-static const char *dump_state_node_tree(FILE *fp, char *path)
+static const char *dump_state_node_tree(FILE *fp, char *path,
+ unsigned int path_max_len)
{
unsigned int pathlen, childlen, p = 0;
struct xs_state_record_header head;
@@ -2642,10 +2643,10 @@ static const char *dump_state_node_tree(FILE *fp, char *path)
}
while (p < hdr->childlen) {
childlen = strlen(child) + 1;
- if (pathlen + childlen > XENSTORE_ABS_PATH_MAX)
+ if (pathlen + childlen > path_max_len)
return "Dump node path length error";
strcpy(path + pathlen, child);
- ret = dump_state_node_tree(fp, path);
+ ret = dump_state_node_tree(fp, path, path_max_len);
if (ret)
return ret;
p += childlen;
@@ -2661,13 +2662,13 @@ const char *dump_state_nodes(FILE *fp, const void *ctx)
{
char *path;
- path = talloc_size(ctx, XENSTORE_ABS_PATH_MAX);
+ path = talloc_size(ctx, XENSTORE_ABS_PATH_MAX + 1);
if (!path)
return "Path buffer allocation error";
strcpy(path, "/");
- return dump_state_node_tree(fp, path);
+ return dump_state_node_tree(fp, path, XENSTORE_ABS_PATH_MAX + 1);
}
void read_state_global(const void *ctx, const void *state)
--
2.17.1
On 29.07.21 11:34, Julien Grall wrote: > From: Julien Grall <jgrall@amazon.com> > > The maximum path length supported by Xenstored protocol is > XENSTORE_ABS_PATH_MAX (i.e 3072). This doesn't take into account the > NUL at the end of the path. > > However, the code to dump the nodes will allocate a buffer > of XENSTORE_ABS_PATH. As a result it may not be possible to live-update > if there is a node name of XENSTORE_ABS_PATH. > > Fix it by allocating a buffer of XENSTORE_ABS_PATH_MAX + 1 characters. > > Take the opportunity to pass the max length of the buffer as a > parameter of dump_state_node_tree(). This will be clearer that the > check in the function is linked to the allocation in dump_state_nodes(). > > Signed-off-by: Julien Grall <jgrall@amazon.com> Reviewed-by: Juergen Gross <jgross@suse.com> > > --- > > This was spotted when backporting Live-Update to 4.11 because the > commit 924bf8c793 "tools/xenstore: rework path length check" is > not present. On the latest upstream, this is looks more a latent bug > because I didn't manage to create such large node. Yes, the path length is limited to "/local/domain/<id>/" + the max relative path length. Juergen
Julien Grall writes ("[PATCH] tools/xenstored: Fix off-by-one in dump_state_nodes()"): > The maximum path length supported by Xenstored protocol is > XENSTORE_ABS_PATH_MAX (i.e 3072). This doesn't take into account the > NUL at the end of the path. ... Julien Grall writes ("[PATCH] tools/xenstored: Propagate correctly the error message from lu_start()"): > lu_start() will only set errno when it returns NULL. For all the > other cases, the value is unknown. Thanks, and to Juergen for the reviews. Pushed. Ian.
© 2016 - 2024 Red Hat, Inc.