Bluetooth: GATT: Fix bt_gatt_discovery with BT_GATT_DISCOVER_DESCRIPTOR

Fix iterating past the response which causes an invalid memory to be
accessed and passed over to the callback as if there were more
attributes found.

Fixes #16602

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2019-06-19 11:27:25 +03:00 committed by Johan Hedberg
commit eb8abda6b0

View file

@ -2410,6 +2410,8 @@ static void gatt_find_info_rsp(struct bt_conn *conn, u8_t err,
struct bt_uuid_16 u16; struct bt_uuid_16 u16;
struct bt_uuid_128 u128; struct bt_uuid_128 u128;
} u; } u;
int i;
bool skip = false;
BT_DBG("err 0x%02x", err); BT_DBG("err 0x%02x", err);
@ -2433,13 +2435,18 @@ static void gatt_find_info_rsp(struct bt_conn *conn, u8_t err,
} }
/* Parse descriptors found */ /* Parse descriptors found */
for (length--, pdu = rsp->info; length >= len; for (i = (length - 1) / len, pdu = rsp->info; i != 0;
length -= len, pdu = (const u8_t *)pdu + len) { i--, pdu = (const u8_t *)pdu + len) {
struct bt_gatt_attr *attr; struct bt_gatt_attr *attr;
info.i16 = pdu; info.i16 = pdu;
handle = sys_le16_to_cpu(info.i16->handle); handle = sys_le16_to_cpu(info.i16->handle);
if (skip) {
skip = false;
continue;
}
switch (u.uuid.type) { switch (u.uuid.type) {
case BT_UUID_TYPE_16: case BT_UUID_TYPE_16:
u.u16.val = sys_le16_to_cpu(info.i16->uuid); u.u16.val = sys_le16_to_cpu(info.i16->uuid);
@ -2470,10 +2477,7 @@ static void gatt_find_info_rsp(struct bt_conn *conn, u8_t err,
* entry must be its value. * entry must be its value.
*/ */
if (!bt_uuid_cmp(&u.uuid, BT_UUID_GATT_CHRC)) { if (!bt_uuid_cmp(&u.uuid, BT_UUID_GATT_CHRC)) {
if (length >= len) { skip = true;
pdu = (const u8_t *)pdu + len;
length -= len;
}
continue; continue;
} }
} }
@ -2488,7 +2492,7 @@ static void gatt_find_info_rsp(struct bt_conn *conn, u8_t err,
} }
/* Stop if could not parse the whole PDU */ /* Stop if could not parse the whole PDU */
if (length > 0) { if (i) {
goto done; goto done;
} }