Commit 700f6409 authored by Aleksander Wasaznik's avatar Aleksander Wasaznik Committed by Carles Cufi
Browse files

Bluetooth: ATT: Reject read-by-uuid rsp outside range

A bad peer responding to read-by-uuid can return handles outside the
requested range. This confuses the stack. In particular, the "continue"
and "end" logic in the same function relies on this assumption.

This bad peer was a real issue at UPF, and it caused an infinite loop
during discovery.

Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/50686

Signed-off-by: default avatarAleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
parent c0e6629b
Loading
Loading
Loading
Loading
+12 −0
Changes for subsys/bluetooth/host/gatt.c: 12 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -4558,6 +4558,9 @@ static void parse_read_by_uuid(struct bt_conn *conn,
{
	const struct bt_att_read_type_rsp *rsp = pdu;

	const uint16_t req_start_handle = params->by_uuid.start_handle;
	const uint16_t req_end_handle = params->by_uuid.end_handle;

	/* Parse values found */
	for (length--, pdu = rsp->data; length;
	     length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
@@ -4577,6 +4580,15 @@ static void parse_read_by_uuid(struct bt_conn *conn,

		LOG_DBG("handle 0x%04x len %u value %u", handle, rsp->len, len);

		if (!IN_RANGE(handle, req_start_handle, req_end_handle)) {
			LOG_WRN("Bad peer: ATT read-by-uuid rsp: "
				"Handle 0x%04x is outside requested range 0x%04x-0x%04x. "
				"Aborting read.",
				handle, req_start_handle, req_end_handle);
			params->func(conn, BT_ATT_ERR_UNLIKELY, params, NULL, 0);
			return;
		}

		/* Update start_handle */
		params->by_uuid.start_handle = handle;