aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-07-20 00:31:19 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-07-20 00:31:19 +0000
commit5ad6b0c6a974435c705ad573ba107261bf9882ea (patch)
tree4a741b9daf06bea664a420116c9256706df30227
parent6bde1f2e5c1700370fe98eba5e7b00b13debe68b (diff)
parent62a2cdf7b9f9d0a3635333bb6e2d65f102bdc482 (diff)
downloadbt-oreo-m6-s3-release.tar.gz
Merge cherrypicks of [4586293, 4586294, 4586295, 4584365, 4584366, 4584367, 4584368, 4584369, 4584370, 4587544, 4584705, 4586296, 4587545, 4587546, 4586297, 4586298, 4586299, 4586300, 4584371, 4586301, 4584706, 4586302, 4586303, 4587584, 4587585, 4587586, 4587587, 4587588, 4587589, 4587590, 4587591, 4587644, 4587645, 4587646, 4587647, 4587648, 4587649, 4587650, 4587651, 4587652, 4587653, 4587654, 4587655, 4587656, 4587657, 4587658, 4587659, 4587660, 4587661, 4587662, 4584536, 4587547, 4587548, 4587549, 4584707, 4584708, 4587550, 4587551, 4587593, 4586516, 4584372, 4584373, 4584374, 4587595, 4584375, 4584376, 4587552, 4587596, 4587597, 4587598, 4587599, 4584414, 4584415, 4584416, 4584417, 4584418, 4584419, 4584420, 4584421, 4584422, 4584423, 4587804, 4587805, 4587806, 4587807, 4587808, 4587809, 4587810, 4587811, 4587812, 4587813, 4587814, 4587815, 4587816, 4587817, 4587818, 4587884, 4587885, 4587600, 4587601, 4587819, 4584709] into sparse-4749909-L91900000192339903android-8.1.0_r43oreo-m6-s3-release
Change-Id: Ia4aa795770eddc7d3f00909f8b193d67e82052c3
-rw-r--r--bta/dm/bta_dm_act.cc21
-rw-r--r--bta/pan/bta_pan_act.cc34
-rw-r--r--btif/src/btif_rc.cc7
-rw-r--r--btif/src/btif_storage.cc4
-rw-r--r--stack/avct/avct_bcb_act.cc15
-rw-r--r--stack/avdt/avdt_msg.cc11
-rw-r--r--stack/avrc/avrc_api.cc9
-rw-r--r--stack/avrc/avrc_pars_ct.cc4
-rw-r--r--stack/bnep/bnep_api.cc9
-rw-r--r--stack/bnep/bnep_main.cc37
-rw-r--r--stack/gatt/gatt_cl.cc22
-rw-r--r--stack/gatt/gatt_sr.cc29
-rw-r--r--stack/l2cap/l2c_ble.cc5
-rw-r--r--stack/l2cap/l2c_fcr.cc22
-rw-r--r--stack/l2cap/l2c_main.cc104
-rw-r--r--stack/pan/pan_main.cc12
-rw-r--r--stack/sdp/sdp_discovery.cc23
-rw-r--r--stack/sdp/sdp_server.cc3
-rw-r--r--stack/smp/p_256_ecc_pp.cc22
-rw-r--r--stack/smp/p_256_ecc_pp.h3
-rw-r--r--stack/smp/smp_act.cc12
-rw-r--r--stack/smp/smp_br_main.cc7
-rw-r--r--stack/smp/smp_main.cc8
23 files changed, 361 insertions, 62 deletions
diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc
index 187bc68e0..175e3faf2 100644
--- a/bta/dm/bta_dm_act.cc
+++ b/bta/dm/bta_dm_act.cc
@@ -28,6 +28,7 @@
#include <base/bind.h>
#include <base/callback.h>
#include <base/logging.h>
+#include <cutils/log.h>
#include <string.h>
#include "bt_common.h"
@@ -146,6 +147,8 @@ static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result);
#define BTA_DM_SWITCH_DELAY_TIMER_MS 500
#endif
+#define BTA_MAX_SERVICES 32
+
static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr);
static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr);
static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir,
@@ -1486,7 +1489,7 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
tBT_UUID service_uuid;
uint32_t num_uuids = 0;
- uint8_t uuid_list[32][MAX_UUID_SIZE]; // assuming a max of 32 services
+ uint8_t uuid_list[BTA_MAX_SERVICES][MAX_UUID_SIZE]; // assuming a max of 32 services
if ((p_data->sdp_event.sdp_result == SDP_SUCCESS) ||
(p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH) ||
@@ -1554,8 +1557,12 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index -
1];
/* Add to the list of UUIDs */
- sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
- num_uuids++;
+ if (num_uuids < BTA_MAX_SERVICES) {
+ sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
+ num_uuids++;
+ } else {
+ android_errorWriteLog(0x534e4554, "74016921");
+ }
}
}
}
@@ -1587,8 +1594,12 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
if (p_sdp_rec) {
if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) {
- memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
- num_uuids++;
+ if (num_uuids < BTA_MAX_SERVICES) {
+ memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
+ num_uuids++;
+ } else {
+ android_errorWriteLog(0x534e4554, "74016921");
+ }
}
}
} while (p_sdp_rec);
diff --git a/bta/pan/bta_pan_act.cc b/bta/pan/bta_pan_act.cc
index 41e0bf6b4..789cce8e3 100644
--- a/bta/pan/bta_pan_act.cc
+++ b/bta/pan/bta_pan_act.cc
@@ -171,31 +171,25 @@ static void bta_pan_data_flow_cb(uint16_t handle, tPAN_RESULT result) {
static void bta_pan_data_buf_ind_cback(uint16_t handle, const RawAddress& src,
const RawAddress& dst, uint16_t protocol,
BT_HDR* p_buf, bool ext, bool forward) {
- tBTA_PAN_SCB* p_scb;
- BT_HDR* p_new_buf;
-
- p_scb = bta_pan_scb_by_handle(handle);
+ tBTA_PAN_SCB* p_scb = bta_pan_scb_by_handle(handle);
if (p_scb == NULL) {
return;
}
- if (sizeof(tBTA_PAN_DATA_PARAMS) > p_buf->offset) {
- /* offset smaller than data structure in front of actual data */
- if (sizeof(BT_HDR) + sizeof(tBTA_PAN_DATA_PARAMS) + p_buf->len >
- PAN_BUF_SIZE) {
- android_errorWriteLog(0x534e4554, "63146237");
- APPL_TRACE_ERROR("%s: received buffer length too large: %d", __func__,
- p_buf->len);
- return;
- }
- p_new_buf = (BT_HDR*)osi_malloc(PAN_BUF_SIZE);
- memcpy((uint8_t*)(p_new_buf + 1) + sizeof(tBTA_PAN_DATA_PARAMS),
- (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
- p_new_buf->len = p_buf->len;
- p_new_buf->offset = sizeof(tBTA_PAN_DATA_PARAMS);
- } else {
- p_new_buf = p_buf;
+ if (sizeof(BT_HDR) + sizeof(tBTA_PAN_DATA_PARAMS) + p_buf->len >
+ PAN_BUF_SIZE) {
+ android_errorWriteLog(0x534e4554, "63146237");
+ APPL_TRACE_ERROR("%s: received buffer length too large: %d", __func__,
+ p_buf->len);
+ return;
}
+
+ BT_HDR* p_new_buf = (BT_HDR*)osi_malloc(PAN_BUF_SIZE);
+ memcpy((uint8_t*)(p_new_buf + 1) + sizeof(tBTA_PAN_DATA_PARAMS),
+ (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
+ p_new_buf->len = p_buf->len;
+ p_new_buf->offset = sizeof(tBTA_PAN_DATA_PARAMS);
+
/* copy params into the space before the data */
((tBTA_PAN_DATA_PARAMS*)p_new_buf)->src = src;
((tBTA_PAN_DATA_PARAMS*)p_new_buf)->dst = dst;
diff --git a/btif/src/btif_rc.cc b/btif/src/btif_rc.cc
index fc10b8b61..edd073062 100644
--- a/btif/src/btif_rc.cc
+++ b/btif/src/btif_rc.cc
@@ -45,6 +45,7 @@
#include "btif_util.h"
#include "btu.h"
#include "device/include/interop.h"
+#include "log/log.h"
#include "osi/include/list.h"
#include "osi/include/osi.h"
#include "osi/include/properties.h"
@@ -3502,6 +3503,12 @@ static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg,
RawAddress rc_addr = p_dev->rc_addr;
app_settings.num_attr = p_rsp->num_val;
+
+ if (app_settings.num_attr > BTRC_MAX_APP_SETTINGS) {
+ android_errorWriteLog(0x534e4554, "73824150");
+ app_settings.num_attr = BTRC_MAX_APP_SETTINGS;
+ }
+
for (xx = 0; xx < app_settings.num_attr; xx++) {
app_settings.attr_ids[xx] = p_rsp->p_vals[xx].attr_id;
app_settings.attr_values[xx] = p_rsp->p_vals[xx].attr_val;
diff --git a/btif/src/btif_storage.cc b/btif/src/btif_storage.cc
index 9d4a84ed0..1c34787b2 100644
--- a/btif/src/btif_storage.cc
+++ b/btif/src/btif_storage.cc
@@ -235,6 +235,10 @@ static int prop2cfg(const RawAddress* remote_bd_addr, bt_property_t* prop) {
bt_uuid_t* p_uuid = (bt_uuid_t*)prop->val + i;
memset(buf, 0, sizeof(buf));
uuid_to_string_legacy(p_uuid, buf, sizeof(buf));
+ if (strlen(value) + strlen(buf) + 1 > (int) sizeof(value) - 1) {
+ android_errorWriteLog(0x534e4554, "73963551");
+ return false;
+ }
strcat(value, buf);
// strcat(value, ";");
strcat(value, " ");
diff --git a/stack/avct/avct_bcb_act.cc b/stack/avct/avct_bcb_act.cc
index bd99562ca..011a52db7 100644
--- a/stack/avct/avct_bcb_act.cc
+++ b/stack/avct/avct_bcb_act.cc
@@ -25,6 +25,7 @@
*
*****************************************************************************/
+#include <log/log.h>
#include <string.h>
#include "avct_api.h"
#include "avct_int.h"
@@ -68,6 +69,12 @@ static BT_HDR* avct_bcb_msg_asmbl(UNUSED_ATTR tAVCT_BCB* p_bcb, BT_HDR* p_buf) {
uint8_t* p;
uint8_t pkt_type;
+ if (p_buf->len == 0) {
+ osi_free_and_reset((void**)&p_buf);
+ android_errorWriteLog(0x534e4554, "79944113");
+ return nullptr;
+ }
+
/* parse the message header */
p = (uint8_t*)(p_buf + 1) + p_buf->offset;
pkt_type = AVCT_PKT_TYPE(p);
@@ -520,6 +527,14 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
return;
}
+ if (p_data->p_buf->len < AVCT_HDR_LEN_SINGLE) {
+ AVCT_TRACE_WARNING("Invalid AVCTP packet length %d: must be at least %d",
+ p_data->p_buf->len, AVCT_HDR_LEN_SINGLE);
+ osi_free_and_reset((void**)&p_data->p_buf);
+ android_errorWriteLog(0x534e4554, "79944113");
+ return;
+ }
+
p = (uint8_t*)(p_data->p_buf + 1) + p_data->p_buf->offset;
/* parse header byte */
diff --git a/stack/avdt/avdt_msg.cc b/stack/avdt/avdt_msg.cc
index 7ab7edc00..52ce2e8a6 100644
--- a/stack/avdt/avdt_msg.cc
+++ b/stack/avdt/avdt_msg.cc
@@ -26,6 +26,7 @@
*
******************************************************************************/
+#include <log/log.h>
#include <string.h>
#include "avdt_api.h"
#include "avdt_int.h"
@@ -602,6 +603,11 @@ static uint8_t avdt_msg_prs_cfg(tAVDT_CFG* p_cfg, uint8_t* p, uint16_t len,
case AVDT_CAT_PROTECT:
p_cfg->psc_mask &= ~AVDT_PSC_PROTECT;
+ if (p + elem_len > p_end) {
+ err = AVDT_ERR_LENGTH;
+ android_errorWriteLog(0x534e4554, "78288378");
+ break;
+ }
if ((elem_len + protect_offset) < AVDT_PROTECT_SIZE) {
p_cfg->num_protect++;
p_cfg->protect_info[protect_offset] = elem_len;
@@ -622,6 +628,11 @@ static uint8_t avdt_msg_prs_cfg(tAVDT_CFG* p_cfg, uint8_t* p, uint16_t len,
if (elem_len >= AVDT_CODEC_SIZE) {
tmp = AVDT_CODEC_SIZE - 1;
}
+ if (p + tmp > p_end) {
+ err = AVDT_ERR_LENGTH;
+ android_errorWriteLog(0x534e4554, "78288378");
+ break;
+ }
p_cfg->num_codec++;
p_cfg->codec_info[0] = elem_len;
memcpy(&p_cfg->codec_info[1], p, tmp);
diff --git a/stack/avrc/avrc_api.cc b/stack/avrc/avrc_api.cc
index b67a6b764..bdf78b736 100644
--- a/stack/avrc/avrc_api.cc
+++ b/stack/avrc/avrc_api.cc
@@ -425,15 +425,15 @@ static BT_HDR* avrc_proc_vendor_command(uint8_t handle, uint8_t label,
}
if (status != AVRC_STS_NO_ERROR) {
- /* use the current GKI buffer to build/send the reject message */
- p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
+ p_rsp = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
+ p_rsp->offset = p_pkt->offset;
+ p_data = (uint8_t*)(p_rsp + 1) + p_pkt->offset;
*p_data++ = AVRC_RSP_REJ;
p_data += AVRC_VENDOR_HDR_SIZE; /* pdu */
*p_data++ = 0; /* pkt_type */
UINT16_TO_BE_STREAM(p_data, 1); /* len */
*p_data++ = status; /* error code */
- p_pkt->len = AVRC_VENDOR_HDR_SIZE + 5;
- p_rsp = p_pkt;
+ p_rsp->len = AVRC_VENDOR_HDR_SIZE + 5;
}
return p_rsp;
@@ -574,6 +574,7 @@ static uint8_t avrc_proc_far_msg(uint8_t handle, uint8_t label, uint8_t cr,
p_rsp = avrc_proc_vendor_command(handle, label, *pp_pkt, p_msg);
if (p_rsp) {
AVCT_MsgReq(handle, label, AVCT_RSP, p_rsp);
+ osi_free_and_reset((void**)pp_pkt);
drop_code = 3;
} else if (p_msg->hdr.opcode == AVRC_OP_DROP) {
drop_code = 1;
diff --git a/stack/avrc/avrc_pars_ct.cc b/stack/avrc/avrc_pars_ct.cc
index 334362449..fbfeeaf9f 100644
--- a/stack/avrc/avrc_pars_ct.cc
+++ b/stack/avrc/avrc_pars_ct.cc
@@ -119,6 +119,10 @@ void avrc_parse_notification_rsp(uint8_t* p_stream,
case AVRC_EVT_APP_SETTING_CHANGE:
BE_STREAM_TO_UINT8(p_rsp->param.player_setting.num_attr, p_stream);
+ if (p_rsp->param.player_setting.num_attr > AVRC_MAX_APP_SETTINGS) {
+ android_errorWriteLog(0x534e4554, "73782082");
+ p_rsp->param.player_setting.num_attr = AVRC_MAX_APP_SETTINGS;
+ }
for (int index = 0; index < p_rsp->param.player_setting.num_attr;
index++) {
BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_id[index],
diff --git a/stack/bnep/bnep_api.cc b/stack/bnep/bnep_api.cc
index 923ce5093..e5d3c0948 100644
--- a/stack/bnep/bnep_api.cc
+++ b/stack/bnep/bnep_api.cc
@@ -23,6 +23,7 @@
******************************************************************************/
#include "bnep_api.h"
+#include <log/log.h>
#include <string.h>
#include "bnep_int.h"
@@ -383,6 +384,10 @@ tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr,
protocol = 0;
else {
new_len += 4;
+ if (new_len > org_len) {
+ android_errorWriteLog(0x534e4554, "74947856");
+ return BNEP_IGNORE_CMD;
+ }
p_data[2] = 0;
p_data[3] = 0;
}
@@ -479,6 +484,10 @@ tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& p_dest_addr,
protocol = 0;
else {
new_len += 4;
+ if (new_len > org_len) {
+ android_errorWriteLog(0x534e4554, "74947856");
+ return BNEP_IGNORE_CMD;
+ }
p_data[2] = 0;
p_data[3] = 0;
}
diff --git a/stack/bnep/bnep_main.cc b/stack/bnep/bnep_main.cc
index f621fdb64..d60fb55fa 100644
--- a/stack/bnep/bnep_main.cc
+++ b/stack/bnep/bnep_main.cc
@@ -431,6 +431,11 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) {
tBNEP_CONN* p_bcb;
uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
uint16_t rem_len = p_buf->len;
+ if (rem_len == 0) {
+ android_errorWriteLog(0x534e4554, "78286118");
+ osi_free(p_buf);
+ return;
+ }
uint8_t type, ctrl_type, ext_type = 0;
bool extension_present, fw_ext_present;
uint16_t protocol = 0;
@@ -479,24 +484,35 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) {
uint16_t org_len, new_len;
/* parse the extension headers and process unknown control headers */
org_len = rem_len;
- new_len = 0;
do {
- if (org_len < 2) break;
+ if (org_len < 2) {
+ android_errorWriteLog(0x534e4554, "67863755");
+ break;
+ }
ext = *p++;
length = *p++;
- p += length;
new_len = (length + 2);
- if (new_len > org_len) break;
+ if (new_len > org_len) {
+ android_errorWriteLog(0x534e4554, "67863755");
+ break;
+ }
- if ((!(ext & 0x7F)) && (*p > BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG))
- bnep_send_command_not_understood(p_bcb, *p);
+ if ((ext & 0x7F) == BNEP_EXTENSION_FILTER_CONTROL) {
+ if (length == 0) {
+ android_errorWriteLog(0x534e4554, "79164722");
+ break;
+ }
+ if (*p > BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG) {
+ bnep_send_command_not_understood(p_bcb, *p);
+ }
+ }
+
+ p += length;
org_len -= new_len;
} while (ext & 0x80);
- android_errorWriteLog(0x534e4554, "67863755");
}
-
osi_free(p_buf);
return;
}
@@ -540,13 +556,13 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) {
while (extension_present && p && rem_len) {
ext_type = *p++;
rem_len--;
- android_errorWriteLog(0x534e4554, "69271284");
extension_present = ext_type >> 7;
ext_type &= 0x7F;
/* if unknown extension present stop processing */
- if (ext_type) break;
+ if (ext_type != BNEP_EXTENSION_FILTER_CONTROL) break;
+ android_errorWriteLog(0x534e4554, "69271284");
p = bnep_process_control_packet(p_bcb, p, &rem_len, true);
}
}
@@ -607,7 +623,6 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) {
if (bnep_cb.p_data_buf_cb) {
(*bnep_cb.p_data_buf_cb)(p_bcb->handle, *p_src_addr, *p_dst_addr, protocol,
p_buf, fw_ext_present);
- osi_free(p_buf);
} else if (bnep_cb.p_data_ind_cb) {
(*bnep_cb.p_data_ind_cb)(p_bcb->handle, *p_src_addr, *p_dst_addr, protocol,
p, rem_len, fw_ext_present);
diff --git a/stack/gatt/gatt_cl.cc b/stack/gatt/gatt_cl.cc
index 2843ac938..9e77e1587 100644
--- a/stack/gatt/gatt_cl.cc
+++ b/stack/gatt/gatt_cl.cc
@@ -29,6 +29,7 @@
#include "bt_utils.h"
#include "gatt_int.h"
#include "l2c_int.h"
+#include "log/log.h"
#include "osi/include/osi.h"
#define GATT_WRITE_LONG_HDR_SIZE 5 /* 1 opcode + 2 handle + 2 offset */
@@ -507,9 +508,24 @@ void gatt_process_error_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
VLOG(1) << __func__;
- STREAM_TO_UINT8(opcode, p);
- STREAM_TO_UINT16(handle, p);
- STREAM_TO_UINT8(reason, p);
+
+ if (len < 4) {
+ android_errorWriteLog(0x534e4554, "79591688");
+ LOG(ERROR) << "Error response too short";
+ // Specification does not clearly define what should happen if error
+ // response is too short. General rule in BT Spec 5.0 Vol 3, Part F 3.4.1.1
+ // is: "If an error code is received in the Error Response that is not
+ // understood by the client, for example an error code that was reserved for
+ // future use that is now being used in a future version of this
+ // specification, then the Error Response shall still be considered to state
+ // that the given request cannot be performed for an unknown reason."
+ opcode = handle = 0;
+ reason = 0x7F;
+ } else {
+ STREAM_TO_UINT8(opcode, p);
+ STREAM_TO_UINT16(handle, p);
+ STREAM_TO_UINT8(reason, p);
+ }
if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) {
gatt_proc_disc_error_rsp(tcb, p_clcb, opcode, handle, reason);
diff --git a/stack/gatt/gatt_sr.cc b/stack/gatt/gatt_sr.cc
index 3af986639..f9e8f537f 100644
--- a/stack/gatt/gatt_sr.cc
+++ b/stack/gatt/gatt_sr.cc
@@ -22,6 +22,7 @@
*
******************************************************************************/
+#include <log/log.h>
#include "bt_target.h"
#include "bt_utils.h"
#include "osi/include/osi.h"
@@ -281,8 +282,8 @@ tGATT_STATUS gatt_sr_process_app_rsp(tGATT_TCB& tcb, tGATT_IF gatt_if,
* Returns void
*
******************************************************************************/
-void gatt_process_exec_write_req(tGATT_TCB& tcb, uint8_t op_code,
- UNUSED_ATTR uint16_t len, uint8_t* p_data) {
+void gatt_process_exec_write_req(tGATT_TCB& tcb, uint8_t op_code, uint16_t len,
+ uint8_t* p_data) {
uint8_t *p = p_data, flag, i = 0;
uint32_t trans_id = 0;
tGATT_IF gatt_if;
@@ -301,6 +302,13 @@ void gatt_process_exec_write_req(tGATT_TCB& tcb, uint8_t op_code,
}
#endif
+ if (len < sizeof(flag)) {
+ android_errorWriteLog(0x534e4554, "73172115");
+ LOG(ERROR) << __func__ << "invalid length";
+ gatt_send_error_rsp(tcb, GATT_INVALID_PDU, GATT_REQ_EXEC_WRITE, 0, false);
+ return;
+ }
+
STREAM_TO_UINT8(flag, p);
/* mask the flag */
@@ -780,7 +788,8 @@ static void gatts_process_mtu_req(tGATT_TCB& tcb, uint16_t len,
void gatts_process_read_by_type_req(tGATT_TCB& tcb, uint8_t op_code,
uint16_t len, uint8_t* p_data) {
tBT_UUID uuid;
- uint16_t s_hdl, e_hdl, err_hdl = 0;
+ uint16_t s_hdl = 0, e_hdl = 0, err_hdl = 0;
+ if (len < 4) android_errorWriteLog(0x534e4554, "73125709");
tGATT_STATUS reason =
gatts_validate_packet_format(op_code, len, p_data, &uuid, s_hdl, e_hdl);
@@ -940,9 +949,19 @@ void gatts_process_write_req(tGATT_TCB& tcb, tGATT_SRV_LIST_ELEM& el,
*/
static void gatts_process_read_req(tGATT_TCB& tcb, tGATT_SRV_LIST_ELEM& el,
uint8_t op_code, uint16_t handle,
- UNUSED_ATTR uint16_t len, uint8_t* p_data) {
+ uint16_t len, uint8_t* p_data) {
size_t buf_len = sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET;
uint16_t offset = 0;
+
+ if (op_code == GATT_REQ_READ_BLOB && len < sizeof(uint16_t)) {
+ /* Error: packet length is too short */
+ LOG(ERROR) << __func__ << ": packet length=" << len
+ << " too short. min=" << sizeof(uint16_t);
+ android_errorWriteWithInfoLog(0x534e4554, "73172115", -1, NULL, 0);
+ gatt_send_error_rsp(tcb, GATT_INVALID_PDU, op_code, 0, false);
+ return;
+ }
+
BT_HDR* p_msg = (BT_HDR*)osi_calloc(buf_len);
if (op_code == GATT_REQ_READ_BLOB) STREAM_TO_UINT16(offset, p_data);
@@ -964,7 +983,7 @@ static void gatts_process_read_req(tGATT_TCB& tcb, tGATT_SRV_LIST_ELEM& el,
if (reason != GATT_SUCCESS) {
osi_free(p_msg);
- /* in theroy BUSY is not possible(should already been checked), protected
+ /* in theory BUSY is not possible(should already been checked), protected
* check */
if (reason != GATT_PENDING && reason != GATT_BUSY)
gatt_send_error_rsp(tcb, reason, op_code, handle, false);
diff --git a/stack/l2cap/l2c_ble.cc b/stack/l2cap/l2c_ble.cc
index 6c7820f66..17ce2d305 100644
--- a/stack/l2cap/l2c_ble.cc
+++ b/stack/l2cap/l2c_ble.cc
@@ -33,6 +33,7 @@
#include "hcimsgs.h"
#include "l2c_int.h"
#include "l2cdefs.h"
+#include "log/log.h"
#include "osi/include/osi.h"
#include "stack_config.h"
@@ -788,6 +789,10 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
break;
case L2CAP_CMD_DISC_REQ:
+ if (p + 4 > p_pkt_end) {
+ android_errorWriteLog(0x534e4554, "74121659");
+ return;
+ }
STREAM_TO_UINT16(lcid, p);
STREAM_TO_UINT16(rcid, p);
diff --git a/stack/l2cap/l2c_fcr.cc b/stack/l2cap/l2c_fcr.cc
index 0e5a84a50..9c2742f56 100644
--- a/stack/l2cap/l2c_fcr.cc
+++ b/stack/l2cap/l2c_fcr.cc
@@ -24,6 +24,7 @@
******************************************************************************/
#include <base/logging.h>
+#include <log/log.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -855,8 +856,24 @@ void l2c_lcc_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) {
p_buf->offset += sizeof(sdu_length);
p_data->offset = 0;
- } else
+ } else {
p_data = p_ccb->ble_sdu;
+ if (p_buf->len > (p_ccb->ble_sdu_length - p_data->len)) {
+ L2CAP_TRACE_ERROR("%s: buffer length=%d too big. max=%d. Dropped",
+ __func__, p_data->len,
+ (p_ccb->ble_sdu_length - p_data->len));
+ android_errorWriteWithInfoLog(0x534e4554, "75298652", -1, NULL, 0);
+ osi_free(p_buf);
+
+ /* Throw away all pending fragments and disconnects */
+ p_ccb->is_first_seg = true;
+ osi_free(p_ccb->ble_sdu);
+ p_ccb->ble_sdu = NULL;
+ p_ccb->ble_sdu_length = 0;
+ l2cu_disconnect_chnl(p_ccb);
+ return;
+ }
+ }
memcpy((uint8_t*)(p_data + 1) + p_data->offset + p_data->len,
(uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
@@ -869,9 +886,6 @@ void l2c_lcc_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) {
p_ccb->ble_sdu_length = 0;
} else if (p_data->len < p_ccb->ble_sdu_length) {
p_ccb->is_first_seg = false;
- } else {
- L2CAP_TRACE_ERROR("%s Length in the SDU messed up", __func__);
- // TODO: reset every thing may be???
}
osi_free(p_buf);
diff --git a/stack/l2cap/l2c_main.cc b/stack/l2cap/l2c_main.cc
index 83d1737bc..7c1ef4837 100644
--- a/stack/l2cap/l2c_main.cc
+++ b/stack/l2cap/l2c_main.cc
@@ -320,8 +320,16 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
switch (cmd_code) {
case L2CAP_CMD_REJECT:
+ if (p + 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(rej_reason, p);
if (rej_reason == L2CAP_CMD_REJ_MTU_EXCEEDED) {
+ if (p + 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(rej_mtu, p);
/* What to do with the MTU reject ? We have negotiated an MTU. For now
*/
@@ -332,6 +340,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
p_lcb->handle, rej_mtu);
}
if (rej_reason == L2CAP_CMD_REJ_INVALID_CID) {
+ if (p + 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(rcid, p);
STREAM_TO_UINT16(lcid, p);
@@ -365,6 +377,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
break;
case L2CAP_CMD_CONN_REQ:
+ if (p + 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(con_info.psm, p);
STREAM_TO_UINT16(rcid, p);
p_rcb = l2cu_find_rcb_by_psm(con_info.psm);
@@ -396,6 +412,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
break;
case L2CAP_CMD_CONN_RSP:
+ if (p + 8 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(con_info.remote_cid, p);
STREAM_TO_UINT16(lcid, p);
STREAM_TO_UINT16(con_info.l2cap_result, p);
@@ -427,6 +447,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
cfg_rej = false;
cfg_rej_len = 0;
+ if (p + 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(lcid, p);
STREAM_TO_UINT16(cfg_info.flags, p);
@@ -437,22 +461,38 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
false;
while (p < p_cfg_end) {
+ if (p + 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT8(cfg_code, p);
STREAM_TO_UINT8(cfg_len, p);
switch (cfg_code & 0x7F) {
case L2CAP_CFG_TYPE_MTU:
cfg_info.mtu_present = true;
+ if (p + 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(cfg_info.mtu, p);
break;
case L2CAP_CFG_TYPE_FLUSH_TOUT:
cfg_info.flush_to_present = true;
+ if (p + 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(cfg_info.flush_to, p);
break;
case L2CAP_CFG_TYPE_QOS:
cfg_info.qos_present = true;
+ if (p + 2 + 5 * 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT8(cfg_info.qos.qos_flags, p);
STREAM_TO_UINT8(cfg_info.qos.service_type, p);
STREAM_TO_UINT32(cfg_info.qos.token_rate, p);
@@ -464,6 +504,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
case L2CAP_CFG_TYPE_FCR:
cfg_info.fcr_present = true;
+ if (p + 3 + 3 * 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT8(cfg_info.fcr.mode, p);
STREAM_TO_UINT8(cfg_info.fcr.tx_win_sz, p);
STREAM_TO_UINT8(cfg_info.fcr.max_transmit, p);
@@ -474,11 +518,19 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
case L2CAP_CFG_TYPE_FCS:
cfg_info.fcs_present = true;
+ if (p + 1 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT8(cfg_info.fcs, p);
break;
case L2CAP_CFG_TYPE_EXT_FLOW:
cfg_info.ext_flow_spec_present = true;
+ if (p + 2 + 2 + 3 * 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT8(cfg_info.ext_flow_spec.id, p);
STREAM_TO_UINT8(cfg_info.ext_flow_spec.stype, p);
STREAM_TO_UINT16(cfg_info.ext_flow_spec.max_sdu_size, p);
@@ -523,6 +575,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
case L2CAP_CMD_CONFIG_RSP:
p_cfg_end = p + cmd_len;
+ if (p + 6 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(lcid, p);
STREAM_TO_UINT16(cfg_info.flags, p);
STREAM_TO_UINT16(cfg_info.result, p);
@@ -532,22 +588,38 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
false;
while (p < p_cfg_end) {
+ if (p + 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT8(cfg_code, p);
STREAM_TO_UINT8(cfg_len, p);
switch (cfg_code & 0x7F) {
case L2CAP_CFG_TYPE_MTU:
cfg_info.mtu_present = true;
+ if (p + 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(cfg_info.mtu, p);
break;
case L2CAP_CFG_TYPE_FLUSH_TOUT:
cfg_info.flush_to_present = true;
+ if (p + 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(cfg_info.flush_to, p);
break;
case L2CAP_CFG_TYPE_QOS:
cfg_info.qos_present = true;
+ if (p + 2 + 5 * 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT8(cfg_info.qos.qos_flags, p);
STREAM_TO_UINT8(cfg_info.qos.service_type, p);
STREAM_TO_UINT32(cfg_info.qos.token_rate, p);
@@ -559,6 +631,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
case L2CAP_CFG_TYPE_FCR:
cfg_info.fcr_present = true;
+ if (p + 3 + 3 * 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT8(cfg_info.fcr.mode, p);
STREAM_TO_UINT8(cfg_info.fcr.tx_win_sz, p);
STREAM_TO_UINT8(cfg_info.fcr.max_transmit, p);
@@ -569,11 +645,19 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
case L2CAP_CFG_TYPE_FCS:
cfg_info.fcs_present = true;
+ if (p + 1 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT8(cfg_info.fcs, p);
break;
case L2CAP_CFG_TYPE_EXT_FLOW:
cfg_info.ext_flow_spec_present = true;
+ if (p + 2 + 2 + 3 * 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT8(cfg_info.ext_flow_spec.id, p);
STREAM_TO_UINT8(cfg_info.ext_flow_spec.stype, p);
STREAM_TO_UINT16(cfg_info.ext_flow_spec.max_sdu_size, p);
@@ -603,6 +687,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
break;
case L2CAP_CMD_DISC_REQ:
+ if (p + 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(lcid, p);
STREAM_TO_UINT16(rcid, p);
@@ -618,6 +706,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
break;
case L2CAP_CMD_DISC_RSP:
+ if (p + 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(rcid, p);
STREAM_TO_UINT16(lcid, p);
@@ -645,6 +737,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
break;
case L2CAP_CMD_INFO_REQ:
+ if (p + 2 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(info_type, p);
l2cu_send_peer_info_rsp(p_lcb, id, info_type);
break;
@@ -656,6 +752,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
p_lcb->w4_info_rsp = false;
}
+ if (p + 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT16(info_type, p);
STREAM_TO_UINT16(result, p);
@@ -663,6 +763,10 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
(result == L2CAP_INFO_RESP_RESULT_SUCCESS)) {
+ if (p + 4 > p_next_cmd) {
+ android_errorWriteLog(0x534e4554, "74202041");
+ return;
+ }
STREAM_TO_UINT32(p_lcb->peer_ext_fea, p);
#if (L2CAP_NUM_FIXED_CHNLS > 0)
diff --git a/stack/pan/pan_main.cc b/stack/pan/pan_main.cc
index d7cd27b07..6a554231f 100644
--- a/stack/pan/pan_main.cc
+++ b/stack/pan/pan_main.cc
@@ -595,12 +595,11 @@ void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src,
if (pan_cb.pan_data_buf_ind_cb)
(*pan_cb.pan_data_buf_ind_cb)(pcb->handle, src, dst, protocol, p_buf,
ext, forward);
- else if (pan_cb.pan_data_ind_cb) {
+ else if (pan_cb.pan_data_ind_cb)
(*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len,
ext, forward);
- osi_free(p_buf);
- }
+ osi_free(p_buf);
return;
}
@@ -625,13 +624,10 @@ void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src,
if (pan_cb.pan_data_buf_ind_cb)
(*pan_cb.pan_data_buf_ind_cb)(pcb->handle, src, dst, protocol, p_buf, ext,
forward);
- else if (pan_cb.pan_data_ind_cb) {
+ else if (pan_cb.pan_data_ind_cb)
(*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len, ext,
forward);
- osi_free(p_buf);
- } else
- osi_free(p_buf);
-
+ osi_free(p_buf);
return;
}
diff --git a/stack/sdp/sdp_discovery.cc b/stack/sdp/sdp_discovery.cc
index 7eea5fda3..bf6f43be7 100644
--- a/stack/sdp/sdp_discovery.cc
+++ b/stack/sdp/sdp_discovery.cc
@@ -332,7 +332,7 @@ static void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
******************************************************************************/
#if (SDP_RAW_DATA_INCLUDED == TRUE)
static void sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) {
- unsigned int cpy_len;
+ unsigned int cpy_len, rem_len;
uint32_t list_len;
uint8_t* p;
uint8_t type;
@@ -357,9 +357,14 @@ static void sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) {
type = *p++;
p = sdpu_get_len_from_type(p, type, &list_len);
}
- if (list_len && list_len < cpy_len) {
+ if (list_len < cpy_len) {
cpy_len = list_len;
}
+ rem_len = SDP_MAX_LIST_BYTE_COUNT - (unsigned int)(p - &p_ccb->rsp_list[0]);
+ if (cpy_len > rem_len) {
+ SDP_TRACE_WARNING("rem_len :%d less than cpy_len:%d", rem_len, cpy_len);
+ cpy_len = rem_len;
+ }
SDP_TRACE_WARNING(
"%s: list_len:%d cpy_len:%d p:%p p_ccb:%p p_db:%p raw_size:%d "
"raw_used:%d raw_data:%p",
@@ -531,6 +536,13 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
#endif
/* If p_reply is NULL, we were called for the initial read */
if (p_reply) {
+ if (p_reply + 4 /* transaction ID and length */ + sizeof(lists_byte_count) >
+ p_reply_end) {
+ android_errorWriteLog(0x534e4554, "79884292");
+ sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE);
+ return;
+ }
+
#if (SDP_DEBUG_RAW == TRUE)
SDP_TRACE_WARNING("ID & len: 0x%02x-%02x-%02x-%02x", p_reply[0], p_reply[1],
p_reply[2], p_reply[3]);
@@ -554,6 +566,13 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
SDP_TRACE_WARNING("list_len: %d, list_byte_count: %d", p_ccb->list_len,
lists_byte_count);
#endif
+
+ if (p_reply + lists_byte_count + 1 /* continuation */ > p_reply_end) {
+ android_errorWriteLog(0x534e4554, "79884292");
+ sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE);
+ return;
+ }
+
if (p_ccb->rsp_list == NULL)
p_ccb->rsp_list = (uint8_t*)osi_malloc(SDP_MAX_LIST_BYTE_COUNT);
memcpy(&p_ccb->rsp_list[p_ccb->list_len], p_reply, lists_byte_count);
diff --git a/stack/sdp/sdp_server.cc b/stack/sdp/sdp_server.cc
index e4ed60a92..d2bbd6c4d 100644
--- a/stack/sdp/sdp_server.cc
+++ b/stack/sdp/sdp_server.cc
@@ -333,9 +333,11 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
/* Extract the record handle */
BE_STREAM_TO_UINT32(rec_handle, p_req);
+ param_len -= sizeof(rec_handle);
/* Get the max list length we can send. Cap it at MTU size minus overhead */
BE_STREAM_TO_UINT16(max_list_len, p_req);
+ param_len -= sizeof(max_list_len);
if (max_list_len > (p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN))
max_list_len = p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN;
@@ -567,6 +569,7 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
if (max_list_len > (p_ccb->rem_mtu_size - SDP_MAX_SERVATTR_RSPHDR_LEN))
max_list_len = p_ccb->rem_mtu_size - SDP_MAX_SERVATTR_RSPHDR_LEN;
+ param_len = static_cast<uint16_t>(p_req_end - p_req);
p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
if ((!p_req) || (!attr_seq.num_attr) ||
diff --git a/stack/smp/p_256_ecc_pp.cc b/stack/smp/p_256_ecc_pp.cc
index b416e1d3f..911dc5498 100644
--- a/stack/smp/p_256_ecc_pp.cc
+++ b/stack/smp/p_256_ecc_pp.cc
@@ -245,3 +245,25 @@ void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n,
multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x, keyLength);
multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength);
}
+
+bool ECC_ValidatePoint(const Point& pt) {
+ const size_t kl = KEY_LENGTH_DWORDS_P256;
+ p_256_init_curve(kl);
+
+ // Ensure y^2 = x^3 + a*x + b (mod p); a = -3
+
+ // y^2 mod p
+ uint32_t y2_mod[kl] = {0};
+ multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y, kl);
+
+ // Right hand side calculation
+ uint32_t rhs[kl] = {0};
+ multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x, kl);
+ uint32_t three[kl] = {0};
+ three[0] = 3;
+ multiprecision_sub_mod(rhs, rhs, three, kl);
+ multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x, kl);
+ multiprecision_add_mod(rhs, rhs, curve_p256.b, kl);
+
+ return multiprecision_compare(rhs, y2_mod, kl) == 0;
+}
diff --git a/stack/smp/p_256_ecc_pp.h b/stack/smp/p_256_ecc_pp.h
index dcc4211dc..b7a8e0066 100644
--- a/stack/smp/p_256_ecc_pp.h
+++ b/stack/smp/p_256_ecc_pp.h
@@ -25,6 +25,7 @@
#pragma once
+#include <cstdbool>
#include "p_256_multprecision.h"
typedef struct {
@@ -55,6 +56,8 @@ typedef struct {
extern elliptic_curve_t curve;
extern elliptic_curve_t curve_p256;
+bool ECC_ValidatePoint(const Point& p);
+
void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, uint32_t keyLength);
#define ECC_PointMult(q, p, n, keyLength) \
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index df9fab9f1..2103776df 100644
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -22,6 +22,7 @@
#include "include/bt_target.h"
#include "stack/btm/btm_int.h"
#include "stack/include/l2c_api.h"
+#include "stack/smp/p_256_ecc_pp.h"
#include "stack/smp/smp_int.h"
#include "utils/include/bt_utils.h"
@@ -655,6 +656,17 @@ void smp_process_pairing_public_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
STREAM_TO_ARRAY(p_cb->peer_publ_key.x, p, BT_OCTET32_LEN);
STREAM_TO_ARRAY(p_cb->peer_publ_key.y, p, BT_OCTET32_LEN);
+
+ Point pt;
+ memcpy(pt.x, p_cb->peer_publ_key.x, BT_OCTET32_LEN);
+ memcpy(pt.y, p_cb->peer_publ_key.y, BT_OCTET32_LEN);
+
+ if (!ECC_ValidatePoint(pt)) {
+ android_errorWriteLog(0x534e4554, "72377774");
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
+ return;
+ }
+
p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY;
smp_wait_for_both_public_keys(p_cb, NULL);
diff --git a/stack/smp/smp_br_main.cc b/stack/smp/smp_br_main.cc
index 260b9c4fd..55405ccfd 100644
--- a/stack/smp/smp_br_main.cc
+++ b/stack/smp/smp_br_main.cc
@@ -19,6 +19,7 @@
#include "bt_target.h"
#include <string.h>
+#include "log/log.h"
#include "smp_int.h"
const char* const smp_br_state_name[SMP_BR_STATE_MAX + 1] = {
@@ -308,6 +309,12 @@ void smp_br_state_machine_event(tSMP_CB* p_cb, tSMP_BR_EVENT event,
return;
}
+ if (p_cb->role > HCI_ROLE_SLAVE) {
+ SMP_TRACE_ERROR("%s: invalid role %d", __func__, p_cb->role);
+ android_errorWriteLog(0x534e4554, "80145946");
+ return;
+ }
+
SMP_TRACE_DEBUG("SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",
(p_cb->role == HCI_ROLE_SLAVE) ? "Slave" : "Master",
smp_get_br_state_name(p_cb->br_state), p_cb->br_state,
diff --git a/stack/smp/smp_main.cc b/stack/smp/smp_main.cc
index 829a5d48f..49e2ece7b 100644
--- a/stack/smp/smp_main.cc
+++ b/stack/smp/smp_main.cc
@@ -18,6 +18,7 @@
#include "bt_target.h"
+#include <cutils/log.h>
#include <string.h>
#include "smp_int.h"
@@ -954,6 +955,13 @@ void smp_sm_event(tSMP_CB* p_cb, tSMP_EVENT event, void* p_data) {
uint8_t curr_state = p_cb->state;
tSMP_SM_TBL state_table;
uint8_t action, entry, i;
+
+ if (p_cb->role >= 2) {
+ SMP_TRACE_DEBUG("Invalid role: %d", p_cb->role);
+ android_errorWriteLog(0x534e4554, "74121126");
+ return;
+ }
+
tSMP_ENTRY_TBL entry_table = smp_entry_table[p_cb->role];
SMP_TRACE_EVENT("main smp_sm_event");