diff options
author | venkata Jagadeesh <vjagad@codeaurora.org> | 2015-08-24 17:20:35 +0530 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2015-10-06 03:22:14 -0600 |
commit | e7accafc7ea0c4cfdcb11d0723249c2d1d54bf75 (patch) | |
tree | 1be10b5cb76215022d4d7b0c7bb8ba30f5bfccf5 /hci/src/packet_fragmenter.c | |
parent | 84f60eb3f2d7076c8f2d2ac099e5c38eb4753bbb (diff) | |
download | android_system_bt-e7accafc7ea0c4cfdcb11d0723249c2d1d54bf75.tar.gz android_system_bt-e7accafc7ea0c4cfdcb11d0723249c2d1d54bf75.tar.bz2 android_system_bt-e7accafc7ea0c4cfdcb11d0723249c2d1d54bf75.zip |
L2cap: Handle invalid HCI packets from Test tool
- Handled Buffer over flow for UINT16
- Handled full packet size more than gki buffer case.
- Discard invalid HCI packets from Codenomican test
tool as data length and actual data not matching
during reassembly
Use case: Execute L2cap test suit from Defensics Codenomican
STR:
1. Pair and connect DUT to Codenomican tool
2. Execute L2cap test suit from Defensics Codenomican
Failure: Crash observed on DUT and Codenomican tool stuck in execution.
Root cause: Codenomican tool sending invalid HCI packets to DUT and
there are no checks to handle buffer over flow and other invalid data
from Codenomican tool
Change-Id: I6f93c80244fc39d607ad285185136bbbca83d7ae
CRs-Fixed: 903510
Diffstat (limited to 'hci/src/packet_fragmenter.c')
-rw-r--r-- | hci/src/packet_fragmenter.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/hci/src/packet_fragmenter.c b/hci/src/packet_fragmenter.c index de6366809..e7cf6a6c0 100644 --- a/hci/src/packet_fragmenter.c +++ b/hci/src/packet_fragmenter.c @@ -30,6 +30,7 @@ #include "osi/include/osi.h" #include "osi/include/hash_functions.h" #include "osi/include/log.h" +#include "gki.h" #define APPLY_CONTINUATION_FLAG(handle) (((handle) & 0xCFFF) | 0x1000) #define APPLY_START_FLAG(handle) (((handle) & 0xCFFF) | 0x2000) @@ -144,14 +145,27 @@ static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR *packet) { hash_map_erase(partial_packets, (void *)(uintptr_t)handle); buffer_allocator->free(partial_packet); } + /* check for invalid hci length */ + if (acl_length < L2CAP_HEADER_SIZE) { + LOG_ERROR("%s HCI length %d .", __func__, packet->len); + buffer_allocator->free(packet); + return; + } uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE; - if (full_length <= packet->len) { - if (full_length < packet->len) - LOG_WARN("%s found l2cap full length %d less than the hci length %d.", __func__, l2cap_length, packet->len); - callbacks->reassembled(packet); - return; + /* Buffer over flow or full packet + BT_HC_HDR_SIZE greater than GKI buffer */ + if (((UINT16_MAX - l2cap_length) < (L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE)) || + ((full_length + sizeof(BT_HDR)) > GKI_MAX_BUF_SIZE) || (full_length < packet->len)) + { + LOG_ERROR("%s Invalid L2cap length : %d :return .", __func__, l2cap_length); + buffer_allocator->free(packet); + return; + } + else if (full_length == packet->len) { + LOG_WARN("%s complete l2cap packet received:l2cap full length %d and hci length %d.", __func__, l2cap_length, packet->len); + callbacks->reassembled(packet); + return; } partial_packet = (BT_HDR *)buffer_allocator->alloc(full_length + sizeof(BT_HDR)); |