You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
56 lines
2.4 KiB
56 lines
2.4 KiB
6 years ago
|
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
|
||
|
|