diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2015-02-27 13:22:46 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2015-02-27 13:22:46 +0200 |
commit | 731e9954b36c2a34136af8b069a93fbbf95e67c2 (patch) | |
tree | 5269c1fc458e329b01211fcc81303fba7ba9d1a0 /emulator/bthost.c | |
parent | 74aa69af7d0f83c4317a28f5cc4ada2c69fed027 (diff) | |
download | bluez-731e9954b36c2a34136af8b069a93fbbf95e67c2.tar.gz |
emulator/bthost: Fix calling RFCOMM callback for zero-length data
Diffstat (limited to 'emulator/bthost.c')
-rw-r--r-- | emulator/bthost.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/emulator/bthost.c b/emulator/bthost.c index 86f1e56f3..16e103d1a 100644 --- a/emulator/bthost.c +++ b/emulator/bthost.c @@ -2038,23 +2038,30 @@ static void rfcomm_mcc_recv(struct bthost *bthost, struct btconn *conn, } } +#define GET_LEN8(length) ((length & 0xfe) >> 1) +#define GET_LEN16(length) ((length & 0xfffe) >> 1) + static void rfcomm_uih_recv(struct bthost *bthost, struct btconn *conn, struct l2conn *l2conn, const void *data, uint16_t len) { const struct rfcomm_hdr *hdr = data; - uint16_t hdr_len; + uint16_t hdr_len, data_len; const void *p; if (len < sizeof(*hdr)) return; - if (RFCOMM_TEST_EA(hdr->length)) + if (RFCOMM_TEST_EA(hdr->length)) { + data_len = (uint16_t) GET_LEN8(hdr->length); hdr_len = sizeof(*hdr); - else + } else { + uint8_t ex_len = *((uint8_t *)(data + sizeof(*hdr))); + data_len = ((uint16_t) hdr->length << 8) | ex_len; hdr_len = sizeof(*hdr) + sizeof(uint8_t); + } - if (len < hdr_len) + if (len < hdr_len + data_len) return; p = data + hdr_len; @@ -2064,13 +2071,10 @@ static void rfcomm_uih_recv(struct bthost *bthost, struct btconn *conn, hook = find_rfcomm_chan_hook(conn, RFCOMM_GET_CHANNEL(hdr->address)); - if (!hook) - return; - - hook->func(p, len - hdr_len - sizeof(uint8_t), - hook->user_data); + if (hook && data_len) + hook->func(p, data_len, hook->user_data); } else { - rfcomm_mcc_recv(bthost, conn, l2conn, p, len - hdr_len); + rfcomm_mcc_recv(bthost, conn, l2conn, p, data_len); } } |