Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
baf48ff
osi: Prevent memory allocations with MSB set
Sep 30, 2021
0f30ea0
security: Use-After-Free in btm_sec_[dis]connected
Nov 9, 2021
6a94760
Reset the IRK after all devices are unpaired
goptedoblivion Oct 29, 2021
4e54538
Security fix OOB read due to invalid count in stack/avrc/avrc_pars_ct
Jan 13, 2022
92cd3cf
Security: Fix out of bound write in HFP client
Apr 15, 2022
2083fe4
Check Avrcp packet vendor length before extracting length
wescande May 2, 2022
55ed17a
Security: Fix out of bound read in AT_SKIP_REST
zxzxwu Apr 29, 2022
035f9b2
Removing bonded device when auth fails due to missing keys
May 25, 2022
954528b
Fix potential interger overflow when parsing vendor response
Apr 1, 2022
65929c1
Add negative length check in process_service_search_rsp
Aug 12, 2022
ddae17f
Add buffer in pin_reply in bluetooth.cc
Aug 13, 2022
87ab541
Add length check when copy AVDTP packet
Aug 4, 2022
ea9fecc
RESTRICT AUTOMERGE Added max buffer length check
Aug 25, 2022
490836a
Add missing increment in bnep_api.cc
Aug 25, 2022
f622b7b
Add length check when copy AVDT and AVCT packet
ek9852 Aug 16, 2022
b26bb42
Fix integer overflow when parsing avrc response
ek9852 Aug 14, 2022
9b9591b
Report failure when not able to connect to AVRCP
Dec 2, 2022
3116e67
Add bounds check in avdt_scb_act.cc
Sep 27, 2022
de967e4
Fix an OOB Write bug in gatt_check_write_long_terminate
benquike Dec 28, 2022
428c325
Fix an OOB access bug in A2DP_BuildMediaPayloadHeaderSbc
benquike Jan 2, 2023
9c30165
Fix an OOB write in SDP_AddAttribute
benquike Jan 4, 2023
ddaec30
Fix OOB access in avdt_scb_hdl_pkt_no_frag
benquike Dec 8, 2022
928fccb
Fix an OOB bug in register_notification_rsp
benquike Jan 20, 2023
030c8ac
Prevent use-after-free of HID reports
Oct 11, 2022
ef364c6
Revert "Revert "[RESTRICT AUTOMERGE] Validate buffer length in sdpu_b…
Mar 21, 2023
88d9cd7
Revert "Revert "Fix wrong BR/EDR link key downgrades (P_256->P_192)""
Mar 21, 2023
e463af8
Fix gatt_end_operation buffer overflow
tyiu-google Mar 28, 2023
6232451
Fix an integer overflow bug in avdt_msg_asmbl
benquike May 16, 2023
bdf9d25
Fix integer overflow in build_read_multi_rsp
May 19, 2023
71c7ac6
Fix potential abort in btu_av_act.cc
Apr 27, 2023
d9606b9
Fix UAF in gatt_cl.cc
Jun 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions bta/av/bta_av_act.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,10 @@ void bta_av_rc_msg(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
av.remote_cmd.rc_handle = p_data->rc_msg.handle;
(*p_cb->p_cback)(evt, &av);
/* If browsing message, then free the browse message buffer */
bta_av_rc_free_browse_msg(p_cb, p_data);
if (p_data->rc_msg.opcode == AVRC_OP_BROWSE &&
p_data->rc_msg.msg.browse.p_browse_pkt != NULL) {
bta_av_rc_free_browse_msg(p_cb, p_data);
}
}
}

