From a4f0b098bc77ebcbce07365f063bf529b9c1ac5d Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Tue, 24 Mar 2026 23:18:11 +0530 Subject: [PATCH] fix(data_model): unlink cluster from endpoint on cluster::destroy cluster::destroy() freed the cluster memory and its children (attributes, commands, events) but never removed the cluster from the parent endpoint's linked list, leaving a dangling pointer. This caused use-after-free crashes when creating a new cluster on the same endpoint after destroying one. Fix: look up the parent endpoint via the endpoint_id stored in the cluster struct and unlink before freeing, consistent with how attribute::destroy, command::destroy and event::destroy handle their parent lists. --- components/esp_matter/esp_matter_core.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/components/esp_matter/esp_matter_core.cpp b/components/esp_matter/esp_matter_core.cpp index 13ceeb6e6..b411d0e25 100644 --- a/components/esp_matter/esp_matter_core.cpp +++ b/components/esp_matter/esp_matter_core.cpp @@ -1592,8 +1592,13 @@ static esp_err_t destroy(cluster_t *cluster) current_cluster->matter_attributes = NULL; } - /* Free */ - esp_matter_mem_free(current_cluster); + /* Remove from parent endpoint's cluster list and free */ + _endpoint_t *parent_endpoint = (_endpoint_t *)endpoint::get(current_cluster->endpoint_id); + if (parent_endpoint) { + SinglyLinkedList<_cluster_t>::remove(&parent_endpoint->cluster_list, current_cluster); + } else { + esp_matter_mem_free(current_cluster); + } return ESP_OK; }