From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Chienyuan Date: Tue, 12 Feb 2019 16:01:00 +0800 Subject: [PATCH] Fix OOB in bnep_is_packet_allowed Bug: 112050983 Test: PoC Change-Id: I5d331f46cdba86c8e61de206a2ede1d2b348d7e4 (cherry picked from commit 230f252b8a1a1073ec1a4081545b2ff62393d16d) CRs-Fixed: 3155069 --- stack/bnep/bnep_api.c | 15 +++++++++++++-- stack/bnep/bnep_int.h | 2 +- stack/bnep/bnep_utils.c | 13 ++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/stack/bnep/bnep_api.c b/stack/bnep/bnep_api.c index dc349299a..e1c9f2e3d 100644 --- a/stack/bnep/bnep_api.c +++ b/stack/bnep/bnep_api.c @@ -387,7 +387,8 @@ tBNEP_RESULT BNEP_WriteBuf (UINT16 handle, /* Check if the packet should be filtered out */ p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; - if (bnep_is_packet_allowed (p_bcb, p_dest_addr, protocol, fw_ext_present, p_data) != BNEP_SUCCESS) + if (bnep_is_packet_allowed (p_bcb, p_dest_addr, protocol, fw_ext_present, + p_data, p_buf->len) != BNEP_SUCCESS) { /* ** If packet is filtered and ext headers are present @@ -401,6 +402,11 @@ tBNEP_RESULT BNEP_WriteBuf (UINT16 handle, org_len = p_buf->len; new_len = 0; do { + if ((new_len + 2) > org_len) + { + osi_free(p_buf); + return BNEP_IGNORE_CMD; + } ext = *p_data++; length = *p_data++; @@ -505,7 +511,8 @@ tBNEP_RESULT BNEP_Write (UINT16 handle, p_bcb = &(bnep_cb.bcb[handle - 1]); /* Check if the packet should be filtered out */ - if (bnep_is_packet_allowed (p_bcb, p_dest_addr, protocol, fw_ext_present, p_data) != BNEP_SUCCESS) + if (bnep_is_packet_allowed (p_bcb, p_dest_addr, protocol, fw_ext_present, + p_data, len) != BNEP_SUCCESS) { /* ** If packet is filtered and ext headers are present @@ -520,6 +527,10 @@ tBNEP_RESULT BNEP_Write (UINT16 handle, new_len = 0; p = p_data; do { + if ((new_len + 2) > org_len) + { + return BNEP_IGNORE_CMD; + } ext = *p_data++; length = *p_data++; diff --git a/stack/bnep/bnep_int.h b/stack/bnep/bnep_int.h index 126be04fe..b10098122 100644 --- a/stack/bnep/bnep_int.h +++ b/stack/bnep/bnep_int.h @@ -236,7 +236,7 @@ extern UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UI extern void bnep_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT trasnport, void *p_ref_data, UINT8 result); extern tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb, BD_ADDR p_dest_addr, UINT16 protocol, - BOOLEAN fw_ext_present, UINT8 *p_data); + BOOLEAN fw_ext_present, UINT8 *p_data, UINT16 org_len); extern UINT32 bnep_get_uuid32 (tBT_UUID *src_uuid); diff --git a/stack/bnep/bnep_utils.c b/stack/bnep/bnep_utils.c index 65acd33f6..09f2d13c2 100644 --- a/stack/bnep/bnep_utils.c +++ b/stack/bnep/bnep_utils.c @@ -1336,7 +1336,7 @@ tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb, BD_ADDR p_dest_addr, UINT16 protocol, BOOLEAN fw_ext_present, - UINT8 *p_data) + UINT8 *p_data, UINT16 org_len) { if (p_bcb->rcvd_num_filters) { @@ -1346,18 +1346,29 @@ tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb, proto = protocol; if (proto == BNEP_802_1_P_PROTOCOL) { + UINT16 new_len = 0; if (fw_ext_present) { UINT8 len, ext; /* parse the extension headers and findout actual protocol */ do { + if ((new_len + 2) > org_len) + { + return BNEP_IGNORE_CMD; + } ext = *p_data++; len = *p_data++; p_data += len; + new_len += (len + 2); + } while (ext & 0x80); } + if ((new_len + 4) > org_len) + { + return BNEP_IGNORE_CMD; + } p_data += 2; BE_STREAM_TO_UINT16 (proto, p_data); }