Expand Down Expand Up @@ -1973,8 +1976,23 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) {
if (p_lcb) {
rc_handle = bta_av_rc_create(p_cb, AVCT_INT,
(uint8_t)(p_scb->hdi + 1), p_lcb->lidx);
p_cb->rcb[rc_handle].peer_features = peer_features;
p_cb->rcb[rc_handle].cover_art_psm = cover_art_psm;
if (rc_handle < BTA_AV_NUM_RCB) {
p_cb->rcb[rc_handle].peer_features = peer_features;
p_cb->rcb[rc_handle].cover_art_psm = cover_art_psm;
} else {
/* cannot create valid rc_handle for current device. report failure
*/
APPL_TRACE_ERROR("%s: no link resources available", __func__);
p_scb->use_rc = false;
tBTA_AV_RC_OPEN rc_open;
rc_open.peer_addr = p_scb->PeerAddress();
rc_open.peer_features = 0;
rc_open.cover_art_psm = 0;
rc_open.status = BTA_AV_FAIL_RESOURCES;
tBTA_AV bta_av_data;
bta_av_data.rc_open = rc_open;
(*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, &bta_av_data);
}
} else {
APPL_TRACE_ERROR("%s: can not find LCB!!", __func__);
}
Expand Down
8 changes: 8 additions & 0 deletions bta/dm/bta_dm_act.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "bta_dm_int.h"
#include "bta_sys.h"
#include "btif_storage.h"
#include "btif_config.h"
#include "btm_api.h"
#include "btm_int.h"
#include "btu.h"
Expand All @@ -48,6 +49,7 @@
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "sdp_api.h"
#include "stack/btm/btm_ble_int.h"
#include "stack/gatt/connection_manager.h"
#include "stack/include/gatt_api.h"
#include "utl.h"
Expand Down Expand Up @@ -705,6 +707,12 @@ void bta_dm_remove_device(const RawAddress& bd_addr) {
if (!other_address_connected && !other_address.IsEmpty()) {
bta_dm_process_remove_device(other_address);
}

/* Check the length of the paired devices, and if 0 then reset IRK */
if (btif_storage_get_num_bonded_devices() < 1) {
LOG(INFO) << "Last paired device removed, resetting IRK";
btm_ble_reset_id();
}
}

/*******************************************************************************
Expand Down
10 changes: 7 additions & 3 deletions bta/hf_client/bta_hf_client_at.cc
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ static void bta_hf_client_handle_cind_list_item(tBTA_HF_CLIENT_CB* client_cb,

APPL_TRACE_DEBUG("%s: %lu.%s <%lu:%lu>", __func__, index, name, min, max);

if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
return;
}

/* look for a matching indicator on list of supported ones */
for (i = 0; i < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT; i++) {
if (strcmp(name, BTA_HF_CLIENT_INDICATOR_SERVICE) == 0) {
Expand Down Expand Up @@ -793,9 +797,9 @@ void bta_hf_client_binp(tBTA_HF_CLIENT_CB* client_cb, char* number) {
} while (0)

/* skip rest of AT string up to <cr> */
#define AT_SKIP_REST(buf) \
do { \
while (*(buf) != '\r') (buf)++; \
#define AT_SKIP_REST(buf) \
do { \
while (*(buf) != '\r' && *(buf) != '\0') (buf)++; \
} while (0)

static char* bta_hf_client_parse_ok(tBTA_HF_CLIENT_CB* client_cb,
Expand Down
4 changes: 3 additions & 1 deletion btif/src/bluetooth.cc
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,12 @@ static int get_connection_state(const RawAddress* bd_addr) {

static int pin_reply(const RawAddress* bd_addr, uint8_t accept, uint8_t pin_len,
bt_pin_code_t* pin_code) {
bt_pin_code_t tmp_pin_code;
/* sanity check */
if (!interface_ready()) return BT_STATUS_NOT_READY;

return btif_dm_pin_reply(bd_addr, accept, pin_len, pin_code);
memcpy(&tmp_pin_code, pin_code, pin_len);
return btif_dm_pin_reply(bd_addr, accept, pin_len, &tmp_pin_code);
}

static int ssp_reply(const RawAddress* bd_addr, bt_ssp_variant_t variant,
Expand Down
7 changes: 1 addition & 6 deletions btif/src/btif_dm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1185,16 +1185,13 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) {
break;

case HCI_ERR_PAIRING_NOT_ALLOWED:
is_bonded_device_removed =
(btif_storage_remove_bonded_device(&bd_addr) == BT_STATUS_SUCCESS);
status = BT_STATUS_AUTH_REJECTED;
break;

/* map the auth failure codes, so we can retry pairing if necessary */
case HCI_ERR_AUTH_FAILURE:
case HCI_ERR_KEY_MISSING:
is_bonded_device_removed =
(btif_storage_remove_bonded_device(&bd_addr) == BT_STATUS_SUCCESS);
is_bonded_device_removed = false;
[[fallthrough]];
case HCI_ERR_HOST_REJECT_SECURITY:
case HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE:
Expand Down Expand Up @@ -1225,8 +1222,6 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) {
/* Remove Device as bonded in nvram as authentication failed */
BTIF_TRACE_DEBUG("%s(): removing hid pointing device from nvram",
__func__);
is_bonded_device_removed =
(btif_storage_remove_bonded_device(&bd_addr) == BT_STATUS_SUCCESS);
}
// Report bond state change to java only if we are bonding to a device or
// a device is removed from the pairing list.
Expand Down
50 changes: 45 additions & 5 deletions btif/src/btif_hh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,38 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
}
}

/*******************************************************************************
*
* Function btif_hh_hsdata_rpt_copy_cb
*
* Description Deep copies the tBTA_HH_HSDATA structure
*
* Returns void
*
******************************************************************************/

static void btif_hh_hsdata_rpt_copy_cb(uint16_t event, char* p_dest,
char* p_src) {
tBTA_HH_HSDATA* p_dst_data = (tBTA_HH_HSDATA*)p_dest;
tBTA_HH_HSDATA* p_src_data = (tBTA_HH_HSDATA*)p_src;
BT_HDR* hdr;

if (!p_src) {
BTIF_TRACE_ERROR("%s: Nothing to copy", __func__);
return;
}

memcpy(p_dst_data, p_src_data, sizeof(tBTA_HH_HSDATA));

hdr = p_src_data->rsp_data.p_rpt_data;
if (hdr != NULL) {
uint8_t* p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HH_HSDATA);
memcpy(p_data, hdr, BT_HDR_SIZE + hdr->offset + hdr->len);

p_dst_data->rsp_data.p_rpt_data = (BT_HDR*)p_data;
}
}

/*******************************************************************************
*
* Function bte_hh_evt
Expand All @@ -1106,6 +1138,7 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
bt_status_t status;
int param_len = 0;
tBTIF_COPY_CBACK* p_copy_cback = NULL;

if (BTA_HH_ENABLE_EVT == event)
param_len = sizeof(tBTA_HH_STATUS);
Expand All @@ -1117,11 +1150,18 @@ void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
param_len = sizeof(tBTA_HH_CBDATA);
else if (BTA_HH_GET_DSCP_EVT == event)
param_len = sizeof(tBTA_HH_DEV_DSCP_INFO);
else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event) ||
(BTA_HH_GET_IDLE_EVT == event))
else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_IDLE_EVT == event))
param_len = sizeof(tBTA_HH_HSDATA);
else if (BTA_HH_GET_RPT_EVT == event) {
BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data;
param_len = sizeof(tBTA_HH_HSDATA);
else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
(BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))

if (hdr != NULL) {
p_copy_cback = btif_hh_hsdata_rpt_copy_cb;
param_len += BT_HDR_SIZE + hdr->offset + hdr->len;
}
} else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
(BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
param_len = sizeof(tBTA_HH_CBDATA);
else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event))
param_len = sizeof(tBTA_HH_DEV_INFO);
Expand All @@ -1130,7 +1170,7 @@ void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
/* switch context to btif task context (copy full union size for convenience)
*/
status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event,
(char*)p_data, param_len, NULL);
(char*)p_data, param_len, p_copy_cback);

/* catch any failed context transfers */
ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
Expand Down
5 changes: 5 additions & 0 deletions btif/src/btif_rc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1968,6 +1968,11 @@ static bt_status_t register_notification_rsp(
dump_rc_notification_event_id(event_id));
std::unique_lock<std::mutex> lock(btif_rc_cb.lock);

if (event_id > MAX_RC_NOTIFICATIONS) {
BTIF_TRACE_ERROR("Invalid event id");
return BT_STATUS_PARM_INVALID;
}

memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));

