import bluez-5.56-3.el8
This commit is contained in:
parent
848a529030
commit
aa4f83604a
@ -0,0 +1,51 @@
|
||||
From 2c3bba7b38be03834162e34069156f1fd49f0528 Mon Sep 17 00:00:00 2001
|
||||
From: "antoine.belvire@laposte.net" <antoine.belvire@laposte.net>
|
||||
Date: Tue, 27 Mar 2018 20:30:26 +0200
|
||||
Subject: [PATCH] adapter: Don't refresh adv_manager for non-LE devices
|
||||
|
||||
btd_adv_manager_refresh is called upon MGMT_SETTING_DISCOVERABLE setting change
|
||||
but as only LE adapters have an adv_manager, this leads to segmentation fault
|
||||
for non-LE devices:
|
||||
|
||||
0 btd_adv_manager_refresh (manager=0x0) at src/advertising.c:1176
|
||||
1 0x0000556fe45fcb02 in settings_changed (settings=<optimized out>,
|
||||
adapter=0x556fe53f7c70) at src/adapter.c:543
|
||||
2 new_settings_callback (index=<optimized out>, length=<optimized out>,
|
||||
param=<optimized out>, user_data=0x556fe53f7c70) at src/adapter.c:573
|
||||
3 0x0000556fe462c278 in request_complete (mgmt=mgmt@entry=0x556fe53f20c0,
|
||||
status=<optimized out>, opcode=opcode@entry=7, index=index@entry=0,
|
||||
length=length@entry=4, param=0x556fe53eb5f9) at src/shared/mgmt.c:261
|
||||
4 0x0000556fe462cd9d in can_read_data (io=<optimized out>,
|
||||
user_data=0x556fe53f20c0) at src/shared/mgmt.c:353
|
||||
5 0x0000556fe46396e3 in watch_callback (channel=<optimized out>,
|
||||
cond=<optimized out>, user_data=<optimized out>)
|
||||
at src/shared/io-glib.c:170
|
||||
6 0x00007fe351c980e5 in g_main_context_dispatch ()
|
||||
from /usr/lib64/libglib-2.0.so.0
|
||||
7 0x00007fe351c984b0 in ?? () from /usr/lib64/libglib-2.0.so.0
|
||||
8 0x00007fe351c987c2 in g_main_loop_run () from /usr/lib64/libglib-2.0.so.0
|
||||
9 0x0000556fe45abc75 in main (argc=<optimized out>, argv=<optimized out>)
|
||||
at src/main.c:770
|
||||
|
||||
This commit prevents the call to btd_adv_manager_refresh for non-LE devices.
|
||||
---
|
||||
src/adapter.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/adapter.c b/src/adapter.c
|
||||
index 6b9222bcf..daccfdc19 100644
|
||||
--- a/src/adapter.c
|
||||
+++ b/src/adapter.c
|
||||
@@ -540,7 +540,8 @@ static void settings_changed(struct btd_adapter *adapter, uint32_t settings)
|
||||
g_dbus_emit_property_changed(dbus_conn, adapter->path,
|
||||
ADAPTER_INTERFACE, "Discoverable");
|
||||
store_adapter_info(adapter);
|
||||
- btd_adv_manager_refresh(adapter->adv_manager);
|
||||
+ if (adapter->supported_settings & MGMT_SETTING_LE)
|
||||
+ btd_adv_manager_refresh(adapter->adv_manager);
|
||||
}
|
||||
|
||||
if (changed_mask & MGMT_SETTING_BONDABLE) {
|
||||
--
|
||||
2.17.0
|
||||
|
@ -0,0 +1,38 @@
|
||||
From cba55944f76ad0f01bb7c8976fd6699f058c68cd Mon Sep 17 00:00:00 2001
|
||||
From: Bastien Nocera <hadess@hadess.net>
|
||||
Date: Wed, 20 Sep 2017 14:42:14 +0200
|
||||
Subject: [PATCH] hostname: Fix "BlueZ 5.XX" adapter name on startup
|
||||
|
||||
The hostname plugin listens to property changes from systemd-hostnamed
|
||||
but doesn't fetch initial values. This means that unless the
|
||||
PrettyHostname or StaticHostname changes, the default adapter will be
|
||||
called "BlueZ 5.XX" matching the version number.
|
||||
|
||||
This is the case since the hostname plugin replaced the adaptername
|
||||
plugin in 2012.
|
||||
|
||||
Fetch the initial values for PrettyHostname, StaticHostname and
|
||||
Chassis when the plugin is initiated, so as to make the values
|
||||
available for adapter setup.
|
||||
---
|
||||
plugins/hostname.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/plugins/hostname.c b/plugins/hostname.c
|
||||
index f876d0afb..db9187378 100644
|
||||
--- a/plugins/hostname.c
|
||||
+++ b/plugins/hostname.c
|
||||
@@ -307,6 +307,10 @@ static int hostname_init(void)
|
||||
hostname_proxy = NULL;
|
||||
g_dbus_client_unref(hostname_client);
|
||||
hostname_client = NULL;
|
||||
+ } else {
|
||||
+ g_dbus_proxy_refresh_property(hostname_proxy, "PrettyHostname");
|
||||
+ g_dbus_proxy_refresh_property(hostname_proxy, "StaticHostname");
|
||||
+ g_dbus_proxy_refresh_property(hostname_proxy, "Chassis");
|
||||
}
|
||||
|
||||
return err;
|
||||
--
|
||||
2.14.1
|
||||
|
@ -0,0 +1,38 @@
|
||||
From 90b72b787a6ae6b9b0bf8ece238e108e8607a433 Mon Sep 17 00:00:00 2001
|
||||
From: Bastien Nocera <hadess@hadess.net>
|
||||
Date: Sat, 9 Nov 2013 18:13:43 +0100
|
||||
Subject: [PATCH 1/2] obex: Use GLib helper function to manipulate paths
|
||||
|
||||
Instead of trying to do it by hand. This also makes sure that
|
||||
relative paths aren't used by the agent.
|
||||
---
|
||||
obexd/src/manager.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/obexd/src/manager.c b/obexd/src/manager.c
|
||||
index f84384ae4..285c07c37 100644
|
||||
--- a/obexd/src/manager.c
|
||||
+++ b/obexd/src/manager.c
|
||||
@@ -650,14 +650,14 @@ static void agent_reply(DBusPendingCall *call, void *user_data)
|
||||
DBUS_TYPE_STRING, &name,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
/* Splits folder and name */
|
||||
- const char *slash = strrchr(name, '/');
|
||||
+ gboolean is_relative = !g_path_is_absolute(name);
|
||||
DBG("Agent replied with %s", name);
|
||||
- if (!slash) {
|
||||
- agent->new_name = g_strdup(name);
|
||||
+ if (is_relative) {
|
||||
+ agent->new_name = g_path_get_basename(name);
|
||||
agent->new_folder = NULL;
|
||||
} else {
|
||||
- agent->new_name = g_strdup(slash + 1);
|
||||
- agent->new_folder = g_strndup(name, slash - name);
|
||||
+ agent->new_name = g_path_get_basename(name);
|
||||
+ agent->new_folder = g_path_get_dirname(name);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.14.1
|
||||
|
@ -0,0 +1,468 @@
|
||||
From 4e6a2402ed4f46ea026ad0929fbc14faecf3a475 Mon Sep 17 00:00:00 2001
|
||||
From: Gopal Tiwari <gtiwari@redhat.com>
|
||||
Date: Wed, 1 Dec 2021 12:18:24 +0530
|
||||
Subject: [PATCH BlueZ] sdpd: Fix leaking buffers stored in cstates cache
|
||||
|
||||
commit e79417ed7185b150a056d4eb3a1ab528b91d2fc0
|
||||
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
||||
Date: Thu Jul 15 11:01:20 2021 -0700
|
||||
|
||||
sdpd: Fix leaking buffers stored in cstates cache
|
||||
|
||||
These buffer shall only be keep in cache for as long as they are
|
||||
needed so this would cleanup any client cstates in the following
|
||||
conditions:
|
||||
|
||||
- There is no cstate on the response
|
||||
- No continuation can be found for cstate
|
||||
- Different request opcode
|
||||
- Respond with an error
|
||||
- Client disconnect
|
||||
|
||||
Fixes: https://github.com/bluez/bluez/security/advisories/GHSA-3fqg-r8j5-f5xq
|
||||
---
|
||||
src/sdpd-request.c | 170 ++++++++++++++++++++++++++++++++-------------
|
||||
src/sdpd-server.c | 20 +++---
|
||||
src/sdpd.h | 3 +
|
||||
unit/test-sdp.c | 2 +-
|
||||
4 files changed, 135 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/src/sdpd-request.c b/src/sdpd-request.c
|
||||
index 033d1e5bf..c8f5a2c72 100644
|
||||
--- a/src/sdpd-request.c
|
||||
+++ b/src/sdpd-request.c
|
||||
@@ -42,48 +42,78 @@ typedef struct {
|
||||
|
||||
#define MIN(x, y) ((x) < (y)) ? (x): (y)
|
||||
|
||||
-typedef struct _sdp_cstate_list sdp_cstate_list_t;
|
||||
+typedef struct sdp_cont_info sdp_cont_info_t;
|
||||
|
||||
-struct _sdp_cstate_list {
|
||||
- sdp_cstate_list_t *next;
|
||||
+struct sdp_cont_info {
|
||||
+ int sock;
|
||||
+ uint8_t opcode;
|
||||
uint32_t timestamp;
|
||||
sdp_buf_t buf;
|
||||
};
|
||||
|
||||
-static sdp_cstate_list_t *cstates;
|
||||
+static sdp_list_t *cstates;
|
||||
|
||||
-/* FIXME: should probably remove it when it's found */
|
||||
-static sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate)
|
||||
+static int cstate_match(const void *data, const void *user_data)
|
||||
{
|
||||
- sdp_cstate_list_t *p;
|
||||
+ const sdp_cont_info_t *cinfo = data;
|
||||
+ const sdp_cont_state_t *cstate = user_data;
|
||||
|
||||
- for (p = cstates; p; p = p->next) {
|
||||
- /* Check timestamp */
|
||||
- if (p->timestamp != cstate->timestamp)
|
||||
- continue;
|
||||
+ /* Check timestamp */
|
||||
+ return cinfo->timestamp - cstate->timestamp;
|
||||
+}
|
||||
+
|
||||
+static void sdp_cont_info_free(sdp_cont_info_t *cinfo)
|
||||
+{
|
||||
+ if (!cinfo)
|
||||
+ return;
|
||||
+
|
||||
+ cstates = sdp_list_remove(cstates, cinfo);
|
||||
+ free(cinfo->buf.data);
|
||||
+ free(cinfo);
|
||||
+}
|
||||
+
|
||||
+static sdp_cont_info_t *sdp_get_cont_info(sdp_req_t *req,
|
||||
+ sdp_cont_state_t *cstate)
|
||||
+{
|
||||
+ sdp_list_t *list;
|
||||
+
|
||||
+ list = sdp_list_find(cstates, cstate, cstate_match);
|
||||
+ if (list) {
|
||||
+ sdp_cont_info_t *cinfo = list->data;
|
||||
|
||||
- /* Check if requesting more than available */
|
||||
- if (cstate->cStateValue.maxBytesSent < p->buf.data_size)
|
||||
- return &p->buf;
|
||||
+ if (cinfo->opcode == req->opcode)
|
||||
+ return cinfo;
|
||||
+
|
||||
+ /* Cleanup continuation if the opcode doesn't match since its
|
||||
+ * response buffer shall only be valid for the original requests
|
||||
+ */
|
||||
+ sdp_cont_info_free(cinfo);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ /* Cleanup cstates if no continuation info could be found */
|
||||
+ sdp_cstate_cleanup(req->sock);
|
||||
+
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
-static uint32_t sdp_cstate_alloc_buf(sdp_buf_t *buf)
|
||||
+static uint32_t sdp_cstate_alloc_buf(sdp_req_t *req, sdp_buf_t *buf)
|
||||
{
|
||||
- sdp_cstate_list_t *cstate = malloc(sizeof(sdp_cstate_list_t));
|
||||
+ sdp_cont_info_t *cinfo = malloc(sizeof(sdp_cont_info_t));
|
||||
uint8_t *data = malloc(buf->data_size);
|
||||
|
||||
memcpy(data, buf->data, buf->data_size);
|
||||
- memset((char *)cstate, 0, sizeof(sdp_cstate_list_t));
|
||||
- cstate->buf.data = data;
|
||||
- cstate->buf.data_size = buf->data_size;
|
||||
- cstate->buf.buf_size = buf->data_size;
|
||||
- cstate->timestamp = sdp_get_time();
|
||||
- cstate->next = cstates;
|
||||
- cstates = cstate;
|
||||
- return cstate->timestamp;
|
||||
+ memset(cinfo, 0, sizeof(sdp_cont_info_t));
|
||||
+ cinfo->buf.data = data;
|
||||
+ cinfo->buf.data_size = buf->data_size;
|
||||
+ cinfo->buf.buf_size = buf->data_size;
|
||||
+ cinfo->timestamp = sdp_get_time();
|
||||
+ cinfo->sock = req->sock;
|
||||
+ cinfo->opcode = req->opcode;
|
||||
+
|
||||
+ cstates = sdp_list_append(cstates, cinfo);
|
||||
+
|
||||
+ return cinfo->timestamp;
|
||||
}
|
||||
|
||||
/* Additional values for checking datatype (not in spec) */
|
||||
@@ -274,14 +304,16 @@ static int sdp_set_cstate_pdu(sdp_buf_t *buf, sdp_cont_state_t *cstate)
|
||||
return length;
|
||||
}
|
||||
|
||||
-static int sdp_cstate_get(uint8_t *buffer, size_t len,
|
||||
- sdp_cont_state_t **cstate)
|
||||
+static int sdp_cstate_get(sdp_req_t *req, uint8_t *buffer, size_t len,
|
||||
+ sdp_cont_state_t **cstate, sdp_cont_info_t **cinfo)
|
||||
{
|
||||
uint8_t cStateSize = *buffer;
|
||||
|
||||
SDPDBG("Continuation State size : %d", cStateSize);
|
||||
|
||||
if (cStateSize == 0) {
|
||||
+ /* Cleanup cstates if request doesn't contain a cstate */
|
||||
+ sdp_cstate_cleanup(req->sock);
|
||||
*cstate = NULL;
|
||||
return 0;
|
||||
}
|
||||
@@ -306,6 +338,8 @@ static int sdp_cstate_get(uint8_t *buffer, size_t len,
|
||||
SDPDBG("Cstate TS : 0x%x", (*cstate)->timestamp);
|
||||
SDPDBG("Bytes sent : %d", (*cstate)->cStateValue.maxBytesSent);
|
||||
|
||||
+ *cinfo = sdp_get_cont_info(req, *cstate);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -360,6 +394,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
uint16_t expected, actual, rsp_count = 0;
|
||||
uint8_t dtd;
|
||||
sdp_cont_state_t *cstate = NULL;
|
||||
+ sdp_cont_info_t *cinfo = NULL;
|
||||
uint8_t *pCacheBuffer = NULL;
|
||||
int handleSize = 0;
|
||||
uint32_t cStateId = 0;
|
||||
@@ -399,9 +434,9 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
|
||||
/*
|
||||
* Check if continuation state exists, if yes attempt
|
||||
- * to get rsp remainder from cache, else send error
|
||||
+ * to get rsp remainder from continuation info, else send error
|
||||
*/
|
||||
- if (sdp_cstate_get(pdata, data_left, &cstate) < 0) {
|
||||
+ if (sdp_cstate_get(req, pdata, data_left, &cstate, &cinfo) < 0) {
|
||||
status = SDP_INVALID_SYNTAX;
|
||||
goto done;
|
||||
}
|
||||
@@ -451,7 +486,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
|
||||
if (rsp_count > actual) {
|
||||
/* cache the rsp and generate a continuation state */
|
||||
- cStateId = sdp_cstate_alloc_buf(buf);
|
||||
+ cStateId = sdp_cstate_alloc_buf(req, buf);
|
||||
/*
|
||||
* subtract handleSize since we now send only
|
||||
* a subset of handles
|
||||
@@ -459,6 +494,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
buf->data_size -= handleSize;
|
||||
} else {
|
||||
/* NULL continuation state */
|
||||
+ sdp_cont_info_free(cinfo);
|
||||
sdp_set_cstate_pdu(buf, NULL);
|
||||
}
|
||||
}
|
||||
@@ -468,13 +504,15 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
short lastIndex = 0;
|
||||
|
||||
if (cstate) {
|
||||
- /*
|
||||
- * Get the previous sdp_cont_state_t and obtain
|
||||
- * the cached rsp
|
||||
- */
|
||||
- sdp_buf_t *pCache = sdp_get_cached_rsp(cstate);
|
||||
- if (pCache) {
|
||||
- pCacheBuffer = pCache->data;
|
||||
+ if (cinfo) {
|
||||
+ /* Check if requesting more than available */
|
||||
+ if (cstate->cStateValue.maxBytesSent >=
|
||||
+ cinfo->buf.data_size) {
|
||||
+ status = SDP_INVALID_CSTATE;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ pCacheBuffer = cinfo->buf.data;
|
||||
/* get the rsp_count from the cached buffer */
|
||||
rsp_count = get_be16(pCacheBuffer);
|
||||
|
||||
@@ -518,6 +556,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
if (i == rsp_count) {
|
||||
/* set "null" continuationState */
|
||||
sdp_set_cstate_pdu(buf, NULL);
|
||||
+ sdp_cont_info_free(cinfo);
|
||||
} else {
|
||||
/*
|
||||
* there's more: set lastIndexSent to
|
||||
@@ -540,6 +579,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
|
||||
done:
|
||||
free(cstate);
|
||||
+
|
||||
if (pattern)
|
||||
sdp_list_free(pattern, free);
|
||||
|
||||
@@ -619,15 +659,21 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, sdp_buf_t *buf)
|
||||
}
|
||||
|
||||
/* Build cstate response */
|
||||
-static int sdp_cstate_rsp(sdp_cont_state_t *cstate, sdp_buf_t *buf,
|
||||
- uint16_t max)
|
||||
+static int sdp_cstate_rsp(sdp_cont_info_t *cinfo, sdp_cont_state_t *cstate,
|
||||
+ sdp_buf_t *buf, uint16_t max)
|
||||
{
|
||||
- /* continuation State exists -> get from cache */
|
||||
- sdp_buf_t *cache = sdp_get_cached_rsp(cstate);
|
||||
+ sdp_buf_t *cache;
|
||||
uint16_t sent;
|
||||
|
||||
- if (!cache)
|
||||
+ if (!cinfo)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (cstate->cStateValue.maxBytesSent >= cinfo->buf.data_size) {
|
||||
+ sdp_cont_info_free(cinfo);
|
||||
return 0;
|
||||
+ }
|
||||
+
|
||||
+ cache = &cinfo->buf;
|
||||
|
||||
sent = MIN(max, cache->data_size - cstate->cStateValue.maxBytesSent);
|
||||
memcpy(buf->data, cache->data + cstate->cStateValue.maxBytesSent, sent);
|
||||
@@ -637,8 +683,10 @@ static int sdp_cstate_rsp(sdp_cont_state_t *cstate, sdp_buf_t *buf,
|
||||
SDPDBG("Response size : %d sending now : %d bytes sent so far : %d",
|
||||
cache->data_size, sent, cstate->cStateValue.maxBytesSent);
|
||||
|
||||
- if (cstate->cStateValue.maxBytesSent == cache->data_size)
|
||||
+ if (cstate->cStateValue.maxBytesSent == cache->data_size) {
|
||||
+ sdp_cont_info_free(cinfo);
|
||||
return sdp_set_cstate_pdu(buf, NULL);
|
||||
+ }
|
||||
|
||||
return sdp_set_cstate_pdu(buf, cstate);
|
||||
}
|
||||
@@ -652,6 +700,7 @@ static int sdp_cstate_rsp(sdp_cont_state_t *cstate, sdp_buf_t *buf,
|
||||
static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
{
|
||||
sdp_cont_state_t *cstate = NULL;
|
||||
+ sdp_cont_info_t *cinfo = NULL;
|
||||
short cstate_size = 0;
|
||||
sdp_list_t *seq = NULL;
|
||||
uint8_t dtd = 0;
|
||||
@@ -708,7 +757,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
* if continuation state exists, attempt
|
||||
* to get rsp remainder from cache, else send error
|
||||
*/
|
||||
- if (sdp_cstate_get(pdata, data_left, &cstate) < 0) {
|
||||
+ if (sdp_cstate_get(req, pdata, data_left, &cstate, &cinfo) < 0) {
|
||||
status = SDP_INVALID_SYNTAX;
|
||||
goto done;
|
||||
}
|
||||
@@ -737,7 +786,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
buf->buf_size -= sizeof(uint16_t);
|
||||
|
||||
if (cstate) {
|
||||
- cstate_size = sdp_cstate_rsp(cstate, buf, max_rsp_size);
|
||||
+ cstate_size = sdp_cstate_rsp(cinfo, cstate, buf, max_rsp_size);
|
||||
if (!cstate_size) {
|
||||
status = SDP_INVALID_CSTATE;
|
||||
error("NULL cache buffer and non-NULL continuation state");
|
||||
@@ -749,7 +798,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
sdp_cont_state_t newState;
|
||||
|
||||
memset((char *)&newState, 0, sizeof(sdp_cont_state_t));
|
||||
- newState.timestamp = sdp_cstate_alloc_buf(buf);
|
||||
+ newState.timestamp = sdp_cstate_alloc_buf(req, buf);
|
||||
/*
|
||||
* Reset the buffer size to the maximum expected and
|
||||
* set the sdp_cont_state_t
|
||||
@@ -793,6 +842,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
int scanned, rsp_count = 0;
|
||||
sdp_list_t *pattern = NULL, *seq = NULL, *svcList;
|
||||
sdp_cont_state_t *cstate = NULL;
|
||||
+ sdp_cont_info_t *cinfo = NULL;
|
||||
short cstate_size = 0;
|
||||
uint8_t dtd = 0;
|
||||
sdp_buf_t tmpbuf;
|
||||
@@ -852,7 +902,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
* if continuation state exists attempt
|
||||
* to get rsp remainder from cache, else send error
|
||||
*/
|
||||
- if (sdp_cstate_get(pdata, data_left, &cstate) < 0) {
|
||||
+ if (sdp_cstate_get(req, pdata, data_left, &cstate, &cinfo) < 0) {
|
||||
status = SDP_INVALID_SYNTAX;
|
||||
goto done;
|
||||
}
|
||||
@@ -906,7 +956,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
sdp_cont_state_t newState;
|
||||
|
||||
memset((char *)&newState, 0, sizeof(sdp_cont_state_t));
|
||||
- newState.timestamp = sdp_cstate_alloc_buf(buf);
|
||||
+ newState.timestamp = sdp_cstate_alloc_buf(req, buf);
|
||||
/*
|
||||
* Reset the buffer size to the maximum expected and
|
||||
* set the sdp_cont_state_t
|
||||
@@ -917,7 +967,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf)
|
||||
} else
|
||||
cstate_size = sdp_set_cstate_pdu(buf, NULL);
|
||||
} else {
|
||||
- cstate_size = sdp_cstate_rsp(cstate, buf, max);
|
||||
+ cstate_size = sdp_cstate_rsp(cinfo, cstate, buf, max);
|
||||
if (!cstate_size) {
|
||||
status = SDP_INVALID_CSTATE;
|
||||
SDPDBG("Non-null continuation state, but null cache buffer");
|
||||
@@ -974,6 +1024,9 @@ static void process_request(sdp_req_t *req)
|
||||
status = SDP_INVALID_PDU_SIZE;
|
||||
goto send_rsp;
|
||||
}
|
||||
+
|
||||
+ req->opcode = reqhdr->pdu_id;
|
||||
+
|
||||
switch (reqhdr->pdu_id) {
|
||||
case SDP_SVC_SEARCH_REQ:
|
||||
SDPDBG("Got a svc srch req");
|
||||
@@ -1020,6 +1073,8 @@ static void process_request(sdp_req_t *req)
|
||||
|
||||
send_rsp:
|
||||
if (status) {
|
||||
+ /* Cleanup cstates on error */
|
||||
+ sdp_cstate_cleanup(req->sock);
|
||||
rsphdr->pdu_id = SDP_ERROR_RSP;
|
||||
put_be16(status, rsp.data);
|
||||
rsp.data_size = sizeof(uint16_t);
|
||||
@@ -1108,3 +1163,20 @@ void handle_request(int sk, uint8_t *data, int len)
|
||||
|
||||
process_request(&req);
|
||||
}
|
||||
+
|
||||
+void sdp_cstate_cleanup(int sock)
|
||||
+{
|
||||
+ sdp_list_t *list;
|
||||
+
|
||||
+ /* Remove any cinfo for the client */
|
||||
+ for (list = cstates; list;) {
|
||||
+ sdp_cont_info_t *cinfo = list->data;
|
||||
+
|
||||
+ list = list->next;
|
||||
+
|
||||
+ if (cinfo->sock != sock)
|
||||
+ continue;
|
||||
+
|
||||
+ sdp_cont_info_free(cinfo);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/sdpd-server.c b/src/sdpd-server.c
|
||||
index dfd8b1f00..66ee7ba14 100644
|
||||
--- a/src/sdpd-server.c
|
||||
+++ b/src/sdpd-server.c
|
||||
@@ -146,16 +146,12 @@ static gboolean io_session_event(GIOChannel *chan, GIOCondition cond, gpointer d
|
||||
|
||||
sk = g_io_channel_unix_get_fd(chan);
|
||||
|
||||
- if (cond & (G_IO_HUP | G_IO_ERR)) {
|
||||
- sdp_svcdb_collect_all(sk);
|
||||
- return FALSE;
|
||||
- }
|
||||
+ if (cond & (G_IO_HUP | G_IO_ERR))
|
||||
+ goto cleanup;
|
||||
|
||||
len = recv(sk, &hdr, sizeof(sdp_pdu_hdr_t), MSG_PEEK);
|
||||
- if (len < 0 || (unsigned int) len < sizeof(sdp_pdu_hdr_t)) {
|
||||
- sdp_svcdb_collect_all(sk);
|
||||
- return FALSE;
|
||||
- }
|
||||
+ if (len < 0 || (unsigned int) len < sizeof(sdp_pdu_hdr_t))
|
||||
+ goto cleanup;
|
||||
|
||||
size = sizeof(sdp_pdu_hdr_t) + ntohs(hdr.plen);
|
||||
buf = malloc(size);
|
||||
@@ -168,14 +164,18 @@ static gboolean io_session_event(GIOChannel *chan, GIOCondition cond, gpointer d
|
||||
* inside handle_request() in order to produce ErrorResponse.
|
||||
*/
|
||||
if (len <= 0) {
|
||||
- sdp_svcdb_collect_all(sk);
|
||||
free(buf);
|
||||
- return FALSE;
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
handle_request(sk, buf, len);
|
||||
|
||||
return TRUE;
|
||||
+
|
||||
+cleanup:
|
||||
+ sdp_svcdb_collect_all(sk);
|
||||
+ sdp_cstate_cleanup(sk);
|
||||
+ return FALSE;
|
||||
}
|
||||
|
||||
static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer data)
|
||||
diff --git a/src/sdpd.h b/src/sdpd.h
|
||||
index 257411f03..4316aff67 100644
|
||||
--- a/src/sdpd.h
|
||||
+++ b/src/sdpd.h
|
||||
@@ -27,8 +27,11 @@ typedef struct request {
|
||||
int flags;
|
||||
uint8_t *buf;
|
||||
int len;
|
||||
+ uint8_t opcode;
|
||||
} sdp_req_t;
|
||||
|
||||
+void sdp_cstate_cleanup(int sock);
|
||||
+
|
||||
void handle_internal_request(int sk, int mtu, void *data, int len);
|
||||
void handle_request(int sk, uint8_t *data, int len);
|
||||
|
||||
diff --git a/unit/test-sdp.c b/unit/test-sdp.c
|
||||
index d3a885f19..8f95fcb71 100644
|
||||
--- a/unit/test-sdp.c
|
||||
+++ b/unit/test-sdp.c
|
||||
@@ -235,7 +235,7 @@ static gboolean client_handler(GIOChannel *channel, GIOCondition cond,
|
||||
tester_monitor('>', 0x0000, 0x0001, buf, len);
|
||||
|
||||
g_assert(len > 0);
|
||||
- g_assert((size_t) len == rsp_pdu->raw_size + rsp_pdu->cont_len);
|
||||
+ g_assert_cmpuint(len, ==, rsp_pdu->raw_size + rsp_pdu->cont_len);
|
||||
|
||||
g_assert(memcmp(buf, rsp_pdu->raw_data, rsp_pdu->raw_size) == 0);
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
33
SOURCES/69-btattach-bcm.rules
Normal file
33
SOURCES/69-btattach-bcm.rules
Normal file
@ -0,0 +1,33 @@
|
||||
# Some devices have a bluetooth HCI connected to an uart, these needs to be
|
||||
# setup by calling btattach. The systemd btattach-bcm.service takes care of
|
||||
# this. These udev rules hardware-activate that service when necessary.
|
||||
#
|
||||
# For now this only suports ACPI enumerated Broadcom BT HCIs.
|
||||
# This has been tested on Bay and Cherry Trail devices with both ACPI and
|
||||
# PCI enumerated UARTs.
|
||||
|
||||
# Note we check for the platform device not for the acpi device, because
|
||||
# some DSDTs list multiple bluetooth adapters, but only some (or none)
|
||||
# are enabled. Only enabled adapters get a platform device created.
|
||||
ACTION!="add", GOTO="btattach_bcm_rules_end"
|
||||
SUBSYSTEM!="platform", GOTO="btattach_bcm_rules_end"
|
||||
|
||||
KERNEL=="BCM2E1A:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E39:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E3A:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E3D:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E3F:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E40:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E54:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E55:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E64:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E65:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E67:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E71:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E7B:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E7C:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E7E:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E95:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
KERNEL=="BCM2E96:00", TAG+="systemd", ENV{SYSTEMD_WANTS}="btattach-bcm@%k.service"
|
||||
|
||||
LABEL="btattach_bcm_rules_end"
|
100
SOURCES/bluez.gitignore
Normal file
100
SOURCES/bluez.gitignore
Normal file
@ -0,0 +1,100 @@
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
*.so
|
||||
.deps
|
||||
.libs
|
||||
.dirstamp
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
compile
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
stamp-h1
|
||||
autom4te.cache
|
||||
|
||||
ylwrap
|
||||
lexer.c
|
||||
parser.h
|
||||
parser.c
|
||||
|
||||
bluez.pc
|
||||
lib/bluetooth
|
||||
src/builtin.h
|
||||
src/bluetoothd
|
||||
audio/telephony.c
|
||||
sap/sap.c
|
||||
scripts/bluetooth.rules
|
||||
scripts/97-bluetooth.rules
|
||||
scripts/97-bluetooth-hid2hci.rules
|
||||
|
||||
sbc/sbcdec
|
||||
sbc/sbcenc
|
||||
sbc/sbcinfo
|
||||
sbc/sbctester
|
||||
|
||||
attrib/gatttool
|
||||
tools/avctrl
|
||||
tools/avinfo
|
||||
tools/bccmd
|
||||
tools/ciptool
|
||||
tools/dfubabel
|
||||
tools/dfutool
|
||||
tools/hciattach
|
||||
tools/hciconfig
|
||||
tools/hcieventmask
|
||||
tools/hcisecfilter
|
||||
tools/hcitool
|
||||
tools/hid2hci
|
||||
tools/rfcomm
|
||||
tools/l2ping
|
||||
tools/ppporc
|
||||
tools/sdptool
|
||||
cups/bluetooth
|
||||
test/agent
|
||||
test/bdaddr
|
||||
test/hciemu
|
||||
test/attest
|
||||
test/hstest
|
||||
test/avtest
|
||||
test/l2test
|
||||
test/rctest
|
||||
test/scotest
|
||||
test/gaptest
|
||||
test/sdptest
|
||||
test/lmptest
|
||||
test/ipctest
|
||||
test/btiotest
|
||||
test/test-textfile
|
||||
test/uuidtest
|
||||
test/mpris-player
|
||||
compat/dund
|
||||
compat/hidd
|
||||
compat/pand
|
||||
unit/test-eir
|
||||
mgmt/btmgmt
|
||||
monitor/btmon
|
||||
emulator/btvirt
|
||||
|
||||
doc/*.bak
|
||||
doc/*.stamp
|
||||
doc/bluez.*
|
||||
doc/bluez-*.txt
|
||||
doc/*.sgml
|
||||
doc/version.xml
|
||||
doc/xml
|
||||
doc/html
|
||||
src/bluetoothd.8
|
||||
src/bluetooth.service
|
30
SOURCES/btattach-bcm-service.sh
Normal file
30
SOURCES/btattach-bcm-service.sh
Normal file
@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Simple shell script to wait for the tty for an uart using BT HCI to show up
|
||||
# and then invoke btattach with the right parameters, this is intended to be
|
||||
# invoked from a hardware-activated systemd service
|
||||
#
|
||||
# For now this only suports ACPI enumerated Broadcom BT HCIs.
|
||||
# This has been tested on Bay and Cherry Trail devices with both ACPI and
|
||||
# PCI enumerated UARTs.
|
||||
#
|
||||
# Note the kernel bt developers are working on solving this entirely in the
|
||||
# kernel, so it is not worth the trouble to write something better then this.
|
||||
|
||||
BT_DEV="/sys/bus/platform/devices/$1"
|
||||
BT_DEV="$(readlink -f $BT_DEV)"
|
||||
UART_DEV="$(dirname $BT_DEV)"
|
||||
|
||||
# Stupid GPD-pocket has USB BT with id 0000:0000, but still claims to have
|
||||
# an uart attached bt
|
||||
if [ "$1" = "BCM2E7E:00" ] && lsusb | grep -q "ID 0000:0000"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
while [ ! -d "$UART_DEV/tty" ]; do
|
||||
sleep .2
|
||||
done
|
||||
|
||||
TTY="$(ls $UART_DEV/tty)"
|
||||
|
||||
exec btattach --bredr "/dev/$TTY" -P bcm
|
6
SOURCES/btattach-bcm@.service
Normal file
6
SOURCES/btattach-bcm@.service
Normal file
@ -0,0 +1,6 @@
|
||||
[Unit]
|
||||
Description=btattach for Broadcom devices
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/libexec/bluetooth/btattach-bcm-service.sh %I
|
@ -1,7 +1,7 @@
|
||||
Name: bluez
|
||||
Summary: Bluetooth utilities
|
||||
Version: 5.56
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
License: GPLv2+
|
||||
URL: http://www.bluez.org/
|
||||
|
||||
@ -46,6 +46,8 @@ Patch24: 0001-adapter-Don-t-refresh-adv_manager-for-non-LE-devices.patch
|
||||
# fixing https://bugzilla.redhat.com/show_bug.cgi?id=1965057
|
||||
Patch31: 0001-shared-gatt-server-Fix-not-properly-checking-for-sec.patch
|
||||
|
||||
Patch32: 0001-sdpd-Fix-leaking-buffers-stored-in-cstates-cache.patch
|
||||
|
||||
BuildRequires: git-core
|
||||
BuildRequires: dbus-devel >= 1.6
|
||||
BuildRequires: glib2-devel
|
||||
@ -279,6 +281,11 @@ make check
|
||||
|
||||
%changelog
|
||||
|
||||
* Wed Dec 13 2021 Gopal Tiwari <gtiwari@redhat.com> - 5.56-3
|
||||
+ bluez-5.56-3
|
||||
- Fixing (#2027434)
|
||||
- Fixing CVE-2021-41229
|
||||
|
||||
* Mon Jun 7 2021 Gopal Tiwari <gtiwari@redhat.com> - 5.56-2
|
||||
+ bluez-5.56-2
|
||||
- Fixing (#1968392)
|
||||
|
Loading…
Reference in New Issue
Block a user