Auto sync2gitlab import of bluez-5.56-3.el8.src.rpm

This commit is contained in:
James Antill 2022-05-26 00:58:11 -04:00
parent 9dd695d960
commit 07d871f3d1
17 changed files with 2178 additions and 1 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/bluez-5.56.tar.xz

View File

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

View File

@ -0,0 +1,41 @@
From 5a62336f4da3a2d1a1ab38d03980d57844bce147 Mon Sep 17 00:00:00 2001
From: Gopal Tiwari <gtiwari@redhat.com>
Date: Mon, 8 Jun 2020 20:56:46 +0530
Subject: [PATCH BlueZ 1/4] build: Always define confdir and statedir
From 69d2e7bebb79f500179298c6c51fafbc217df6c8 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Wed, 20 Sep 2017 12:49:10 +0200
build: Always define confdir and statedir
As we will need those paths to lock down on them.
---
Makefile.am | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 84c9712c9..6e77ed91e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,14 +31,15 @@ pkginclude_HEADERS =
AM_CFLAGS = $(WARNING_CFLAGS) $(MISC_CFLAGS) $(UDEV_CFLAGS) $(ell_cflags)
AM_LDFLAGS = $(MISC_LDFLAGS)
+confdir = $(sysconfdir)/bluetooth
+statedir = $(localstatedir)/lib/bluetooth
+
if DATAFILES
dbusdir = $(DBUS_CONFDIR)/dbus-1/system.d
dbus_DATA = src/bluetooth.conf
-confdir = $(sysconfdir)/bluetooth
conf_DATA =
-statedir = $(localstatedir)/lib/bluetooth
state_DATA =
endif
--
2.21.1

View File

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

View File

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

View File

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

View File

