Blame SOURCES/0001-Out-of-bounds-heap-read-in-service_search_attr_req-f.patch

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