From 61819f23f97ccc294add1608c3e43e28e31094df Mon Sep 17 00:00:00 2001 From: Trond Einar Snekvik Date: Thu, 10 Sep 2020 15:36:15 +0200 Subject: [PATCH] Bluetooth: Mesh: Virtual address memory leak Fixes a memory leak when a virtual address subscription is added for a model that either has this VA already, or the model has no more space for subscription addresses. Signed-off-by: Trond Einar Snekvik --- subsys/bluetooth/mesh/cfg_srv.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index 073c1075cc4..a3584a6fabf 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -43,6 +43,10 @@ static struct bt_mesh_cfg_srv *conf; static struct label labels[CONFIG_BT_MESH_LABEL_COUNT]; +#if CONFIG_BT_MESH_LABEL_COUNT > 0 +static uint8_t va_del(uint8_t *label_uuid, uint16_t *addr); +#endif + static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, bool primary) { @@ -234,6 +238,16 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, return STATUS_INVALID_APPKEY; } +#if CONFIG_BT_MESH_LABEL_COUNT > 0 + if (BT_MESH_ADDR_IS_VIRTUAL(model->pub->addr)) { + uint8_t *uuid = bt_mesh_label_uuid_get(model->pub->addr); + + if (uuid) { + va_del(uuid, NULL); + } + } +#endif + model->pub->addr = pub_addr; model->pub->key = app_idx; model->pub->cred = cred_flag; @@ -1230,9 +1244,14 @@ static void mod_pub_va_set(struct bt_mesh_model *model, } status = va_add(label_uuid, &pub_addr); - if (status == STATUS_SUCCESS) { - status = _mod_pub_set(mod, pub_addr, pub_app_idx, cred_flag, - pub_ttl, pub_period, retransmit, true); + if (status != STATUS_SUCCESS) { + goto send_status; + } + + status = _mod_pub_set(mod, pub_addr, pub_app_idx, cred_flag, pub_ttl, + pub_period, retransmit, true); + if (status != STATUS_SUCCESS) { + va_del(label_uuid, NULL); } send_status: @@ -1800,6 +1819,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, if (bt_mesh_model_find_group(&mod, sub_addr)) { /* Tried to add existing subscription */ status = STATUS_SUCCESS; + va_del(label_uuid, NULL); goto send_status; } @@ -1807,6 +1827,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, entry = bt_mesh_model_find_group(&mod, BT_MESH_ADDR_UNASSIGNED); if (!entry) { status = STATUS_INSUFF_RESOURCES; + va_del(label_uuid, NULL); goto send_status; } @@ -1935,11 +1956,11 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, if (ARRAY_SIZE(mod->groups) > 0) { - bt_mesh_model_tree_walk(bt_mesh_model_root(mod), - mod_sub_clear_visitor, NULL); status = va_add(label_uuid, &sub_addr); if (status == STATUS_SUCCESS) { + bt_mesh_model_tree_walk(bt_mesh_model_root(mod), + mod_sub_clear_visitor, NULL); mod->groups[0] = sub_addr; if (IS_ENABLED(CONFIG_BT_SETTINGS)) {