diff --git a/system/bta/hf_client/bta_hf_client_sdp.cc b/system/bta/hf_client/bta_hf_client_sdp.cc index cfb88d32ffd29b47548d70f4861b5a15f33d5c8b..6cc5cb724238e5f1b5dee313bc0eb11d3d51044f 100755 --- a/system/bta/hf_client/bta_hf_client_sdp.cc +++ b/system/bta/hf_client/bta_hf_client_sdp.cc @@ -335,6 +335,19 @@ void bta_hf_client_do_disc(tBTA_HF_CLIENT_CB* client_cb) { uuid_list[0] = Uuid::From16Bit(UUID_SERVCLASS_AG_HANDSFREE); } + /* If we already have a non-null discovery database at this point, we can get + * into a race condition leading to UAF once this connection is closed. + * This should only happen with malicious modifications to a client. */ + if (client_cb->p_disc_db != NULL) { + APPL_TRACE_ERROR( + "Tried to set up a HF client with a preexisting discovery database."); + client_cb->p_disc_db = NULL; + // We manually set the state here because it's possible to call this from an + // OPEN state, in which case the discovery fail event will be ignored. + client_cb->state = 0; // BTA_HF_CLIENT_INIT_ST + return; + } + /* allocate buffer for sdp database */ client_cb->p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(BT_DEFAULT_BUFFER_SIZE); diff --git a/system/stack/avct/avct_api.cc b/system/stack/avct/avct_api.cc index b52e1afdf45248e8b73161a2bccc69cc79c2d11d..325426409268fbac189343468803291d1928116c 100644 --- a/system/stack/avct/avct_api.cc +++ b/system/stack/avct/avct_api.cc @@ -63,9 +63,11 @@ void AVCT_Register() { /* initialize AVCTP data structures */ memset(&avct_cb, 0, sizeof(tAVCT_CB)); + uint16_t sec = BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT; + /* register PSM with L2CAP */ L2CA_Register2(AVCT_PSM, avct_l2c_appl, true /* enable_snoop */, nullptr, - kAvrcMtu, 0, BTA_SEC_AUTHENTICATE); + kAvrcMtu, 0, sec); /* Include the browsing channel which uses eFCR */ tL2CAP_ERTM_INFO ertm_info; @@ -73,7 +75,7 @@ void AVCT_Register() { L2CA_Register2(AVCT_BR_PSM, avct_l2c_br_appl, true /*enable_snoop*/, &ertm_info, kAvrcBrMtu, AVCT_MIN_BROWSE_MTU, - BTA_SEC_AUTHENTICATE); + sec); avct_cb.trace_level = avct_trace_level; } diff --git a/system/stack/avct/avct_bcb_act.cc b/system/stack/avct/avct_bcb_act.cc index d59c4e8f49e8f501521f2da4bd08d3c842cfcebf..ba327662e7d361ca1ea115f817dbe85a7e8b9c2a 100644 --- a/system/stack/avct/avct_bcb_act.cc +++ b/system/stack/avct/avct_bcb_act.cc @@ -114,8 +114,9 @@ void avct_bcb_chnl_open(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) { /* call l2cap connect req */ p_bcb->ch_state = AVCT_CH_CONN; - p_bcb->ch_lcid = - L2CA_ConnectReq2(AVCT_BR_PSM, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE); + p_bcb->ch_lcid = L2CA_ConnectReq2(AVCT_BR_PSM, p_lcb->peer_addr, + BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); + if (p_bcb->ch_lcid == 0) { /* if connect req failed, send ourselves close event */ tAVCT_LCB_EVT avct_lcb_evt; diff --git a/system/stack/avct/avct_lcb_act.cc b/system/stack/avct/avct_lcb_act.cc index 2a2f6b2161b2b33d4ca40d8396b1f3e61c305a62..6c5585ffa6abb0b8f4990a9919bc66b41ed75b95 100644 --- a/system/stack/avct/avct_lcb_act.cc +++ b/system/stack/avct/avct_lcb_act.cc @@ -185,7 +185,8 @@ void avct_lcb_chnl_open(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) { p_lcb->ch_state = AVCT_CH_CONN; p_lcb->ch_lcid = - L2CA_ConnectReq2(AVCT_PSM, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE); + L2CA_ConnectReq2(AVCT_PSM, p_lcb->peer_addr, + BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); if (p_lcb->ch_lcid == 0) { /* if connect req failed, send ourselves close event */ tAVCT_LCB_EVT avct_lcb_evt; diff --git a/system/stack/avdt/avdt_ad.cc b/system/stack/avdt/avdt_ad.cc index ccfb12945cb592ad6a5f03fcbb5b4c686936dbd4..9d2d6779ca385fca7e5a990059fdfee937c99f3d 100644 --- a/system/stack/avdt/avdt_ad.cc +++ b/system/stack/avdt/avdt_ad.cc @@ -548,7 +548,8 @@ void avdt_ad_open_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb, /* call l2cap connect req */ lcid = - L2CA_ConnectReq2(AVDT_PSM, p_ccb->peer_addr, BTM_SEC_OUT_AUTHENTICATE); + L2CA_ConnectReq2(AVDT_PSM, p_ccb->peer_addr, + BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT); if (lcid != 0) { /* if connect req ok, store tcid in lcid table */ avdtp_cb.ad.lcid_tbl[lcid] = avdt_ad_tc_tbl_to_idx(p_tbl); diff --git a/system/stack/avdt/avdt_api.cc b/system/stack/avdt/avdt_api.cc index a5f53885e8410ac11db904bde8b5fdd90cb7131f..ea4d2acd007123e4d95ee7b19781e5123664692f 100644 --- a/system/stack/avdt/avdt_api.cc +++ b/system/stack/avdt/avdt_api.cc @@ -95,9 +95,10 @@ void avdt_scb_transport_channel_timer_timeout(void* data) { * ******************************************************************************/ void AVDT_Register(AvdtpRcb* p_reg, tAVDT_CTRL_CBACK* p_cback) { + uint16_t sec = BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT; /* register PSM with L2CAP */ L2CA_Register2(AVDT_PSM, avdt_l2c_appl, true /* enable_snoop */, nullptr, - kAvdtpMtu, 0, BTA_SEC_AUTHENTICATE); + kAvdtpMtu, 0, sec); /* initialize AVDTP data structures */ avdt_scb_init(); diff --git a/system/stack/sdp/sdp_discovery.cc b/system/stack/sdp/sdp_discovery.cc index f025df856b97a4cf8418e9e901489ac72bb9d112..2e8c63ebc73c6f105388321571d55ad4abdbcf72 100644 --- a/system/stack/sdp/sdp_discovery.cc +++ b/system/stack/sdp/sdp_discovery.cc @@ -596,6 +596,15 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, uint8_t* p; uint16_t bytes_left = SDP_DATA_BUF_SIZE; + /* If we don't have a valid discovery database, we can't do anything. */ + if (p_ccb->p_db == NULL) { + SDP_TRACE_WARNING( + "Attempted continuation or first time request with invalid discovery " + "database"); + sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_CONT_STATE); + return; + } + p_msg->offset = L2CAP_MIN_OFFSET; p = p_start = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;