summaryrefslogtreecommitdiffstats
path: root/hci/src/packet_fragmenter.c
diff options
context:
space:
mode:
authorvenkata Jagadeesh <vjagad@codeaurora.org>2015-08-24 17:20:35 +0530
committerLinux Build Service Account <lnxbuild@localhost>2015-10-06 03:22:14 -0600
commite7accafc7ea0c4cfdcb11d0723249c2d1d54bf75 (patch)
tree1be10b5cb76215022d4d7b0c7bb8ba30f5bfccf5 /hci/src/packet_fragmenter.c
parent84f60eb3f2d7076c8f2d2ac099e5c38eb4753bbb (diff)
downloadandroid_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.c24
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));