summaryrefslogtreecommitdiff
path: root/mesh/node.c
diff options
context:
space:
mode:
authorBrian Gix <brian.gix@intel.com>2020-05-20 15:14:38 -0700
committerBrian Gix <brian.gix@intel.com>2020-05-20 15:16:55 -0700
commit0e8ed1f261cf336ce1ec8b3b514e4794ac8f058c (patch)
treecc168ed8a283d7d66b83a5dd828514e8a25e1dea /mesh/node.c
parent5b6536954b53afe1eebb4d54578cb45953456023 (diff)
downloadbluez-0e8ed1f261cf336ce1ec8b3b514e4794ac8f058c.tar.gz
mesh: Fix double-free
This fixes a double-free error when destroying the NVM storage of a mesh node. Cleanly handle two distinct scenarios: 1. When the node is being deleted at runtime. This causes release of both dynamic memory and NVM storage. 2. During shutdown, we release dynamic memory only.
Diffstat (limited to 'mesh/node.c')
-rw-r--r--mesh/node.c20
1 files changed, 7 insertions, 13 deletions
diff --git a/mesh/node.c b/mesh/node.c
index 2b4b3a563..d5e07ce7f 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -323,18 +323,16 @@ static void free_node_resources(void *data)
struct mesh_node *node = data;
/* Unregister io callbacks */
- if (node->net)
- mesh_net_detach(node->net);
+ mesh_net_detach(node->net);
- l_queue_destroy(node->elements, element_free);
- node->elements = NULL;
/* In case of a provisioner, stop active scanning */
if (node->provisioner)
manager_scan_cancel(node);
+ /* Free dynamic resources */
free_node_dbus_resources(node);
-
+ l_queue_destroy(node->elements, element_free);
mesh_config_release(node->cfg);
mesh_net_free(node->net);
l_free(node->storage_dir);
@@ -352,8 +350,7 @@ void node_remove(struct mesh_node *node)
l_queue_remove(nodes, node);
- if (node->cfg)
- mesh_config_destroy(node->cfg);
+ mesh_config_destroy_nvm(node->cfg);
free_node_resources(node);
}
@@ -576,13 +573,10 @@ fail:
static void cleanup_node(void *data)
{
struct mesh_node *node = data;
- struct mesh_net *net = node->net;
+ uint32_t seq_num = mesh_net_get_seq_num(node->net);
- /* Preserve the last sequence number */
- if (node->cfg)
- mesh_config_write_seq_number(node->cfg,
- mesh_net_get_seq_num(net),
- false);
+ /* Preserve the last used sequence number */
+ mesh_config_write_seq_number(node->cfg, seq_num, false);
free_node_resources(node);
}