From 8d48a56249d5ebbff9149fd6a4ede442f33d96df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CYangZhao=E2=80=9D?= Date: Wed, 29 Dec 2021 19:54:21 +0800 Subject: [PATCH] There is an issue that if the the btm_cb.p_sec_dev_rec_list is full,but at the same time we can't find old device to be replaced,then this can cause crash. So we need to change the way to malloc the new device or replace the old in the list. --- .../bt/host/bluedroid/stack/btm/btm_dev.c | 63 ++++++++++++++----- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/components/bt/host/bluedroid/stack/btm/btm_dev.c b/components/bt/host/bluedroid/stack/btm/btm_dev.c index cc8e2d9a05..d83da09907 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_dev.c +++ b/components/bt/host/bluedroid/stack/btm/btm_dev.c @@ -314,25 +314,60 @@ BOOLEAN btm_find_sec_dev_in_list (void *p_node_data, void *context) tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr) { tBTM_SEC_DEV_REC *p_dev_rec = NULL; + tBTM_SEC_DEV_REC *p_dev_new_rec = NULL; + tBTM_SEC_DEV_REC *p_dev_old_rec = NULL; tBTM_INQ_INFO *p_inq_info; + list_node_t *p_node = NULL; + BOOLEAN new_entry_found = FALSE; + BOOLEAN old_entry_found = FALSE; + BOOLEAN malloc_new_entry = FALSE; BTM_TRACE_EVENT ("btm_sec_alloc_dev\n"); - - /* Old devices which are not in use are deleted already */ - /* Allocate new device or reuse the oldest device */ - if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS) { - //Max number of devices is not exceeded, allocate new device - p_dev_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); - if (p_dev_rec) { - list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec); - } else { - return NULL; + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_old_rec = list_node(p_node); + /* look for old entry which match the bd_addr and the BTM_SEC_IN_USE is cleared */ + if (!(p_dev_old_rec->sec_flags & BTM_SEC_IN_USE) && + (!memcmp (p_dev_old_rec->bd_addr, bd_addr, BD_ADDR_LEN))) { + old_entry_found = TRUE; + BTM_TRACE_EVENT ("btm_sec_alloc_dev old device found\n"); + break; } } - else { - //Find and reuse the oldest device - p_dev_rec = btm_find_oldest_dev(); + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_new_rec = list_node(p_node); + /* find the first entry whose BTM_SEC_IN_USE is cleared */ + if (!(p_dev_new_rec->sec_flags & BTM_SEC_IN_USE)) { + new_entry_found = TRUE; + break; + } + } + if (!new_entry_found) { + /* We can not find new device. We need malloc a new one if p_sec_dev_rec_list is not full */ + if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS){ + p_dev_new_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); + if (p_dev_new_rec) { + new_entry_found = TRUE; + malloc_new_entry = TRUE; + } else { + return NULL; + } + } + } + if (!new_entry_found) { + p_dev_rec = btm_find_oldest_dev(); + } else { + /* if the old device entry not present go with new entry */ + if (old_entry_found) { + p_dev_rec = p_dev_old_rec; + if (malloc_new_entry) { + osi_free(p_dev_new_rec); + } + } else { + if (malloc_new_entry) { + list_append(btm_cb.p_sec_dev_rec_list, p_dev_new_rec); + } + p_dev_rec = p_dev_new_rec; + } } - memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); p_dev_rec->bond_type = BOND_TYPE_UNKNOWN; /* Default value */