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

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