]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: server: fix crash after duplicate GUID insertion
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 22 May 2025 15:48:58 +0000 (17:48 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 22 May 2025 15:59:37 +0000 (17:59 +0200)
On "add server", if a GUID is defined, guid_insert() is used to add the
entry into the global GUID tree. If a similar entry already exists, GUID
insertion fails and the server creation is eventually aborted.

A crash could occur in this case because of an invalid memory access via
guid_remove(). The latter is caused via free_server() as the server
insertion is rejected. The invalid occurs on GUID key.

The issue occurs because of guid_insert(). The function properly
deallocates the GUID key on duplicate insertion, but it failed to reset
<guid.node.key> to NULL. This caused the invalid memory access on
guid_remove(). To fix this, ensure that key member is properly resetted
on guid_insert() error path.

This must be backported up to 3.0.

src/guid.c

index 567669cd7b0b32de616c4791548bdbc54d2757bd..f2bc99cf6da130d43d5a6cc973645ca74ba12021 100644 (file)
@@ -30,7 +30,6 @@ int guid_insert(enum obj_type *objt, const char *uid, char **errmsg)
        struct guid_node *guid = NULL;
        struct guid_node *dup;
        struct ebpt_node *node;
-       char *key = NULL;
        char *dup_name = NULL;
 
        if (!guid_is_valid_fmt(uid, errmsg))
@@ -55,14 +54,12 @@ int guid_insert(enum obj_type *objt, const char *uid, char **errmsg)
                return 0;
        }
 
-       key = strdup(uid);
-       if (!key) {
+       guid->node.key = strdup(uid);
+       if (!guid->node.key) {
                memprintf(errmsg, "key alloc failure");
                goto err;
        }
 
-       guid->node.key = key;
-
        HA_RWLOCK_WRLOCK(GUID_LOCK, &guid_lock);
        node = ebis_insert(&guid_tree, &guid->node);
        if (node != &guid->node) {
@@ -78,7 +75,7 @@ int guid_insert(enum obj_type *objt, const char *uid, char **errmsg)
        return 0;
 
  err:
-       ha_free(&key);
+       ha_free(&guid->node.key);
        ha_free(&dup_name);
        return 1;
 }