HearingAidAudioSource implementation am: be754da679
am: e9dcaa3d80
Change-Id: I305f5dd1175fcb68f1f76f9932ac4791615a48fe
diff --git a/bta/pan/bta_pan_act.cc b/bta/pan/bta_pan_act.cc
index bbcd183..75d5e94 100644
--- a/bta/pan/bta_pan_act.cc
+++ b/bta/pan/bta_pan_act.cc
@@ -174,6 +174,11 @@
tBTA_PAN_SCB* p_scb;
BT_HDR* p_new_buf;
+ 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 >
@@ -181,7 +186,6 @@
android_errorWriteLog(0x534e4554, "63146237");
APPL_TRACE_ERROR("%s: received buffer length too large: %d", __func__,
p_buf->len);
- osi_free(p_buf);
return;
}
p_new_buf = (BT_HDR*)osi_malloc(PAN_BUF_SIZE);
@@ -189,7 +193,6 @@
(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);
- osi_free(p_buf);
} else {
p_new_buf = p_buf;
}
@@ -200,12 +203,6 @@
((tBTA_PAN_DATA_PARAMS*)p_new_buf)->ext = ext;
((tBTA_PAN_DATA_PARAMS*)p_new_buf)->forward = forward;
- p_scb = bta_pan_scb_by_handle(handle);
- if (p_scb == NULL) {
- osi_free(p_new_buf);
- return;
- }
-
fixed_queue_enqueue(p_scb->data_queue, p_new_buf);
BT_HDR* p_event = (BT_HDR*)osi_malloc(sizeof(BT_HDR));
p_event->layer_specific = handle;
diff --git a/osi/src/alarm.cc b/osi/src/alarm.cc
index 163a54e..83a661d 100644
--- a/osi/src/alarm.cc
+++ b/osi/src/alarm.cc
@@ -71,7 +71,6 @@
size_t rescheduled_count;
size_t total_updates;
period_ms_t last_update_ms;
- stat_t callback_execution;
stat_t overdue_scheduling;
stat_t premature_scheduling;
} alarm_stats_t;
@@ -155,8 +154,7 @@
static void callback_dispatch(void* context);
static bool timer_create_internal(const clockid_t clock_id, timer_t* timer);
static void update_scheduling_stats(alarm_stats_t* stats, period_ms_t now_ms,
- period_ms_t deadline_ms,
- period_ms_t execution_delta_ms);
+ period_ms_t deadline_ms);
// Registers |queue| for processing alarm callbacks on |thread|.
// |queue| may not be NULL. |thread| may not be NULL.
static void alarm_register_processing_queue(fixed_queue_t* queue,
@@ -584,14 +582,12 @@
std::lock_guard<std::recursive_mutex> cb_lock(*alarm->callback_mutex);
lock.unlock();
- period_ms_t t0 = now();
- callback(data);
- period_ms_t t1 = now();
-
// Update the statistics
- CHECK(t1 >= t0);
- period_ms_t delta = t1 - t0;
- update_scheduling_stats(&alarm->stats, t0, deadline, delta);
+ update_scheduling_stats(&alarm->stats, now(), deadline);
+
+ // NOTE: Do NOT access "alarm" after the callback, as a safety precaution
+ // in case the callback itself deleted the alarm.
+ callback(data);
}
static void alarm_ready_mloop(alarm_t* alarm) {
@@ -697,13 +693,10 @@
}
static void update_scheduling_stats(alarm_stats_t* stats, period_ms_t now_ms,
- period_ms_t deadline_ms,
- period_ms_t execution_delta_ms) {
+ period_ms_t deadline_ms) {
stats->total_updates++;
stats->last_update_ms = now_ms;
- update_stat(&stats->callback_execution, execution_delta_ms);
-
if (deadline_ms < now_ms) {
// Overdue scheduling
period_ms_t delta_ms = now_ms - deadline_ms;
@@ -750,7 +743,7 @@
dprintf(fd, "%-51s: %zu / %zu / %zu / %zu\n",
" Action counts (sched/resched/exec/cancel)",
stats->scheduled_count, stats->rescheduled_count,
- stats->callback_execution.count, stats->canceled_count);
+ stats->total_updates, stats->canceled_count);
dprintf(fd, "%-51s: %zu / %zu\n",
" Deviation counts (overdue/premature)",
@@ -762,9 +755,6 @@
(unsigned long long)alarm->period,
(long long)(alarm->deadline - just_now));
- dump_stat(fd, &stats->callback_execution,
- " Callback execution time in ms (total/max/avg)");
-
dump_stat(fd, &stats->overdue_scheduling,
" Overdue scheduling time in ms (total/max/avg)");
diff --git a/osi/src/config.cc b/osi/src/config.cc
index 18360bf..d4ed2e6 100644
--- a/osi/src/config.cc
+++ b/osi/src/config.cc
@@ -17,6 +17,7 @@
******************************************************************************/
#include "osi/include/config.h"
+#include "log/log.h"
#include <base/files/file_path.h>
#include <base/logging.h>
@@ -170,14 +171,23 @@
sec = std::prev(config->sections.end());
}
+ std::string value_no_newline;
+ size_t newline_position = value.find("\n");
+ if (newline_position != std::string::npos) {
+ android_errorWriteLog(0x534e4554, "70808273");
+ value_no_newline = value.substr(0, newline_position);
+ } else {
+ value_no_newline = value;
+ }
+
for (entry_t& entry : sec->entries) {
if (entry.key == key) {
- entry.value = value;
+ entry.value = value_no_newline;
return;
}
}
- sec->entries.emplace_back(entry_t{.key = key, .value = value});
+ sec->entries.emplace_back(entry_t{.key = key, .value = value_no_newline});
}
bool config_remove_section(config_t* config, const std::string& section) {
diff --git a/stack/avrc/avrc_pars_ct.cc b/stack/avrc/avrc_pars_ct.cc
index d48b721..7c30642 100644
--- a/stack/avrc/avrc_pars_ct.cc
+++ b/stack/avrc/avrc_pars_ct.cc
@@ -22,6 +22,7 @@
#include "avrc_int.h"
#include "bt_common.h"
#include "bt_utils.h"
+#include "log/log.h"
#include "osi/include/osi.h"
/*****************************************************************************
@@ -457,6 +458,12 @@
BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p);
AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
p_result->list_app_attr.num_attr);
+
+ if (p_result->list_app_attr.num_attr > AVRC_MAX_APP_ATTR_SIZE) {
+ android_errorWriteLog(0x534e4554, "63146237");
+ p_result->list_app_attr.num_attr = AVRC_MAX_APP_ATTR_SIZE;
+ }
+
for (int xx = 0; xx < p_result->list_app_attr.num_attr; xx++) {
BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx], p);
}
@@ -485,6 +492,12 @@
p_result->get_cur_app_val.num_val * sizeof(tAVRC_APP_SETTING));
AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
p_result->get_cur_app_val.num_val);
+
+ if (p_result->get_cur_app_val.num_val > AVRC_MAX_APP_ATTR_SIZE) {
+ android_errorWriteLog(0x534e4554, "63146237");
+ p_result->get_cur_app_val.num_val = AVRC_MAX_APP_ATTR_SIZE;
+ }
+
for (int xx = 0; xx < p_result->get_cur_app_val.num_val; xx++) {
BE_STREAM_TO_UINT8(app_sett[xx].attr_id, p);
BE_STREAM_TO_UINT8(app_sett[xx].attr_val, p);
@@ -493,7 +506,6 @@
} break;
case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: {
- tAVRC_APP_SETTING_TEXT* p_setting_text;
uint8_t num_attrs;
if (len == 0) {
@@ -501,10 +513,14 @@
break;
}
BE_STREAM_TO_UINT8(num_attrs, p);
+ if (num_attrs > AVRC_MAX_APP_ATTR_SIZE) {
+ num_attrs = AVRC_MAX_APP_ATTR_SIZE;
+ }
AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
p_result->get_app_attr_txt.num_attr);
p_result->get_app_attr_txt.num_attr = num_attrs;
- p_setting_text = (tAVRC_APP_SETTING_TEXT*)osi_malloc(
+
+ p_result->get_app_attr_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_malloc(
num_attrs * sizeof(tAVRC_APP_SETTING_TEXT));
for (int xx = 0; xx < num_attrs; xx++) {
BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].attr_id, p);
@@ -524,7 +540,6 @@
} break;
case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: {
- tAVRC_APP_SETTING_TEXT* p_setting_text;
uint8_t num_vals;
if (len == 0) {
@@ -532,11 +547,14 @@
break;
}
BE_STREAM_TO_UINT8(num_vals, p);
+ if (num_vals > AVRC_MAX_APP_ATTR_SIZE) {
+ num_vals = AVRC_MAX_APP_ATTR_SIZE;
+ }
p_result->get_app_val_txt.num_attr = num_vals;
AVRC_TRACE_DEBUG("%s value count = %d ", __func__,
p_result->get_app_val_txt.num_attr);
- p_setting_text = (tAVRC_APP_SETTING_TEXT*)osi_malloc(
+ p_result->get_app_val_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_malloc(
num_vals * sizeof(tAVRC_APP_SETTING_TEXT));
for (int i = 0; i < num_vals; i++) {
BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].attr_id, p);
diff --git a/stack/avrc/avrc_pars_tg.cc b/stack/avrc/avrc_pars_tg.cc
index 871dddf..c0504ee 100644
--- a/stack/avrc/avrc_pars_tg.cc
+++ b/stack/avrc/avrc_pars_tg.cc
@@ -21,6 +21,7 @@
#include "avrc_defs.h"
#include "avrc_int.h"
#include "bt_common.h"
+#include "log/log.h"
/*****************************************************************************
* Global data
@@ -157,6 +158,12 @@
status = AVRC_STS_INTERNAL_ERR;
break;
}
+
+ if (p_result->get_cur_app_val.num_attr > AVRC_MAX_APP_ATTR_SIZE) {
+ android_errorWriteLog(0x534e4554, "63146237");
+ p_result->get_cur_app_val.num_attr = AVRC_MAX_APP_ATTR_SIZE;
+ }
+
p_u8 = p_result->get_cur_app_val.attrs;
for (xx = 0, yy = 0; xx < p_result->get_cur_app_val.num_attr; xx++) {
/* only report the valid player app attributes */
@@ -212,6 +219,11 @@
p_result->get_app_val_txt.num_val)
status = AVRC_STS_INTERNAL_ERR;
else {
+ if (p_result->get_app_val_txt.num_val > AVRC_MAX_APP_ATTR_SIZE) {
+ android_errorWriteLog(0x534e4554, "63146237");
+ p_result->get_app_val_txt.num_val = AVRC_MAX_APP_ATTR_SIZE;
+ }
+
p_u8 = p_result->get_app_val_txt.vals;
for (xx = 0; xx < p_result->get_app_val_txt.num_val; xx++) {
p_u8[xx] = *p++;
@@ -484,8 +496,11 @@
BE_STREAM_TO_UINT16(p_result->search.string.str_len, p);
p_result->search.string.p_str = p_buf;
if (p_buf) {
- if (buf_len > p_result->search.string.str_len)
- buf_len = p_result->search.string.str_len;
+ if (p_result->search.string.str_len > buf_len) {
+ p_result->search.string.str_len = buf_len;
+ } else {
+ android_errorWriteLog(0x534e4554, "63146237");
+ }
BE_STREAM_TO_ARRAY(p, p_buf, p_result->search.string.str_len);
} else {
status = AVRC_STS_INTERNAL_ERR;
diff --git a/stack/bnep/bnep_main.cc b/stack/bnep/bnep_main.cc
index e3b8c7f..5dcb827 100644
--- a/stack/bnep/bnep_main.cc
+++ b/stack/bnep/bnep_main.cc
@@ -34,6 +34,7 @@
#include "l2c_api.h"
#include "l2cdefs.h"
+#include "log/log.h"
#include "btm_api.h"
#include "btu.h"
@@ -445,6 +446,12 @@
type = *p++;
extension_present = type >> 7;
type &= 0x7f;
+ if (type >= sizeof(bnep_frame_hdr_sizes) / sizeof(bnep_frame_hdr_sizes[0])) {
+ BNEP_TRACE_EVENT("BNEP - rcvd frame, bad type: 0x%02x", type);
+ android_errorWriteLog(0x534e4554, "68818034");
+ osi_free(p_buf);
+ return;
+ }
if ((rem_len <= bnep_frame_hdr_sizes[type]) || (rem_len > BNEP_MTU_SIZE)) {
BNEP_TRACE_EVENT("BNEP - rcvd frame, bad len: %d type: 0x%02x", p_buf->len,
type);
@@ -473,18 +480,20 @@
org_len = rem_len;
new_len = 0;
do {
+ if (org_len < 2) break;
ext = *p++;
length = *p++;
p += length;
+ new_len = (length + 2);
+ if (new_len > org_len) break;
+
if ((!(ext & 0x7F)) && (*p > BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG))
bnep_send_command_not_understood(p_bcb, *p);
- new_len += (length + 2);
-
- if (new_len > org_len) break;
-
+ org_len -= new_len;
} while (ext & 0x80);
+ android_errorWriteLog(0x534e4554, "67863755");
}
osi_free(p_buf);
@@ -529,6 +538,8 @@
} else {
while (extension_present && p && rem_len) {
ext_type = *p++;
+ rem_len--;
+ android_errorWriteLog(0x534e4554, "69271284");
extension_present = ext_type >> 7;
ext_type &= 0x7F;
@@ -595,6 +606,7 @@
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/bnep/bnep_utils.cc b/stack/bnep/bnep_utils.cc
index 28fbcb4..48fd5d1 100644
--- a/stack/bnep/bnep_utils.cc
+++ b/stack/bnep/bnep_utils.cc
@@ -22,6 +22,8 @@
*
******************************************************************************/
+#include <cutils/log.h>
+
#include <stdio.h>
#include <string.h>
#include "bnep_int.h"
@@ -760,6 +762,13 @@
break;
case BNEP_SETUP_CONNECTION_REQUEST_MSG:
+ if (*rem_len < 1) {
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_SETUP_CONNECTION_REQUEST_MSG with bad length",
+ __func__);
+ android_errorWriteLog(0x534e4554, "69177292");
+ goto bad_packet_length;
+ }
len = *p++;
if (*rem_len < ((2 * len) + 1)) {
BNEP_TRACE_ERROR(
@@ -785,6 +794,13 @@
break;
case BNEP_FILTER_NET_TYPE_SET_MSG:
+ if (*rem_len < 2) {
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_FILTER_NET_TYPE_SET_MSG with bad length",
+ __func__);
+ android_errorWriteLog(0x534e4554, "69177292");
+ goto bad_packet_length;
+ }
BE_STREAM_TO_UINT16(len, p);
if (*rem_len < (len + 2)) {
BNEP_TRACE_ERROR(
@@ -810,6 +826,13 @@
break;
case BNEP_FILTER_MULTI_ADDR_SET_MSG:
+ if (*rem_len < 2) {
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_FILTER_MULTI_ADDR_SET_MSG with bad length",
+ __func__);
+ android_errorWriteLog(0x534e4554, "69177292");
+ goto bad_packet_length;
+ }
BE_STREAM_TO_UINT16(len, p);
if (*rem_len < (len + 2)) {
BNEP_TRACE_ERROR(
diff --git a/stack/btu/btu_init.cc b/stack/btu/btu_init.cc
index 7920e0f..b2016da 100644
--- a/stack/btu/btu_init.cc
+++ b/stack/btu/btu_init.cc
@@ -89,6 +89,8 @@
/* Free the mandatory core stack components */
l2c_free();
+ sdp_free();
+
gatt_free();
}
diff --git a/stack/sdp/sdp_discovery.cc b/stack/sdp/sdp_discovery.cc
index 20a00c2..c8521b1 100644
--- a/stack/sdp/sdp_discovery.cc
+++ b/stack/sdp/sdp_discovery.cc
@@ -33,6 +33,7 @@
#include "hcidefs.h"
#include "hcimsgs.h"
#include "l2cdefs.h"
+#include "log/log.h"
#include "sdp_api.h"
#include "sdpint.h"
@@ -45,9 +46,12 @@
/******************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
/******************************************************************************/
-static void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply);
-static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply);
-static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply);
+static void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+ uint8_t* p_reply_end);
+static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+ uint8_t* p_reply_end);
+static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+ uint8_t* p_reply_end);
static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end);
static tSDP_DISC_REC* add_record(tSDP_DISCOVERY_DB* p_db,
const RawAddress& p_bda);
@@ -190,7 +194,7 @@
if (p_ccb->is_attr_search) {
p_ccb->disc_state = SDP_DISC_WAIT_SEARCH_ATTR;
- process_service_search_attr_rsp(p_ccb, NULL);
+ process_service_search_attr_rsp(p_ccb, NULL, NULL);
} else {
/* First step is to get a list of the handles from the server. */
/* We are not searching for a specific attribute, so we will */
@@ -224,6 +228,7 @@
/* Got a reply!! Check what we got back */
p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+ uint8_t* p_end = p + p_msg->len;
BE_STREAM_TO_UINT8(rsp_pdu, p);
@@ -232,21 +237,21 @@
switch (rsp_pdu) {
case SDP_PDU_SERVICE_SEARCH_RSP:
if (p_ccb->disc_state == SDP_DISC_WAIT_HANDLES) {
- process_service_search_rsp(p_ccb, p);
+ process_service_search_rsp(p_ccb, p, p_end);
invalid_pdu = false;
}
break;
case SDP_PDU_SERVICE_ATTR_RSP:
if (p_ccb->disc_state == SDP_DISC_WAIT_ATTR) {
- process_service_attr_rsp(p_ccb, p);
+ process_service_attr_rsp(p_ccb, p, p_end);
invalid_pdu = false;
}
break;
case SDP_PDU_SERVICE_SEARCH_ATTR_RSP:
if (p_ccb->disc_state == SDP_DISC_WAIT_SEARCH_ATTR) {
- process_service_search_attr_rsp(p_ccb, p);
+ process_service_search_attr_rsp(p_ccb, p, p_end);
invalid_pdu = false;
}
break;
@@ -269,7 +274,8 @@
* Returns void
*
******************************************************************************/
-static void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply) {
+static void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+ uint8_t* p_reply_end) {
uint16_t xx;
uint16_t total, cur_handles, orig;
uint8_t cont_len;
@@ -301,6 +307,11 @@
sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
return;
}
+ if (p_reply + cont_len > p_reply_end) {
+ android_errorWriteLog(0x534e4554, "68161546");
+ sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
+ return;
+ }
/* stay in the same state */
sdp_snd_service_search_req(p_ccb, cont_len, p_reply);
} else {
@@ -308,7 +319,7 @@
p_ccb->disc_state = SDP_DISC_WAIT_ATTR;
/* Kick off the first attribute request */
- process_service_attr_rsp(p_ccb, NULL);
+ process_service_attr_rsp(p_ccb, NULL, NULL);
}
}
@@ -378,7 +389,8 @@
* Returns void
*
******************************************************************************/
-static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply) {
+static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+ uint8_t* p_reply_end) {
uint8_t *p_start, *p_param_len;
uint16_t param_len, list_byte_count;
bool cont_request_needed = false;
@@ -477,8 +489,12 @@
/* Was this a continuation request ? */
if (cont_request_needed) {
- memcpy(p, p_reply, *p_reply + 1);
- p += *p_reply + 1;
+ if ((p_reply + *p_reply + 1) <= p_reply_end) {
+ memcpy(p, p_reply, *p_reply + 1);
+ p += *p_reply + 1;
+ } else {
+ android_errorWriteLog(0x534e4554, "68161546");
+ }
} else
UINT8_TO_BE_STREAM(p, 0);
@@ -510,7 +526,8 @@
* Returns void
*
******************************************************************************/
-static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply) {
+static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
+ uint8_t* p_reply_end) {
uint8_t *p, *p_start, *p_end, *p_param_len;
uint8_t type;
uint32_t seq_len;
@@ -607,8 +624,12 @@
/* No continuation for first request */
if (p_reply) {
- memcpy(p, p_reply, *p_reply + 1);
- p += *p_reply + 1;
+ if ((p_reply + *p_reply + 1) <= p_reply_end) {
+ memcpy(p, p_reply, *p_reply + 1);
+ p += *p_reply + 1;
+ } else {
+ android_errorWriteLog(0x534e4554, "68161546");
+ }
} else
UINT8_TO_BE_STREAM(p, 0);
diff --git a/stack/sdp/sdp_main.cc b/stack/sdp/sdp_main.cc
index 32c9a85..2ee310b 100644
--- a/stack/sdp/sdp_main.cc
+++ b/stack/sdp/sdp_main.cc
@@ -73,6 +73,10 @@
/* Clears all structures and local SDP database (if Server is enabled) */
memset(&sdp_cb, 0, sizeof(tSDP_CB));
+ for (int i = 0; i < SDP_MAX_CONNECTIONS; i++) {
+ sdp_cb.ccb[i].sdp_conn_timer = alarm_new("sdp.sdp_conn_timer");
+ }
+
/* Initialize the L2CAP configuration. We only care about MTU and flush */
sdp_cb.l2cap_my_cfg.mtu_present = true;
sdp_cb.l2cap_my_cfg.mtu = SDP_MTU_SIZE;
@@ -122,6 +126,13 @@
}
}
+void sdp_free(void) {
+ for (int i = 0; i < SDP_MAX_CONNECTIONS; i++) {
+ alarm_free(sdp_cb.ccb[i].sdp_conn_timer);
+ sdp_cb.ccb[i].sdp_conn_timer = NULL;
+ }
+}
+
#if (SDP_DEBUG == TRUE)
/*******************************************************************************
*
diff --git a/stack/sdp/sdp_server.cc b/stack/sdp/sdp_server.cc
index 51b0933..733f1a3 100644
--- a/stack/sdp/sdp_server.cc
+++ b/stack/sdp/sdp_server.cc
@@ -23,6 +23,7 @@
*
******************************************************************************/
+#include <cutils/log.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -52,7 +53,7 @@
/******************************************************************************/
static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
uint16_t param_len, uint8_t* p_req,
- UNUSED_ATTR uint8_t* p_req_end);
+ uint8_t* p_req_end);
static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
uint16_t param_len, uint8_t* p_req,
@@ -60,7 +61,7 @@
static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
uint16_t param_len, uint8_t* p_req,
- UNUSED_ATTR uint8_t* p_req_end);
+ uint8_t* p_req_end);
/******************************************************************************/
/* E R R O R T E X T S T R I N G S */
@@ -121,11 +122,25 @@
alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
sdp_conn_timer_timeout, p_ccb);
+ if (p_req + sizeof(pdu_id) + sizeof(trans_num) > p_req_end) {
+ android_errorWriteLog(0x534e4554, "69384124");
+ trans_num = 0;
+ sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
+ SDP_TEXT_BAD_HEADER);
+ }
+
/* The first byte in the message is the pdu type */
pdu_id = *p_req++;
/* Extract the transaction number and parameter length */
BE_STREAM_TO_UINT16(trans_num, p_req);
+
+ if (p_req + sizeof(param_len) > p_req_end) {
+ android_errorWriteLog(0x534e4554, "69384124");
+ sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
+ SDP_TEXT_BAD_HEADER);
+ }
+
BE_STREAM_TO_UINT16(param_len, p_req);
if ((p_req + param_len) != p_req_end) {
@@ -169,7 +184,7 @@
******************************************************************************/
static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
uint16_t param_len, uint8_t* p_req,
- UNUSED_ATTR uint8_t* p_req_end) {
+ uint8_t* p_req_end) {
uint16_t max_replies, cur_handles, rem_handles, cont_offset;
tSDP_UUID_SEQ uid_seq;
uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
@@ -187,15 +202,15 @@
}
/* Get the max replies we can send. Cap it at our max anyways. */
- BE_STREAM_TO_UINT16(max_replies, p_req);
-
- if (max_replies > SDP_MAX_RECORDS) max_replies = SDP_MAX_RECORDS;
-
- if ((!p_req) || (p_req > p_req_end)) {
+ if (p_req + sizeof(max_replies) + sizeof(uint8_t) > p_req_end) {
+ android_errorWriteLog(0x534e4554, "69384124");
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
SDP_TEXT_BAD_MAX_RECORDS_LIST);
return;
}
+ BE_STREAM_TO_UINT16(max_replies, p_req);
+
+ if (max_replies > SDP_MAX_RECORDS) max_replies = SDP_MAX_RECORDS;
/* Get a list of handles that match the UUIDs given to us */
for (num_rsp_handles = 0; num_rsp_handles < max_replies;) {
@@ -209,7 +224,8 @@
/* Check if this is a continuation request */
if (*p_req) {
- if (*p_req++ != SDP_CONTINUATION_LEN || (p_req >= p_req_end)) {
+ if (*p_req++ != SDP_CONTINUATION_LEN ||
+ (p_req + sizeof(cont_offset) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
SDP_TEXT_BAD_CONT_LEN);
return;
@@ -308,15 +324,16 @@
bool is_cont = false;
uint16_t attr_len;
- /* Extract the record handle */
- BE_STREAM_TO_UINT32(rec_handle, p_req);
-
- if (p_req > p_req_end) {
+ if (p_req + sizeof(rec_handle) + sizeof(max_list_len) > p_req_end) {
+ android_errorWriteLog(0x534e4554, "69384124");
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_SERV_REC_HDL,
SDP_TEXT_BAD_HANDLE);
return;
}
+ /* Extract the record handle */
+ BE_STREAM_TO_UINT32(rec_handle, p_req);
+
/* Get the max list length we can send. Cap it at MTU size minus overhead */
BE_STREAM_TO_UINT16(max_list_len, p_req);
@@ -325,7 +342,8 @@
p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
- if ((!p_req) || (!attr_seq.num_attr) || (p_req > p_req_end)) {
+ if ((!p_req) || (!attr_seq.num_attr) ||
+ (p_req + sizeof(uint8_t) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
SDP_TEXT_BAD_ATTR_LIST);
return;
@@ -341,13 +359,20 @@
return;
}
+ if (max_list_len < 4) {
+ sdpu_build_n_send_error(p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL);
+ android_errorWriteLog(0x534e4554, "68776054");
+ return;
+ }
+
/* Free and reallocate buffer */
osi_free(p_ccb->rsp_list);
p_ccb->rsp_list = (uint8_t*)osi_malloc(max_list_len);
/* Check if this is a continuation request */
if (*p_req) {
- if (*p_req++ != SDP_CONTINUATION_LEN) {
+ if (*p_req++ != SDP_CONTINUATION_LEN ||
+ (p_req + sizeof(cont_offset) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
SDP_TEXT_BAD_CONT_LEN);
return;
@@ -512,7 +537,7 @@
******************************************************************************/
static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
uint16_t param_len, uint8_t* p_req,
- UNUSED_ATTR uint8_t* p_req_end) {
+ uint8_t* p_req_end) {
uint16_t max_list_len;
int16_t rem_len;
uint16_t len_to_send, cont_offset;
@@ -529,7 +554,8 @@
/* Extract the UUID sequence to search for */
p_req = sdpu_extract_uid_seq(p_req, param_len, &uid_seq);
- if ((!p_req) || (!uid_seq.num_uids)) {
+ if ((!p_req) || (!uid_seq.num_uids) ||
+ (p_req + sizeof(uint16_t) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
SDP_TEXT_BAD_UUID_LIST);
return;
@@ -543,7 +569,8 @@
p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
- if ((!p_req) || (!attr_seq.num_attr)) {
+ if ((!p_req) || (!attr_seq.num_attr) ||
+ (p_req + sizeof(uint8_t) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
SDP_TEXT_BAD_ATTR_LIST);
return;
@@ -551,13 +578,20 @@
memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ));
+ if (max_list_len < 4) {
+ sdpu_build_n_send_error(p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL);
+ android_errorWriteLog(0x534e4554, "68817966");
+ return;
+ }
+
/* Free and reallocate buffer */
osi_free(p_ccb->rsp_list);
p_ccb->rsp_list = (uint8_t*)osi_malloc(max_list_len);
/* Check if this is a continuation request */
if (*p_req) {
- if (*p_req++ != SDP_CONTINUATION_LEN) {
+ if (*p_req++ != SDP_CONTINUATION_LEN ||
+ (p_req + sizeof(uint16_t) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
SDP_TEXT_BAD_CONT_LEN);
return;
diff --git a/stack/sdp/sdp_utils.cc b/stack/sdp/sdp_utils.cc
index 5529a46..c57a499 100644
--- a/stack/sdp/sdp_utils.cc
+++ b/stack/sdp/sdp_utils.cc
@@ -109,8 +109,9 @@
/* Look through each connection control block for a free one */
for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
if (p_ccb->con_state == SDP_STATE_IDLE) {
+ alarm_t* alarm = p_ccb->sdp_conn_timer;
memset(p_ccb, 0, sizeof(tCONN_CB));
- p_ccb->sdp_conn_timer = alarm_new("sdp.sdp_conn_timer");
+ p_ccb->sdp_conn_timer = alarm;
return (p_ccb);
}
}
@@ -130,8 +131,7 @@
******************************************************************************/
void sdpu_release_ccb(tCONN_CB* p_ccb) {
/* Ensure timer is stopped */
- alarm_free(p_ccb->sdp_conn_timer);
- p_ccb->sdp_conn_timer = NULL;
+ alarm_cancel(p_ccb->sdp_conn_timer);
/* Drop any response pointer we may be holding */
p_ccb->con_state = SDP_STATE_IDLE;
@@ -333,6 +333,8 @@
p_seq->num_uids = 0;
/* A UID sequence is composed of a bunch of UIDs. */
+ if (sizeof(descr) > param_len) return (NULL);
+ param_len -= sizeof(descr);
BE_STREAM_TO_UINT8(descr, p);
type = descr >> 3;
@@ -351,19 +353,25 @@
seq_len = 16;
break;
case SIZE_IN_NEXT_BYTE:
+ if (sizeof(uint8_t) > param_len) return (NULL);
+ param_len -= sizeof(uint8_t);
BE_STREAM_TO_UINT8(seq_len, p);
break;
case SIZE_IN_NEXT_WORD:
+ if (sizeof(uint16_t) > param_len) return (NULL);
+ param_len -= sizeof(uint16_t);
BE_STREAM_TO_UINT16(seq_len, p);
break;
case SIZE_IN_NEXT_LONG:
+ if (sizeof(uint32_t) > param_len) return (NULL);
+ param_len -= sizeof(uint32_t);
BE_STREAM_TO_UINT32(seq_len, p);
break;
default:
return (NULL);
}
- if (seq_len >= param_len) return (NULL);
+ if (seq_len > param_len) return (NULL);
p_seq_end = p + seq_len;
@@ -386,12 +394,15 @@
uuid_len = 16;
break;
case SIZE_IN_NEXT_BYTE:
+ if (p + sizeof(uint8_t) > p_seq_end) return NULL;
BE_STREAM_TO_UINT8(uuid_len, p);
break;
case SIZE_IN_NEXT_WORD:
+ if (p + sizeof(uint16_t) > p_seq_end) return NULL;
BE_STREAM_TO_UINT16(uuid_len, p);
break;
case SIZE_IN_NEXT_LONG:
+ if (p + sizeof(uint32_t) > p_seq_end) return NULL;
BE_STREAM_TO_UINT32(uuid_len, p);
break;
default:
@@ -399,7 +410,8 @@
}
/* If UUID length is valid, copy it across */
- if ((uuid_len == 2) || (uuid_len == 4) || (uuid_len == 16)) {
+ if (((uuid_len == 2) || (uuid_len == 4) || (uuid_len == 16)) &&
+ (p + uuid_len <= p_seq_end)) {
p_seq->uuid_entry[p_seq->num_uids].len = (uint16_t)uuid_len;
BE_STREAM_TO_ARRAY(p, p_seq->uuid_entry[p_seq->num_uids].value,
(int)uuid_len);
@@ -436,30 +448,38 @@
p_seq->num_attr = 0;
/* Get attribute sequence info */
+ if (param_len < sizeof(descr)) return NULL;
+ param_len -= sizeof(descr);
BE_STREAM_TO_UINT8(descr, p);
type = descr >> 3;
size = descr & 7;
- if (type != DATA_ELE_SEQ_DESC_TYPE) return (p);
+ if (type != DATA_ELE_SEQ_DESC_TYPE) return NULL;
switch (size) {
case SIZE_IN_NEXT_BYTE:
+ if (param_len < sizeof(uint8_t)) return NULL;
+ param_len -= sizeof(uint8_t);
BE_STREAM_TO_UINT8(list_len, p);
break;
case SIZE_IN_NEXT_WORD:
+ if (param_len < sizeof(uint16_t)) return NULL;
+ param_len -= sizeof(uint16_t);
BE_STREAM_TO_UINT16(list_len, p);
break;
case SIZE_IN_NEXT_LONG:
+ if (param_len < sizeof(uint32_t)) return NULL;
+ param_len -= sizeof(uint32_t);
BE_STREAM_TO_UINT32(list_len, p);
break;
default:
- return (p);
+ return NULL;
}
- if (list_len > param_len) return (p);
+ if (list_len > param_len) return NULL;
p_end_list = p + list_len;
@@ -469,7 +489,7 @@
type = descr >> 3;
size = descr & 7;
- if (type != UINT_DESC_TYPE) return (p);
+ if (type != UINT_DESC_TYPE) return NULL;
switch (size) {
case SIZE_TWO_BYTES:
@@ -479,20 +499,24 @@
attr_len = 4;
break;
case SIZE_IN_NEXT_BYTE:
+ if (p + sizeof(uint8_t) > p_end_list) return NULL;
BE_STREAM_TO_UINT8(attr_len, p);
break;
case SIZE_IN_NEXT_WORD:
+ if (p + sizeof(uint16_t) > p_end_list) return NULL;
BE_STREAM_TO_UINT16(attr_len, p);
break;
case SIZE_IN_NEXT_LONG:
+ if (p + sizeof(uint32_t) > p_end_list) return NULL;
BE_STREAM_TO_UINT32(attr_len, p);
break;
default:
- return (NULL);
+ return NULL;
break;
}
/* Attribute length must be 2-bytes or 4-bytes for a paired entry. */
+ if (p + attr_len > p_end_list) return NULL;
if (attr_len == 2) {
BE_STREAM_TO_UINT16(p_seq->attr_entry[p_seq->num_attr].start, p);
p_seq->attr_entry[p_seq->num_attr].end =
diff --git a/stack/sdp/sdpint.h b/stack/sdp/sdpint.h
index 612a762..0d44c9d 100644
--- a/stack/sdp/sdpint.h
+++ b/stack/sdp/sdpint.h
@@ -223,6 +223,7 @@
/* Functions provided by sdp_main.cc */
extern void sdp_init(void);
+extern void sdp_free(void);
extern void sdp_disconnect(tCONN_CB* p_ccb, uint16_t reason);
#if (SDP_DEBUG == TRUE)