|
|
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 |
|