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.
55 lines
2.4 KiB
55 lines
2.4 KiB
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 |
|
|
|
|