[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen stable-4.16] tools/xenstore: simplify check_store()



commit c5a76df793c638423e1388528dc679a3e020a477
Author:     Juergen Gross <jgross@xxxxxxxx>
AuthorDate: Tue Sep 13 07:35:12 2022 +0200
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Tue Nov 1 14:07:24 2022 +0000

    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@xxxxxxxx>
    Reviewed-by: Julien Grall <jgrall@xxxxxxxxxx>
    (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 2cda3ee375..760f3c16c7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -2477,50 +2477,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);
@@ -2530,19 +2514,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");
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.16



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.