From 6821472c7509c54c5b1ef4744af8f6eab9be4aa7 Mon Sep 17 00:00:00 2001 From: Fedora Bluez maintainers Date: Mon, 11 Sep 2017 11:19:18 -0400 Subject: [PATCH] Out of bounds heap read in service_search_attr_req function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a long response is returned to a specific search attribute request, a continuation state is returned to allow reception of additional fragments, via additional requests that contain the last continuation state sent. However, the incoming “cstate” that requests additional fragments isn’t validated properly, and thus an out-of-bounds read of the response buffer (pResponse) can be achieved, leading to information disclosure of the heap. --- src/sdpd-request.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/sdpd-request.c b/src/sdpd-request.c index 1eefdce..ddeea7f 100644 --- a/src/sdpd-request.c +++ b/src/sdpd-request.c @@ -918,15 +918,20 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) /* continuation State exists -> get from cache */ sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); if (pCache) { - uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent); - pResponse = pCache->data; - memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); - buf->data_size += sent; - cstate->cStateValue.maxBytesSent += sent; - if (cstate->cStateValue.maxBytesSent == pCache->data_size) - cstate_size = sdp_set_cstate_pdu(buf, NULL); - else - cstate_size = sdp_set_cstate_pdu(buf, cstate); + if (cstate->cStateValue.maxBytesSent >= pCache->data_size) { + status = SDP_INVALID_CSTATE; + SDPDBG("Got bad cstate with invalid size"); + } else { + uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent); + pResponse = pCache->data; + memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); + buf->data_size += sent; + cstate->cStateValue.maxBytesSent += sent; + if (cstate->cStateValue.maxBytesSent == pCache->data_size) + cstate_size = sdp_set_cstate_pdu(buf, NULL); + else + cstate_size = sdp_set_cstate_pdu(buf, cstate); + } } else { status = SDP_INVALID_CSTATE; SDPDBG("Non-null continuation state, but null cache buffer"); -- 2.13.5