summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavlin Radoslavov <pavlin@google.com>2017-07-06 16:51:35 -0700
committerAndreas Blaesius <skate4life@gmx.de>2017-09-17 22:11:29 +0200
commitbee52c2d82153fa6459b31922c332b80bcc8a5ee (patch)
tree9c9a34ddbcf8ff9dff6830f9f6ac1d74a8cb6e43
parent33427d54f31adaf5b9c697f5ce642fda1dc01946 (diff)
downloadandroid_system_bt-bee52c2d82153fa6459b31922c332b80bcc8a5ee.tar.gz
android_system_bt-bee52c2d82153fa6459b31922c332b80bcc8a5ee.tar.bz2
android_system_bt-bee52c2d82153fa6459b31922c332b80bcc8a5ee.zip
Add missing packet length checks while parsing BNEP control packets
Bug: 63146237 Test: External script Change-Id: Ie778f3c99df81c85ed988f3af89b4edbcc2eeb99 Merged-In: Ie778f3c99df81c85ed988f3af89b4edbcc2eeb99 (cherry picked from commit 7feaeb006941a1494d7cdc0a2ffc4bb1004b38b4) (cherry picked from commit 6d415839da570b94b0763f6ab444f0dd1321fc33) CVE-2017-0782
-rw-r--r--stack/bnep/bnep_utils.c90
1 files changed, 69 insertions, 21 deletions
diff --git a/stack/bnep/bnep_utils.c b/stack/bnep/bnep_utils.c
index 4c738ea6d..777ac776d 100644
--- a/stack/bnep/bnep_utils.c
+++ b/stack/bnep/bnep_utils.c
@@ -785,24 +785,45 @@ void bnep_process_setup_conn_responce (tBNEP_CONN *p_bcb, UINT8 *p_setup)
UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *rem_len, BOOLEAN is_ext)
{
UINT8 control_type;
- BOOLEAN bad_pkt = FALSE;
UINT16 len, ext_len = 0;
+ if (p == NULL || rem_len == NULL)
+ {
+ if (rem_len != NULL) *rem_len = 0;
+ BNEP_TRACE_DEBUG("%s: invalid packet: p = %p rem_len = %p", __func__, p,
+ rem_len);
+ return NULL;
+ }
+ uint16_t rem_len_orig = *rem_len;
+
if (is_ext)
{
+ if (*rem_len < 1) goto bad_packet_length;
ext_len = *p++;
*rem_len = *rem_len - 1;
}
+ if (*rem_len < 1) goto bad_packet_length;
control_type = *p++;
*rem_len = *rem_len - 1;
- BNEP_TRACE_EVENT ("BNEP processing control packet rem_len %d, is_ext %d, ctrl_type %d", *rem_len, is_ext, control_type);
+ BNEP_TRACE_EVENT(
+ "%s: BNEP processing control packet rem_len %d, is_ext %d, ctrl_type %d",
+ __func__, *rem_len, is_ext, control_type);
switch (control_type)
{
case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
- BNEP_TRACE_ERROR ("BNEP Received Cmd not understood for ctl pkt type: %d", *p);
+ if (*rem_len < 1)
+ {
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD with bad length",
+ __func__);
+ goto bad_packet_length;
+ }
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD for pkt type: %d",
+ __func__, *p);
p++;
*rem_len = *rem_len - 1;
break;
@@ -811,9 +832,10 @@ UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *rem_len
len = *p++;
if (*rem_len < ((2 * len) + 1))
{
- bad_pkt = TRUE;
- BNEP_TRACE_ERROR ("BNEP Received Setup message with bad length");
- break;
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_SETUP_CONNECTION_REQUEST_MSG with bad length",
+ __func__);
+ goto bad_packet_length;
}
if (!is_ext)
bnep_process_setup_conn_req (p_bcb, p, (UINT8)len);
@@ -822,6 +844,13 @@ UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *rem_len
break;
case BNEP_SETUP_CONNECTION_RESPONSE_MSG:
+ if (*rem_len < 2)
+ {
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_SETUP_CONNECTION_RESPONSE_MSG with bad length",
+ __func__);
+ goto bad_packet_length;
+ }
if (!is_ext)
bnep_process_setup_conn_responce (p_bcb, p);
p += 2;
@@ -832,9 +861,10 @@ UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *rem_len
BE_STREAM_TO_UINT16 (len, p);
if (*rem_len < (len + 2))
{
- bad_pkt = TRUE;
- BNEP_TRACE_ERROR ("BNEP Received Filter set message with bad length");
- break;
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_FILTER_NET_TYPE_SET_MSG with bad length",
+ __func__);
+ goto bad_packet_length;
}
bnepu_process_peer_filter_set (p_bcb, p, len);
p += len;
@@ -842,6 +872,13 @@ UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *rem_len
break;
case BNEP_FILTER_NET_TYPE_RESPONSE_MSG:
+ if (*rem_len < 2)
+ {
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_FILTER_NET_TYPE_RESPONSE_MSG with bad length",
+ __func__);
+ goto bad_packet_length;
+ }
bnepu_process_peer_filter_rsp (p_bcb, p);
p += 2;
*rem_len = *rem_len - 2;
@@ -851,9 +888,10 @@ UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *rem_len
BE_STREAM_TO_UINT16 (len, p);
if (*rem_len < (len + 2))
{
- bad_pkt = TRUE;
- BNEP_TRACE_ERROR ("BNEP Received Multicast Filter Set message with bad length");
- break;
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_FILTER_MULTI_ADDR_SET_MSG with bad length",
+ __func__);
+ goto bad_packet_length;
}
bnepu_process_peer_multicast_filter_set (p_bcb, p, len);
p += len;
@@ -861,30 +899,40 @@ UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *rem_len
break;
case BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG:
+ if (*rem_len < 2)
+ {
+ BNEP_TRACE_ERROR(
+ "%s: Received BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG with bad length",
+ __func__);
+ goto bad_packet_length;
+ }
bnepu_process_multicast_filter_rsp (p_bcb, p);
p += 2;
*rem_len = *rem_len - 2;
break;
default :
- BNEP_TRACE_ERROR ("BNEP - bad ctl pkt type: %d", control_type);
+ BNEP_TRACE_ERROR("%s: BNEP - bad ctl pkt type: %d", __func__,
+ control_type);
bnep_send_command_not_understood (p_bcb, control_type);
if (is_ext)
{
+ if (*rem_len < (ext_len - 1))
+ {
+ goto bad_packet_length;
+ }
p += (ext_len - 1);
*rem_len -= (ext_len - 1);
}
break;
}
-
- if (bad_pkt)
- {
- BNEP_TRACE_ERROR ("BNEP - bad ctl pkt length: %d", *rem_len);
- *rem_len = 0;
- return NULL;
- }
-
return p;
+
+bad_packet_length:
+ BNEP_TRACE_ERROR("%s: bad control packet length: original=%d remaining=%d",
+ __func__, rem_len_orig, *rem_len);
+ *rem_len = 0;
+ return NULL;
}