diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index acafb029ce91674bf13d8ce46e7651b532914aef..9eeecc370d1e240387fa44bfbb662063962cf87e 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -3082,11 +3082,14 @@ static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr) { } } } else { - BTM_SecDeleteDevice(remote_bd_addr); + // remote_bd_addr comes from security record, which is removed in + // BTM_SecDeleteDevice. + RawAddress addr_copy = remote_bd_addr; + BTM_SecDeleteDevice(addr_copy); /* need to remove all pending background connection */ - BTA_GATTC_CancelOpen(0, remote_bd_addr, false); + BTA_GATTC_CancelOpen(0, addr_copy, false); /* remove all cached GATT information */ - BTA_GATTC_Refresh(remote_bd_addr); + BTA_GATTC_Refresh(addr_copy); } } diff --git a/system/bta/hd/bta_hd_act.cc b/system/bta/hd/bta_hd_act.cc index 8819983e0abb7bad6abcdf1b5ab3b48192651db7..0d677ee2489703306f87f915325d9b6bfd1c4687 100644 --- a/system/bta/hd/bta_hd_act.cc +++ b/system/bta/hd/bta_hd_act.cc @@ -36,6 +36,7 @@ #include "bta_sys.h" #include "btm_api.h" +#include "log/log.h" #include "osi/include/osi.h" static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event, @@ -510,6 +511,10 @@ extern void bta_hd_intr_data_act(tBTA_HD_DATA* p_data) { APPL_TRACE_API("%s", __func__); if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) { + if (len < 1) { + android_errorWriteLog(0x534e4554, "109757986"); + return; + } ret.report_id = *p_buf; len--; @@ -544,15 +549,31 @@ extern void bta_hd_get_report_act(tBTA_HD_DATA* p_data) { APPL_TRACE_API("%s", __func__); + uint16_t remaining_len = p_msg->len; + if (remaining_len < 1) { + android_errorWriteLog(0x534e4554, "109757168"); + return; + } + ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK; p_buf++; + remaining_len--; if (bta_hd_cb.use_report_id) { + if (remaining_len < 1) { + android_errorWriteLog(0x534e4554, "109757168"); + return; + } ret.report_id = *p_buf; p_buf++; + remaining_len--; } if (rep_size_follows) { + if (remaining_len < 2) { + android_errorWriteLog(0x534e4554, "109757168"); + return; + } ret.buffer_size = *p_buf | (*(p_buf + 1) << 8); } @@ -579,11 +600,19 @@ extern void bta_hd_set_report_act(tBTA_HD_DATA* p_data) { APPL_TRACE_API("%s", __func__); + if (len < 1) { + android_errorWriteLog(0x534e4554, "110846194"); + return; + } ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK; p_buf++; len--; if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) { + if (len < 1) { + android_errorWriteLog(0x534e4554, "109757435"); + return; + } ret.report_id = *p_buf; len--; diff --git a/system/btif/src/btif_hf.cc b/system/btif/src/btif_hf.cc index f5c971bddeb515d4943713d115635625382104e6..6fd803ba44491b60a5a379caa9f7b943079c50eb 100644 --- a/system/btif/src/btif_hf.cc +++ b/system/btif/src/btif_hf.cc @@ -1020,12 +1020,20 @@ bt_status_t HeadsetInterface::ClccResponse( dialnum[newidx++] = '+'; } for (size_t i = 0; number[i] != 0; i++) { + if (newidx >= (sizeof(dialnum) - res_strlen - 1)) { + android_errorWriteLog(0x534e4554, "79266386"); + break; + } if (utl_isdialchar(number[i])) { dialnum[newidx++] = number[i]; } } dialnum[newidx] = 0; - snprintf(&ag_res.str[res_strlen], rem_bytes, ",\"%s\",%d", dialnum, type); + // Reserve 5 bytes for ["][,][3_digit_type] + snprintf(&ag_res.str[res_strlen], rem_bytes - 5, ",\"%s", dialnum); + std::stringstream remaining_string; + remaining_string << "\"," << type; + strncat(&ag_res.str[res_strlen], remaining_string.str().c_str(), 5); } } BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_CLCC_RES, ag_res); @@ -1172,6 +1180,13 @@ bt_status_t HeadsetInterface::PhoneStateChange( else xx = snprintf(ag_res.str, sizeof(ag_res.str), "\"%s\"", number); ag_res.num = type; + // 5 = [,][3_digit_type][null_terminator] + if (xx > static_cast<int>(sizeof(ag_res.str) - 5)) { + android_errorWriteLog(0x534e4554, "79431031"); + xx = sizeof(ag_res.str) - 5; + // Null terminating the string + memset(&ag_res.str[xx], 0, 5); + } if (res == BTA_AG_CALL_WAIT_RES) snprintf(&ag_res.str[xx], sizeof(ag_res.str) - xx, ",%d", type); diff --git a/system/stack/btm/btm_dev.cc b/system/stack/btm/btm_dev.cc index e999fed32f99f75f6a7c435ee0d3bf5ecba09aea..bf1582734d767154282eb17adda135db8ce7383b 100644 --- a/system/stack/btm/btm_dev.cc +++ b/system/stack/btm/btm_dev.cc @@ -149,17 +149,16 @@ bool BTM_SecAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class, return true; } -/******************************************************************************* - * - * Function BTM_SecDeleteDevice - * - * Description Free resources associated with the device. +/** Free resources associated with the device associated with |bd_addr| address. * - * Parameters: bd_addr - BD address of the peer - * - * Returns true if removed OK, false if not found or ACL link is active + * *** WARNING *** + * tBTM_SEC_DEV_REC associated with bd_addr becomes invalid after this function + * is called, also any of it's fields. i.e. if you use p_dev_rec->bd_addr, it is + * no longer valid! + * *** WARNING *** * - ******************************************************************************/ + * Returns true if removed OK, false if not found or ACL link is active. + */ bool BTM_SecDeleteDevice(const RawAddress& bd_addr) { if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) || BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR)) { @@ -170,9 +169,10 @@ bool BTM_SecDeleteDevice(const RawAddress& bd_addr) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec != NULL) { + RawAddress bda = p_dev_rec->bd_addr; btm_sec_free_dev(p_dev_rec); /* Tell controller to get rid of the link key, if it has one stored */ - BTM_DeleteStoredLinkKey(&p_dev_rec->bd_addr, NULL); + BTM_DeleteStoredLinkKey(&bda, NULL); } return true; diff --git a/system/stack/hid/hidh_conn.cc b/system/stack/hid/hidh_conn.cc index df0083a462c12dd391355085201a91e8b62994d3..6b729e5f12411f223b6ff5ec3be2b191aab037d8 100644 --- a/system/stack/hid/hidh_conn.cc +++ b/system/stack/hid/hidh_conn.cc @@ -42,6 +42,7 @@ #include "hidh_api.h" #include "hidh_int.h" +#include "log/log.h" #include "osi/include/osi.h" static uint8_t find_conn_by_cid(uint16_t cid); @@ -799,6 +800,14 @@ static void hidh_l2cif_data_ind(uint16_t l2cap_cid, BT_HDR* p_msg) { return; } + if (p_msg->len < 1) { + HIDH_TRACE_WARNING("Rcvd L2CAP data, invalid length %d, should be >= 1", + p_msg->len); + osi_free(p_msg); + android_errorWriteLog(0x534e4554, "80493272"); + return; + } + ttype = HID_GET_TRANS_FROM_HDR(*p_data); param = HID_GET_PARAM_FROM_HDR(*p_data); rep_type = param & HID_PAR_REP_TYPE_MASK; diff --git a/system/stack/include/btm_api.h b/system/stack/include/btm_api.h index 457ae3da57b31ce81388978ef07db6b4499ced03..df4cbe0163f0e01bcf637029b0397638135530fa 100644 --- a/system/stack/include/btm_api.h +++ b/system/stack/include/btm_api.h @@ -1411,15 +1411,16 @@ extern bool BTM_SecAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class, uint8_t key_type, tBTM_IO_CAP io_cap, uint8_t pin_length); -/******************************************************************************* - * - * Function BTM_SecDeleteDevice +/** Free resources associated with the device associated with |bd_addr| address. * - * Description Free resources associated with the device. + * *** WARNING *** + * tBTM_SEC_DEV_REC associated with bd_addr becomes invalid after this function + * is called, also any of it's fields. i.e. if you use p_dev_rec->bd_addr, it is + * no longer valid! + * *** WARNING *** * - * Returns true if rmoved OK, false if not found - * - ******************************************************************************/ + * Returns true if removed OK, false if not found or ACL link is active. + */ extern bool BTM_SecDeleteDevice(const RawAddress& bd_addr); /******************************************************************************* diff --git a/system/stack/include/rfcdefs.h b/system/stack/include/rfcdefs.h index aba555d852e52b0e4ac35230fca93af1c23a7079..ca9b3ce5207ff9e677197bd1a64ec61ad4153581 100644 --- a/system/stack/include/rfcdefs.h +++ b/system/stack/include/rfcdefs.h @@ -89,13 +89,6 @@ (pf) = (*(p_data)++ & RFCOMM_PF_MASK) >> RFCOMM_PF_OFFSET; \ } -#define RFCOMM_PARSE_LEN_FIELD(ea, length, p_data) \ - { \ - (ea) = (*(p_data)&RFCOMM_EA); \ - (length) = (*(p_data)++ >> RFCOMM_SHIFT_LENGTH1); \ - if (!(ea)) (length) += (*(p_data)++ << RFCOMM_SHIFT_LENGTH2); \ - } - #define RFCOMM_FRAME_IS_CMD(initiator, cr) \ (((initiator) && !(cr)) || (!(initiator) && (cr))) diff --git a/system/stack/l2cap/l2c_ble.cc b/system/stack/l2cap/l2c_ble.cc index 09ab317a092d57e7e694705904fe65d7a47b3e0b..1492991072504cf8b282fccd5f99fa0c6660c669 100644 --- a/system/stack/l2cap/l2c_ble.cc +++ b/system/stack/l2cap/l2c_ble.cc @@ -602,6 +602,12 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { uint16_t credit; p_pkt_end = p + pkt_len; + if (p + 4 > p_pkt_end) { + android_errorWriteLog(0x534e4554, "80261585"); + LOG(ERROR) << "invalid read"; + return; + } + STREAM_TO_UINT8(cmd_code, p); STREAM_TO_UINT8(id, p); STREAM_TO_UINT16(cmd_len, p); @@ -627,6 +633,12 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { break; case L2CAP_CMD_BLE_UPDATE_REQ: + if (p + 8 > p_pkt_end) { + android_errorWriteLog(0x534e4554, "80261585"); + LOG(ERROR) << "invalid read"; + return; + } + STREAM_TO_UINT16(min_interval, p); /* 0x0006 - 0x0C80 */ STREAM_TO_UINT16(max_interval, p); /* 0x0006 - 0x0C80 */ STREAM_TO_UINT16(latency, p); /* 0x0000 - 0x03E8 */ @@ -668,6 +680,12 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { break; case L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ: + if (p + 10 > p_pkt_end) { + android_errorWriteLog(0x534e4554, "80261585"); + LOG(ERROR) << "invalid read"; + return; + } + STREAM_TO_UINT16(con_info.psm, p); STREAM_TO_UINT16(rcid, p); STREAM_TO_UINT16(mtu, p); @@ -751,6 +769,12 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { } if (p_ccb) { L2CAP_TRACE_DEBUG("I remember the connection req"); + if (p + 10 > p_pkt_end) { + android_errorWriteLog(0x534e4554, "80261585"); + LOG(ERROR) << "invalid read"; + return; + } + STREAM_TO_UINT16(p_ccb->remote_cid, p); STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mtu, p); STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mps, p); @@ -796,6 +820,12 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { break; case L2CAP_CMD_BLE_FLOW_CTRL_CREDIT: + if (p + 4 > p_pkt_end) { + android_errorWriteLog(0x534e4554, "80261585"); + LOG(ERROR) << "invalid read"; + return; + } + STREAM_TO_UINT16(lcid, p); p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, lcid); if (p_ccb == NULL) { @@ -829,6 +859,11 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { break; case L2CAP_CMD_DISC_RSP: + if (p + 4 > p_pkt_end) { + android_errorWriteLog(0x534e4554, "80261585"); + LOG(ERROR) << "invalid read"; + return; + } STREAM_TO_UINT16(rcid, p); STREAM_TO_UINT16(lcid, p); diff --git a/system/stack/l2cap/l2c_main.cc b/system/stack/l2cap/l2c_main.cc index 2574f88c5ec1e2c7731f57caca3d6627d8420db2..eae77a643fa5b3cac1bb53b05c7884479a38bb26 100644 --- a/system/stack/l2cap/l2c_main.cc +++ b/system/stack/l2cap/l2c_main.cc @@ -173,9 +173,6 @@ void l2c_rcv_acl_data(BT_HDR* p_msg) { if (rcv_cid == L2CAP_CONNECTIONLESS_CID) { /* process_connectionless_data (p_lcb); */ - uint16_t psm; - STREAM_TO_UINT16(psm, p); - L2CAP_TRACE_DEBUG("GOT CONNECTIONLESS DATA PSM:%d", psm); osi_free(p_msg); return; } @@ -511,6 +508,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { default: /* sanity check option length */ if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= cmd_len) { + if (p + cfg_len > p_next_cmd) return; p += cfg_len; if ((cfg_code & 0x80) == 0) { cfg_rej_len += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; diff --git a/system/stack/rfcomm/rfc_ts_frames.cc b/system/stack/rfcomm/rfc_ts_frames.cc index 51fbcac95a4cd0e14a5a671a5ea905e26ca354f4..7f8656b2d21ada6f76bc584bad907080d20ca6ad 100644 --- a/system/stack/rfcomm/rfc_ts_frames.cc +++ b/system/stack/rfcomm/rfc_ts_frames.cc @@ -26,6 +26,7 @@ #include "bt_common.h" #include "bt_target.h" #include "l2c_api.h" +#include "log/log.h" #include "port_api.h" #include "port_int.h" #include "rfc_int.h" @@ -521,7 +522,16 @@ uint8_t rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) { return (RFC_EVENT_BAD_FRAME); } RFCOMM_PARSE_TYPE_FIELD(p_frame->type, p_frame->pf, p_data); - RFCOMM_PARSE_LEN_FIELD(eal, len, p_data); + + eal = *(p_data)&RFCOMM_EA; + len = *(p_data)++ >> RFCOMM_SHIFT_LENGTH1; + if (eal == 0 && p_buf->len > RFCOMM_CTRL_FRAME_LEN) { + len += (*(p_data)++ << RFCOMM_SHIFT_LENGTH2); + } else if (eal == 0) { + RFCOMM_TRACE_ERROR("Bad Length when EAL = 0: %d", p_buf->len); + android_errorWriteLog(0x534e4554, "78288018"); + return RFC_EVENT_BAD_FRAME; + } p_buf->len -= (3 + !ead + !eal + 1); /* Additional 1 for FCS */ p_buf->offset += (3 + !ead + !eal); diff --git a/system/stack/sdp/sdp_server.cc b/system/stack/sdp/sdp_server.cc index 91b5ae2e576cd816d8702b258e611c1aee095228..386f62fa5eb6446a35afaa91a0f2d4f25a35ada3 100644 --- a/system/stack/sdp/sdp_server.cc +++ b/system/stack/sdp/sdp_server.cc @@ -421,6 +421,13 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, attr_len = sdpu_get_attrib_entry_len(p_attr); /* if there is a partial attribute pending to be sent */ if (p_ccb->cont_info.attr_offset) { + if (attr_len < p_ccb->cont_info.attr_offset) { + android_errorWriteLog(0x534e4554, "79217770"); + LOG(ERROR) << "offset is bigger than attribute length"; + sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE, + SDP_TEXT_BAD_CONT_LEN); + return; + } p_rsp = sdpu_build_partial_attrib_entry(p_rsp, p_attr, rem_len, &p_ccb->cont_info.attr_offset); @@ -661,6 +668,13 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, attr_len = sdpu_get_attrib_entry_len(p_attr); /* if there is a partial attribute pending to be sent */ if (p_ccb->cont_info.attr_offset) { + if (attr_len < p_ccb->cont_info.attr_offset) { + android_errorWriteLog(0x534e4554, "79217770"); + LOG(ERROR) << "offset is bigger than attribute length"; + sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE, + SDP_TEXT_BAD_CONT_LEN); + return; + } p_rsp = sdpu_build_partial_attrib_entry( p_rsp, p_attr, rem_len, &p_ccb->cont_info.attr_offset);