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.
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))
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) {
return 0;
err:
- ha_free(&key);
+ ha_free(&guid->node.key);
ha_free(&dup_name);
return 1;
}