diff options
author | Pavlin Radoslavov <pavlin@google.com> | 2017-07-06 16:51:35 -0700 |
---|---|---|
committer | Andreas Blaesius <skate4life@gmx.de> | 2017-09-17 22:11:29 +0200 |
commit | bee52c2d82153fa6459b31922c332b80bcc8a5ee (patch) | |
tree | 9c9a34ddbcf8ff9dff6830f9f6ac1d74a8cb6e43 | |
parent | 33427d54f31adaf5b9c697f5ce642fda1dc01946 (diff) | |
download | android_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.c | 90 |
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; } |