From 6821472c7509c54c5b1ef4744af8f6eab9be4aa7 Mon Sep 17 00:00:00 2001
From: Fedora Bluez maintainers <bluez-owner@fedoraproject.org>
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