@ -0,0 +1,115 @@
From d22177efb6f17ed281013cdfa4976d218718d5b6 Mon Sep 17 00:00:00 2001
From: Gopal Tiwari <gtiwari@redhat.com>
Date: Mon, 31 May 2021 12:29:01 +0530
Subject: [PATCH BlueZ] shared/gatt-server: Fix not properly checking for
secure flags
commit ef7316b34cf3a568694bdb0e4e83af17804dff9e (HEAD)
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Tue Mar 2 11:38:33 2021 -0800
shared/gatt-server: Fix not properly checking for secure flags
When passing the mask to check_permissions all valid permissions for
the operation must be set including BT_ATT_PERM_SECURE flags.
(cherry picked from commit 00da0fb4972cf59e1c075f313da81ea549cb8738)
Signed-off-by: Gopal Tiwari <gtiwari@redhat.com>
---
src/shared/att-types.h | 8 ++++++++
src/shared/gatt-server.c | 25 +++++++------------------
2 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/src/shared/att-types.h b/src/shared/att-types.h
index 7108b4e94..3adc05d9e 100644
--- a/src/shared/att-types.h
+++ b/src/shared/att-types.h
@@ -129,6 +129,14 @@ struct bt_att_pdu_error_rsp {
#define BT_ATT_PERM_WRITE_SECURE 0x0200
#define BT_ATT_PERM_SECURE (BT_ATT_PERM_READ_SECURE | \
BT_ATT_PERM_WRITE_SECURE)
+#define BT_ATT_PERM_READ_MASK (BT_ATT_PERM_READ | \
+ BT_ATT_PERM_READ_AUTHEN | \
+ BT_ATT_PERM_READ_ENCRYPT | \
+ BT_ATT_PERM_READ_SECURE)
+#define BT_ATT_PERM_WRITE_MASK (BT_ATT_PERM_WRITE | \
+ BT_ATT_PERM_WRITE_AUTHEN | \
+ BT_ATT_PERM_WRITE_ENCRYPT | \
+ BT_ATT_PERM_WRITE_SECURE)
/* GATT Characteristic Properties Bitfield values */
#define BT_GATT_CHRC_PROP_BROADCAST 0x01
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index b5f7de7dc..970c35f94 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -444,9 +444,7 @@ static void process_read_by_type(struct async_read_op *op)
return;
}
- ecode = check_permissions(server, attr, BT_ATT_PERM_READ |
- BT_ATT_PERM_READ_AUTHEN |
- BT_ATT_PERM_READ_ENCRYPT);
+ ecode = check_permissions(server, attr, BT_ATT_PERM_READ_MASK);
if (ecode)
goto error;
@@ -811,9 +809,7 @@ static void write_cb(struct bt_att_chan *chan, uint8_t opcode, const void *pdu,
(opcode == BT_ATT_OP_WRITE_REQ) ? "Req" : "Cmd",
handle);
- ecode = check_permissions(server, attr, BT_ATT_PERM_WRITE |
- BT_ATT_PERM_WRITE_AUTHEN |
- BT_ATT_PERM_WRITE_ENCRYPT);
+ ecode = check_permissions(server, attr, BT_ATT_PERM_WRITE_MASK);
if (ecode)
goto error;
@@ -913,9 +909,7 @@ static void handle_read_req(struct bt_att_chan *chan,
opcode == BT_ATT_OP_READ_BLOB_REQ ? "Blob " : "",
handle);
- ecode = check_permissions(server, attr, BT_ATT_PERM_READ |
- BT_ATT_PERM_READ_AUTHEN |
- BT_ATT_PERM_READ_ENCRYPT);
+ ecode = check_permissions(server, attr, BT_ATT_PERM_READ_MASK);
if (ecode)
goto error;
@@ -1051,9 +1045,8 @@ static void read_multiple_complete_cb(struct gatt_db_attribute *attr, int err,
goto error;
}
- ecode = check_permissions(data->server, next_attr, BT_ATT_PERM_READ |
- BT_ATT_PERM_READ_AUTHEN |
- BT_ATT_PERM_READ_ENCRYPT);
+ ecode = check_permissions(data->server, next_attr,
+ BT_ATT_PERM_READ_MASK);
if (ecode)
goto error;
@@ -1129,9 +1122,7 @@ static void read_multiple_cb(struct bt_att_chan *chan, uint8_t opcode,
goto error;
}
- ecode = check_permissions(data->server, attr, BT_ATT_PERM_READ |
- BT_ATT_PERM_READ_AUTHEN |
- BT_ATT_PERM_READ_ENCRYPT);
+ ecode = check_permissions(data->server, attr, BT_ATT_PERM_READ_MASK);
if (ecode)
goto error;
@@ -1308,9 +1299,7 @@ static void prep_write_cb(struct bt_att_chan *chan, uint8_t opcode,
util_debug(server->debug_callback, server->debug_data,
"Prep Write Req - handle: 0x%04x", handle);
- ecode = check_permissions(server, attr, BT_ATT_PERM_WRITE |
- BT_ATT_PERM_WRITE_AUTHEN |
- BT_ATT_PERM_WRITE_ENCRYPT);
+ ecode = check_permissions(server, attr, BT_ATT_PERM_WRITE_MASK);
if (ecode)
goto error;
--
2.26.2

View File

@ -0,0 +1,44 @@
From 98826d0717fe831265256f996c9e90d15262bef1 Mon Sep 17 00:00:00 2001
From: Gopal Tiwari <gtiwari@redhat.com>
Date: Mon, 8 Jun 2020 19:54:24 +0530
Subject: [PATCH BlueZ 2/4] systemd: Add PrivateTmp and NoNewPrivileges options
From 4570164f0c90603bd07eb9e7c07e17bbafb5b5da Mon Sep 17 00:00:00 2001
From: Craig Andrews <candrews@integralblue.com>
Date: Wed, 13 Sep 2017 15:23:09 +0200
systemd: Add PrivateTmp and NoNewPrivileges options
PrivateTmp makes bluetoothd's /tmp and /var/tmp be inside a different
namespace. This is useful to secure access to temporary files of the
process.
NoNewPrivileges ensures that service process and all its children
can never gain new privileges through execve(), lowering the risk of
possible privilege escalations.
---
src/bluetooth.service.in | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/bluetooth.service.in b/src/bluetooth.service.in
index f9faaa452..7c2f60bb4 100644
--- a/src/bluetooth.service.in
+++ b/src/bluetooth.service.in
@@ -12,8 +12,14 @@ NotifyAccess=main
#Restart=on-failure
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
LimitNPROC=1
+
+# Filesystem lockdown
ProtectHome=true
ProtectSystem=full
+PrivateTmp=true
+
+# Privilege escalation
+NoNewPrivileges=true
[Install]
WantedBy=bluetooth.target
--
2.21.1

View File

@ -0,0 +1,49 @@
From 1da4185a89fba1c14032ab87757e5fb798d76bc0 Mon Sep 17 00:00:00 2001
From: Gopal Tiwari <gtiwari@redhat.com>
Date: Mon, 8 Jun 2020 19:55:39 +0530
Subject: [PATCH BlueZ 3/4] systemd: Add more filesystem lockdown
From 73a9c0902e7c97adf96e735407a75033152c04a9 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Wed, 13 Sep 2017 15:37:11 +0200
systemd: Add more filesystem lockdown
We can only access the configuration file as read-only and read-write
to the Bluetooth cache directory and sub-directories.
---
Makefile.am | 2 ++
src/bluetooth.service.in | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index cdd2fd8fb..0af1a8c45 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -580,6 +580,8 @@ MAINTAINERCLEANFILES = Makefile.in \
SED_PROCESS = $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
$(SED) -e 's,@pkglibexecdir\@,$(pkglibexecdir),g' \
+ -e 's,@statedir\@,$(statedir),g' \
+ -e 's,@confdir\@,$(confdir),g' \
< $< > $@
%.service: %.service.in Makefile
diff --git a/src/bluetooth.service.in b/src/bluetooth.service.in
index 7c2f60bb4..4daedef2a 100644
--- a/src/bluetooth.service.in
+++ b/src/bluetooth.service.in
@@ -17,6 +17,10 @@ LimitNPROC=1
ProtectHome=true
ProtectSystem=full
PrivateTmp=true
+ProtectKernelTunables=true
+ProtectControlGroups=true
+ReadWritePaths=@statedir@
+ReadOnlyPaths=@confdir@
# Privilege escalation
NoNewPrivileges=true
--
2.21.1

View File

@ -0,0 +1,40 @@
From 9a7872f04cb748e8de743d9136ecd91539d13cb7 Mon Sep 17 00:00:00 2001
From: Gopal Tiwari <gtiwari@redhat.com>
Date: Mon, 8 Jun 2020 19:56:42 +0530
Subject: [PATCH BlueZ 4/4] systemd: More lockdown
From 171d812218883281fed57b57fafd5c18eac441ac Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Wed, 13 Sep 2017 15:38:26 +0200
systemd: More lockdown
bluetoothd does not need to execute mapped memory, or real-time
access, so block those.
---
src/bluetooth.service.in | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/bluetooth.service.in b/src/bluetooth.service.in
index 4daedef2a..f18801866 100644
--- a/src/bluetooth.service.in
+++ b/src/bluetooth.service.in
@@ -22,9 +22,15 @@ ProtectControlGroups=true
ReadWritePaths=@statedir@
ReadOnlyPaths=@confdir@
+# Execute Mappings
+MemoryDenyWriteExecute=true
+
# Privilege escalation
NoNewPrivileges=true
+# Real-time
+RestrictRealtime=true
+
[Install]
WantedBy=bluetooth.target
Alias=dbus-org.bluez.service
--
2.21.1

33
69-btattach-bcm.rules Normal file
View 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"

1
EMPTY
View File

@ -1 +0,0 @@

100
bluez.gitignore Normal file
View 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

1123
bluez.spec Normal file

File diff suppressed because it is too large Load Diff

30
btattach-bcm-service.sh Normal file
View 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
btattach-bcm@.service Normal file
View File

@ -0,0 +1,6 @@
[Unit]
Description=btattach for Broadcom devices
[Service]
Type=simple
ExecStart=/usr/libexec/bluetooth/btattach-bcm-service.sh %I

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (bluez-5.56.tar.xz) = b320ee9d49a516f5cecb5fbc410ba42e9127f44ebcfb95647f68bd5d300147d0eaf633f8e8d0678631a2184ea3afae7b01b5f228157328874fa2a87832ed0ae1