avrc_rsp.reg_notif.event_id = event_id;
Expand Down
2 changes: 2 additions & 0 deletions osi/src/allocator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@ char* osi_strndup(const char* str, size_t len) {
}

void* osi_malloc(size_t size) {
CHECK(static_cast<ssize_t>(size) >= 0);
size_t real_size = allocation_tracker_resize_for_canary(size);
void* ptr = malloc(real_size);
CHECK(ptr);
return allocation_tracker_notify_alloc(alloc_allocator_id, ptr, size);
}

void* osi_calloc(size_t size) {
CHECK(static_cast<ssize_t>(size) >= 0);
size_t real_size = allocation_tracker_resize_for_canary(size);
void* ptr = calloc(1, real_size);
CHECK(ptr);
Expand Down
5 changes: 5 additions & 0 deletions stack/a2dp/a2dp_sbc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,11 @@ bool A2DP_BuildCodecHeaderSbc(UNUSED_ATTR const uint8_t* p_codec_info,
BT_HDR* p_buf, uint16_t frames_per_packet) {
uint8_t* p;

// there is a timestamp right following p_buf
if (p_buf->offset < 4 + A2DP_SBC_MPL_HDR_LEN) {
return false;
}

p_buf->offset -= A2DP_SBC_MPL_HDR_LEN;
p = (uint8_t*)(p_buf + 1) + p_buf->offset;
p_buf->len += A2DP_SBC_MPL_HDR_LEN;
Expand Down
16 changes: 14 additions & 2 deletions stack/avct/avct_lcb_act.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "bt_types.h"
#include "bt_utils.h"
#include "btm_api.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"

/* packet header length lookup table */
Expand Down Expand Up @@ -64,7 +65,12 @@ static BT_HDR* avct_lcb_msg_asmbl(tAVCT_LCB* p_lcb, BT_HDR* p_buf) {
pkt_type = AVCT_PKT_TYPE(p);

/* quick sanity check on length */
if (p_buf->len < avct_lcb_pkt_type_len[pkt_type]) {
if (p_buf->len < avct_lcb_pkt_type_len[pkt_type] ||
(sizeof(BT_HDR) + p_buf->offset + p_buf->len) > BT_DEFAULT_BUFFER_SIZE) {
if ((sizeof(BT_HDR) + p_buf->offset + p_buf->len) >
BT_DEFAULT_BUFFER_SIZE) {
android_errorWriteWithInfoLog(0x534e4554, "230867224", -1, NULL, 0);
}
osi_free(p_buf);
AVCT_TRACE_WARNING("Bad length during reassembly");
p_ret = NULL;
Expand All @@ -85,13 +91,19 @@ static BT_HDR* avct_lcb_msg_asmbl(tAVCT_LCB* p_lcb, BT_HDR* p_buf) {
if (p_lcb->p_rx_msg != NULL)
AVCT_TRACE_WARNING("Got start during reassembly");

osi_free(p_lcb->p_rx_msg);
osi_free_and_reset((void**)&p_lcb->p_rx_msg);

/*
* Allocate bigger buffer for reassembly. As lower layers are
* not aware of possible packet size after reassembly, they
* would have allocated smaller buffer.
*/
if (sizeof(BT_HDR) + p_buf->offset + p_buf->len > BT_DEFAULT_BUFFER_SIZE) {
android_errorWriteLog(0x534e4554, "232023771");
osi_free(p_buf);
p_ret = NULL;
return p_ret;
}
p_lcb->p_rx_msg = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
memcpy(p_lcb->p_rx_msg, p_buf, sizeof(BT_HDR) + p_buf->offset + p_buf->len);

Expand Down
10 changes: 8 additions & 2 deletions stack/avdt/avdt_msg.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,12 @@ BT_HDR* avdt_msg_asmbl(AvdtpCcb* p_ccb, BT_HDR* p_buf) {
* not aware of possible packet size after reassembly, they
* would have allocated smaller buffer.
*/
if (sizeof(BT_HDR) + p_buf->offset + p_buf->len > BT_DEFAULT_BUFFER_SIZE) {
android_errorWriteLog(0x534e4554, "232023771");
osi_free(p_buf);
p_ret = NULL;
return p_ret;
}
p_ccb->p_rx_msg = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
memcpy(p_ccb->p_rx_msg, p_buf, sizeof(BT_HDR) + p_buf->offset + p_buf->len);

Expand Down Expand Up @@ -1283,14 +1289,14 @@ BT_HDR* avdt_msg_asmbl(AvdtpCcb* p_ccb, BT_HDR* p_buf) {
* NOTE: The buffer is allocated above at the beginning of the
* reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
*/
uint16_t buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
size_t buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);

/* adjust offset and len of fragment for header byte */
p_buf->offset += AVDT_LEN_TYPE_CONT;
p_buf->len -= AVDT_LEN_TYPE_CONT;

/* verify length */
if ((p_ccb->p_rx_msg->offset + p_buf->len) > buf_len) {
if (((size_t) p_ccb->p_rx_msg->offset + (size_t) p_buf->len) > buf_len) {
/* won't fit; free everything */
AVDT_TRACE_WARNING("%s: Fragmented message too big!", __func__);
osi_free_and_reset((void**)&p_ccb->p_rx_msg);
Expand Down
20 changes: 15 additions & 5 deletions stack/avdt/avdt_scb_act.cc
Original file line number Diff line number Diff line change
Expand Up @@ -255,19 +255,24 @@ void avdt_scb_hdl_pkt_no_frag(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
if (offset > len) goto length_error;
p += 2;
BE_STREAM_TO_UINT16(ex_len, p);
offset += ex_len * 4;
p += ex_len * 4;
}

if ((p - p_start) >= len) {
AVDT_TRACE_WARNING("%s: handling malformatted packet: ex_len too large", __func__);
osi_free_and_reset((void**)&p_data->p_pkt);
return;
}
offset = p - p_start;

/* adjust length for any padding at end of packet */
if (o_p) {
/* padding length in last byte of packet */
pad_len = *(p_start + p_data->p_pkt->len);
pad_len = *(p_start + len - 1);
}

/* do sanity check */
if ((offset > p_data->p_pkt->len) ||
((pad_len + offset) > p_data->p_pkt->len)) {
if (pad_len >= (len - offset)) {
AVDT_TRACE_WARNING("Got bad media packet");
osi_free_and_reset((void**)&p_data->p_pkt);
}
Expand Down Expand Up @@ -308,7 +313,7 @@ uint8_t* avdt_scb_hdl_report(AvdtpScb* p_scb, uint8_t* p, uint16_t len) {
uint8_t* p_start = p;
uint32_t ssrc;
uint8_t o_v, o_p, o_cc;
uint16_t min_len = 0;
uint32_t min_len = 0;
AVDT_REPORT_TYPE pt;
tAVDT_REPORT_DATA report;

Expand Down Expand Up @@ -977,6 +982,11 @@ void avdt_scb_hdl_write_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {

/* Build a media packet, and add an RTP header if required. */
if (add_rtp_header) {
if (p_data->apiwrite.p_buf->offset < AVDT_MEDIA_HDR_SIZE) {
android_errorWriteWithInfoLog(0x534e4554, "242535997", -1, NULL, 0);
return;
}

ssrc = avdt_scb_gen_ssrc(p_scb);

p_data->apiwrite.p_buf->len += AVDT_MEDIA_HDR_SIZE;
Expand Down
Loading