From 12091a323ef84cad10d91fcf6588a6657e591ee0 Mon Sep 17 00:00:00 2001 From: Nitin Arora Date: Wed, 27 Jan 2016 17:02:02 -0800 Subject: [PATCH] Avoid double memory free and crash during LE discovery or disconnect 1. Prevent GATT operations to proceed if queue is not empty This change returns a FALSE from GATT enqueue operation, in case there is already a GATT command enqueued. This simple change will a. Prevent incorrect memory freeing of the currently queued command. b. Prevent incorrect dequeing of the ongoing command and enqueing another command which will never be executed. c. Double free of memory causing segmentation fault 2. Prevent performing pending operations when link is down This change prevents performing the execution of pending operations when the link is disconnected. The pending operation in that case is bound to fail thus freeing the memory pointed to by the p_q_cmd which is cleaned up again by the discovery completion routine and thus causing double free. Bug:24178843 Change-Id: Ief2756f289a7db73d251ef7e247774dd3f7fc413 --- bta/gatt/bta_gattc_act.c | 6 ++++-- bta/gatt/bta_gattc_utils.c | 18 ++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bta/gatt/bta_gattc_act.c b/bta/gatt/bta_gattc_act.c index a9b9cd19c..d62f8b697 100644 --- a/bta/gatt/bta_gattc_act.c +++ b/bta/gatt/bta_gattc_act.c @@ -1064,8 +1064,10 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) else if (p_q_cmd != NULL) { p_clcb->p_q_cmd = NULL; - - bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd); + /* execute pending operation of link block still present */ + if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) { + bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd); + } /* if the command executed requeued the cmd, we don't * want to free the underlying buffer that's being * referenced by p_clcb->p_q_cmd diff --git a/bta/gatt/bta_gattc_utils.c b/bta/gatt/bta_gattc_utils.c index 539d2a76f..a8c4ac3e9 100644 --- a/bta/gatt/bta_gattc_utils.c +++ b/bta/gatt/bta_gattc_utils.c @@ -440,17 +440,15 @@ tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda) BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { - if (p_clcb->p_q_cmd == NULL) - { - p_clcb->p_q_cmd = p_data; - } - else - { - APPL_TRACE_ERROR("already has a pending command!!"); - /* skip the callback now. ----- need to send callback ? */ - } - return (p_clcb->p_q_cmd != NULL) ? TRUE : FALSE; + if (p_clcb->p_q_cmd == NULL) + { + p_clcb->p_q_cmd = p_data; + return TRUE; + } + APPL_TRACE_ERROR ("%s: already has a pending command!!", __func__); + /* skip the callback now. ----- need to send callback ? */ + return FALSE; } /******************************************************************************* -- 2.11.0