!110 update to 5.71

From: @zppzhangpan 
Reviewed-by: @yanan-rock 
Signed-off-by: @yanan-rock
This commit is contained in:
openeuler-ci-bot 2024-02-01 10:03:06 +00:00 committed by Gitee
commit 188827b676
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
26 changed files with 11 additions and 2448 deletions

View File

@ -1,35 +0,0 @@
From 5744f79d84ecee3929a682166034c5bbc36c0ef5 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Wed, 20 Sep 2017 12:49:10 +0200
Subject: [PATCH 1/4] build: Always define confdir and statedir
As we will need those paths to lock down on them.
---
Makefile.am | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 9d25a815b..ac88c12e0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,14 +31,14 @@ 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.0

View File

@ -1,38 +0,0 @@
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

@ -1,38 +0,0 @@
From 36a44fc05feebe1aab16c33a1121f952986b2801 Mon Sep 17 00:00:00 2001
From: Craig Andrews <candrews@integralblue.com>
Date: Wed, 13 Sep 2017 15:23:09 +0200
Subject: [PATCH 2/4] 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.0

View File

@ -1,44 +0,0 @@
From 13a348670fef0047555395ce6977e86e0005f8bd Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Wed, 13 Sep 2017 15:37:11 +0200
Subject: [PATCH 3/4] 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 | 3 +++
src/bluetooth.service.in | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index ac88c12e0..0a6d09847 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -562,6 +562,9 @@ MAINTAINERCLEANFILES = Makefile.in \
SED_PROCESS = $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
$(SED) -e 's,@pkglibexecdir\@,$(pkglibexecdir),g' \
+ -e 's,@libexecdir\@,$(libexecdir),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.0

View File

@ -1,34 +0,0 @@
From a6963e0402695d7b6a89c1b1c75c40dbd8fcde52 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Wed, 13 Sep 2017 15:38:26 +0200
Subject: [PATCH 4/4] 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.0

View File

@ -1,71 +0,0 @@
From d676c4ddcb569234c6ce499732bb5fbe76ba14ac Mon Sep 17 00:00:00 2001
From: Szymon Janc <szymon.janc@codecoup.pl>
Date: Tue, 31 Mar 2020 12:45:32 +0200
Subject: [PATCH] shared/gatt: Fix NULL pointer dereference
bluetoothd[363094]: src/device.c:device_connect_le() Connection attempt to: 00:AA:01:00:00:23
Program received signal SIGSEGV, Segmentation fault.
write_complete_cb (attr=0x55555580aa30, err=-110, user_data=0x55555585f7c0) at src/shared/gatt-server.c:793
793 util_debug(server->debug_callback, server->debug_data,
(gdb) bt
#0 write_complete_cb (attr=0x55555580aa30, err=-110, user_data=0x55555585f7c0) at src/shared/gatt-server.c:793
#1 0x00005555556a5852 in pending_write_result (p=0x555555866030, err=<optimized out>) at src/shared/gatt-db.c:162
#2 0x00005555556a5ac7 in write_timeout (user_data=0x555555866030) at src/shared/gatt-db.c:1879
#3 0x00005555556a9b15 in timeout_callback (user_data=user_data@entry=0x555555864b20) at src/shared/timeout-glib.c:34
#4 0x00007ffff7e1f081 in g_timeout_dispatch (source=source@entry=0x555555864f00, callback=0x5555556a9b00 <timeout_callback>, user_data=0x555555864b20) at ../glib/gmain.c:4705
#5 0x00007ffff7e1e570 in g_main_dispatch (context=0x5555557d9630) at ../glib/gmain.c:3216
#6 g_main_context_dispatch (context=context@entry=0x5555557d9630) at ../glib/gmain.c:3881
#7 0x00007ffff7e1e900 in g_main_context_iterate (context=0x5555557d9630, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:3954
#8 0x00007ffff7e1ebf3 in g_main_loop_run (loop=0x5555557d75d0) at ../glib/gmain.c:4148
#9 0x00005555556a9dbd in mainloop_run () at src/shared/mainloop-glib.c:79
#10 0x00005555556aa36a in mainloop_run_with_signal (func=<optimized out>, user_data=0x0) at src/shared/mainloop-notify.c:201
#11 0x00005555555bb9e3 in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:770
Conflict:NA
Reference:https://github.com/bluez/bluez/commit/d676c4ddcb569234c6ce499732bb5fbe76ba14ac
---
src/shared/gatt-server.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 7e5d652e42..4e07398d21 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -790,14 +790,14 @@ static void write_complete_cb(struct gatt_db_attribute *attr, int err,
struct bt_gatt_server *server = op->server;
uint16_t handle;
- util_debug(server->debug_callback, server->debug_data,
- "Write Complete: err %d", err);
-
if (!server || op->opcode == BT_ATT_OP_WRITE_CMD) {
async_write_op_destroy(op);
return;
}
+ util_debug(server->debug_callback, server->debug_data,
+ "Write Complete: err %d", err);
+
handle = gatt_db_attribute_get_handle(attr);
if (err)
@@ -914,14 +914,14 @@ static void read_complete_cb(struct gatt_db_attribute *attr, int err,
uint16_t mtu;
uint16_t handle;
- util_debug(server->debug_callback, server->debug_data,
- "Read Complete: err %d", err);
-
if (!server) {
async_read_op_destroy(op);
return;
}
+ util_debug(server->debug_callback, server->debug_data,
+ "Read Complete: err %d", err);
+
mtu = bt_att_get_mtu(server->att);
handle = gatt_db_attribute_get_handle(attr);

View File

@ -1,193 +0,0 @@
From 0ce535ecb2bb58079513ccbd1fe086409c77beb8 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Thu, 11 Jun 2020 13:23:06 -0700
Subject: [PATCH] adapter: Rename watch_client to discovery_client
watch term is quite vague so this replace it with discovery which is
what is used for the filter as well.
Conflict:NA
Reference:https://github.com/bluez/bluez/commit/0ce535ecb2bb58079513ccbd1fe086409c77beb8
---
src/adapter.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 972d887..160f199 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -182,7 +182,7 @@ struct discovery_filter {
bool discoverable;
};
-struct watch_client {
+struct discovery_client {
struct btd_adapter *adapter;
DBusMessage *msg;
char *owner;
@@ -1474,7 +1474,7 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
struct btd_adapter *adapter = user_data;
- struct watch_client *client;
+ struct discovery_client *client;
const struct mgmt_cp_start_discovery *rp = param;
DBusMessage *reply;
@@ -1851,8 +1851,8 @@ static void discovery_cleanup(struct btd_adapter *adapter)
static void discovery_free(void *user_data)
{
- struct watch_client *client = user_data;
+ struct discovery_client *client = user_data;
if (client->watch)
g_dbus_remove_watch(dbus_conn, client->watch);
@@ -1882,7 +1882,7 @@ static bool set_discovery_discoverable(struct btd_adapter *adapter, bool enable)
return set_discoverable(adapter, enable, 0);
}
-static void discovery_remove(struct watch_client *client, bool exit)
+static void discovery_remove(struct discovery_client *client, bool exit)
{
struct btd_adapter *adapter = client->adapter;
@@ -1913,7 +1913,7 @@ static void discovery_remove(struct watch_client *client, bool exit)
static void stop_discovery_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
- struct watch_client *client = user_data;
+ struct discovery_client *client = user_data;
struct btd_adapter *adapter = client->adapter;
DBusMessage *reply;
@@ -1949,7 +1949,7 @@ done:
static int compare_sender(gconstpointer a, gconstpointer b)
{
- const struct watch_client *client = a;
+ const struct discovery_client *client = a;
const char *sender = b;
return g_strcmp0(client->owner, sender);
@@ -1982,7 +1982,7 @@ static int merge_discovery_filters(struct btd_adapter *adapter, int *rssi,
bool has_filtered_discovery = false;
for (l = adapter->discovery_list; l != NULL; l = g_slist_next(l)) {
- struct watch_client *client = l->data;
+ struct discovery_client *client = l->data;
struct discovery_filter *item = client->discovery_filter;
if (!item) {
@@ -2149,7 +2149,7 @@ static int update_discovery_filter(struct btd_adapter *adapter)
}
for (l = adapter->discovery_list; l; l = g_slist_next(l)) {
- struct watch_client *client = l->data;
+ struct discovery_client *client = l->data;
if (!client->discovery_filter)
continue;
@@ -2179,7 +2179,7 @@ static int update_discovery_filter(struct btd_adapter *adapter)
return -EINPROGRESS;
}
-static int discovery_stop(struct watch_client *client, bool exit)
+static int discovery_stop(struct discovery_client *client, bool exit)
{
struct btd_adapter *adapter = client->adapter;
struct mgmt_cp_stop_discovery cp;
@@ -2220,7 +2220,7 @@ static int discovery_stop(struct watch_client *client, bool exit)
static void discovery_disconnect(DBusConnection *conn, void *user_data)
{
- struct watch_client *client = user_data;
+ struct discovery_client *client = user_data;
DBG("owner %s", client->owner);
@@ -2233,7 +2233,7 @@ static void discovery_disconnect(DBusConnection *conn, void *user_data)
*/
static bool get_discovery_client(struct btd_adapter *adapter,
const char *owner,
- struct watch_client **client)
+ struct discovery_client **client)
{
GSList *list = g_slist_find_custom(adapter->discovery_list, owner,
compare_sender);
@@ -2258,7 +2258,7 @@ static DBusMessage *start_discovery(DBusConnection *conn,
{
struct btd_adapter *adapter = user_data;
const char *sender = dbus_message_get_sender(msg);
- struct watch_client *client;
+ struct discovery_client *client;
bool is_discovering;
int err;
@@ -2292,7 +2292,7 @@ static DBusMessage *start_discovery(DBusConnection *conn,
goto done;
}
- client = g_new0(struct watch_client, 1);
+ client = g_new0(struct discovery_client, 1);
client->adapter = adapter;
client->owner = g_strdup(sender);
@@ -2556,7 +2556,7 @@ static DBusMessage *set_discovery_filter(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
struct btd_adapter *adapter = user_data;
- struct watch_client *client;
+ struct discovery_client *client;
struct discovery_filter *discovery_filter;
const char *sender = dbus_message_get_sender(msg);
bool is_discovering;
@@ -2593,7 +2593,7 @@ static DBusMessage *set_discovery_filter(DBusConnection *conn,
DBG("successfully cleared pre-set filter");
} else if (discovery_filter) {
/* Client pre-setting his filter for first time */
- client = g_new0(struct watch_client, 1);
+ client = g_new0(struct discovery_client, 1);
client->adapter = adapter;
client->owner = g_strdup(sender);
client->discovery_filter = discovery_filter;
@@ -2614,7 +2614,7 @@ static DBusMessage *stop_discovery(DBusConnection *conn,
{
struct btd_adapter *adapter = user_data;
const char *sender = dbus_message_get_sender(msg);
- struct watch_client *client;
+ struct discovery_client *client;
GSList *list;
int err;
@@ -6109,7 +6109,7 @@ static bool is_filter_match(GSList *discovery_filter, struct eir_data *eir_data,
for (l = discovery_filter; l != NULL && got_match != true;
l = g_slist_next(l)) {
- struct watch_client *client = l->data;
+ struct discovery_client *client = l->data;
struct discovery_filter *item = client->discovery_filter;
/*
@@ -6157,7 +6157,7 @@ static bool is_filter_match(GSList *discovery_filter, struct eir_data *eir_data,
static void filter_duplicate_data(void *data, void *user_data)
{
- struct watch_client *client = data;
+ struct discovery_client *client = data;
bool *duplicate = user_data;
if (*duplicate || !client->discovery_filter)
@@ -6187,7 +6187,7 @@ static bool device_is_discoverable(struct btd_adapter *adapter,
/* Do a prefix match for both address and name if pattern is set */
for (l = adapter->discovery_list; l; l = g_slist_next(l)) {
- struct watch_client *client = l->data;
+ struct discovery_client *client = l->data;
struct discovery_filter *filter = client->discovery_filter;
size_t pattern_len;
--
2.27.0

View File

@ -1,103 +0,0 @@
From 7a80d2096f1b7125085e21448112aa02f49f5e9a Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Thu, 29 Apr 2021 17:10:50 -0700
Subject: avdtp: Fix accepting invalid/malformed capabilities
Check if capabilities are valid before attempting to copy them.
---
profiles/audio/avdtp.c | 56 ++++++++++++++++++++++++++++++++------------------
1 file changed, 36 insertions(+), 20 deletions(-)
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 623fe30d3..c7bf99f42 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -1305,43 +1305,53 @@ struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
return NULL;
}
-static GSList *caps_to_list(uint8_t *data, int size,
+static GSList *caps_to_list(uint8_t *data, size_t size,
struct avdtp_service_capability **codec,
gboolean *delay_reporting)
{
+ struct avdtp_service_capability *cap;
GSList *caps;
- int processed;
if (delay_reporting)
*delay_reporting = FALSE;
- for (processed = 0, caps = NULL; processed + 2 <= size;) {
- struct avdtp_service_capability *cap;
- uint8_t length, category;
+ if (size < sizeof(*cap))
+ return NULL;
+
+ for (caps = NULL; size >= sizeof(*cap);) {
+ struct avdtp_service_capability *cpy;
- category = data[0];
- length = data[1];
+ cap = (struct avdtp_service_capability *)data;
- if (processed + 2 + length > size) {
+ if (sizeof(*cap) + cap->length >= size) {
error("Invalid capability data in getcap resp");
break;
}
- cap = g_malloc(sizeof(struct avdtp_service_capability) +
- length);
- memcpy(cap, data, 2 + length);
+ if (cap->category == AVDTP_MEDIA_CODEC &&
+ cap->length < sizeof(**codec)) {
+ error("Invalid codec data in getcap resp");
+ break;
+ }
+
+ cpy = btd_malloc(sizeof(*cpy) + cap->length);
+ memcpy(cpy, cap, sizeof(*cap) + cap->length);
- processed += 2 + length;
- data += 2 + length;
+ size -= sizeof(*cap) + cap->length;
+ data += sizeof(*cap) + cap->length;
- caps = g_slist_append(caps, cap);
+ caps = g_slist_append(caps, cpy);
- if (category == AVDTP_MEDIA_CODEC &&
- length >=
- sizeof(struct avdtp_media_codec_capability))
- *codec = cap;
- else if (category == AVDTP_DELAY_REPORTING && delay_reporting)
- *delay_reporting = TRUE;
+ switch (cap->category) {
+ case AVDTP_MEDIA_CODEC:
+ if (codec)
+ *codec = cap;
+ break;
+ case AVDTP_DELAY_REPORTING:
+ if (delay_reporting)
+ *delay_reporting = TRUE;
+ break;
+ }
}
return caps;
@@ -1538,6 +1548,12 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
&stream->codec,
&stream->delay_reporting);
+ if (!stream->caps || !stream->codec) {
+ err = AVDTP_UNSUPPORTED_CONFIGURATION;
+ category = 0x00;
+ goto failed_stream;
+ }
+
/* Verify that the Media Transport capability's length = 0. Reject otherwise */
for (l = stream->caps; l != NULL; l = g_slist_next(l)) {
struct avdtp_service_capability *cap = l->data;
--
cgit

View File

@ -1,195 +0,0 @@
From ee49fb1d13617e7d38fbf8f979206b905aa25345 Mon Sep 17 00:00:00 2001
From: Archie Pusaka <apusaka@chromium.org>
Date: Thu, 7 May 2020 14:38:46 +0800
Subject: [PATCH] shared/gatt-server: Fix read multiple charc values
According to bluetooth spec Ver 5.2, Vol 3, Part G, 4.8.4, An
ATT_ERROR_RSP PDU shall be sent by the server in response to the
ATT_READ_MULTIPLE_RSP PDU if insufficient authentication,
insufficient authorization, insufficient encryption key size, or
insufficient encryption is used by the client, or if a read operation
is not permitted on any of the Characteristic Values.
Currently if the size of the response grows larger than the MTU size,
BlueZ does an early return and not check the permission for the rest
of the characteristics. This patch forces BlueZ to check for possible
errors even though we already reach MTU size.
This patch also moves the read permission check for read multiple
characteristics so it is done before actually retrieving the
characteristics.
Conflict:NA
Reference:https://github.com/bluez/bluez/commit/ee49fb1d13617e7d38fbf8f979206b905aa25345
---
src/shared/gatt-server.c | 88 ++++++++++++++++++++--------------------
1 file changed, 45 insertions(+), 43 deletions(-)
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 4e07398d21..28ac2d68de 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -1057,33 +1057,23 @@ static void read_multiple_complete_cb(struct gatt_db_attribute *attr, int err,
uint16_t length;
if (err != 0) {
- bt_att_chan_send_error_rsp(data->chan, data->opcode, handle,
- err);
- read_mult_data_free(data);
- return;
- }
-
- ecode = check_permissions(data->server, attr, BT_ATT_PERM_READ |
- BT_ATT_PERM_READ_AUTHEN |
- BT_ATT_PERM_READ_ENCRYPT);
- if (ecode) {
- bt_att_chan_send_error_rsp(data->chan, data->opcode, handle,
- ecode);
- read_mult_data_free(data);
- return;
+ ecode = err;
+ goto error;
}
length = data->opcode == BT_ATT_OP_READ_MULT_VL_REQ ?
- MIN(len, data->mtu - data->length - 3) :
+ MIN(len, MAX(data->mtu - data->length, 3) - 3) :
MIN(len, data->mtu - data->length - 1);
if (data->opcode == BT_ATT_OP_READ_MULT_VL_REQ) {
/* The Length Value Tuple List may be truncated within the first
* two octets of a tuple due to the size limits of the current
- * ATT_MTU.
+ * ATT_MTU, but the first two octets cannot be separated.
*/
- put_le16(len, data->rsp_data + data->length);
- data->length += 2;
+ if (data->mtu - data->length >= 3) {
+ put_le16(len, data->rsp_data + data->length);
+ data->length += 2;
+ }
}
memcpy(data->rsp_data + data->length, value, length);
@@ -1091,45 +1081,46 @@ static void read_multiple_complete_cb(struct gatt_db_attribute *attr, int err,
data->cur_handle++;
- len = data->opcode == BT_ATT_OP_READ_MULT_VL_REQ ?
- data->mtu - data->length - 3 : data->mtu - data->length - 1;
-
- if (!len || (data->cur_handle == data->num_handles)) {
+ if (data->cur_handle == data->num_handles) {
bt_att_chan_send_rsp(data->chan, data->opcode + 1,
data->rsp_data, data->length);
read_mult_data_free(data);
return;
}
+ handle = data->handles[data->cur_handle];
+
util_debug(data->server->debug_callback, data->server->debug_data,
"%s Req - #%zu of %zu: 0x%04x",
data->opcode == BT_ATT_OP_READ_MULT_REQ ?
"Read Multiple" :
"Read Multiple Variable Length",
data->cur_handle + 1, data->num_handles,
- data->handles[data->cur_handle]);
+ handle);
- next_attr = gatt_db_get_attribute(data->server->db,
- data->handles[data->cur_handle]);
+ next_attr = gatt_db_get_attribute(data->server->db, handle);
if (!next_attr) {
- bt_att_chan_send_error_rsp(data->chan,
- BT_ATT_OP_READ_MULT_REQ,
- data->handles[data->cur_handle],
- BT_ATT_ERROR_INVALID_HANDLE);
- read_mult_data_free(data);
- return;
+ ecode = BT_ATT_ERROR_INVALID_HANDLE;
+ goto error;
}
- if (!gatt_db_attribute_read(next_attr, 0, BT_ATT_OP_READ_MULT_REQ,
+ ecode = check_permissions(data->server, next_attr, BT_ATT_PERM_READ |
+ BT_ATT_PERM_READ_AUTHEN |
+ BT_ATT_PERM_READ_ENCRYPT);
+ if (ecode)
+ goto error;
+
+ if (gatt_db_attribute_read(next_attr, 0, data->opcode,
data->server->att,
- read_multiple_complete_cb, data)) {
- bt_att_chan_send_error_rsp(data->chan,
- BT_ATT_OP_READ_MULT_REQ,
- data->handles[data->cur_handle],
- BT_ATT_ERROR_UNLIKELY);
- read_mult_data_free(data);
- }
+ read_multiple_complete_cb, data))
+ return;
+
+ ecode = BT_ATT_ERROR_UNLIKELY;
+
+error:
+ bt_att_chan_send_error_rsp(data->chan, data->opcode, handle, ecode);
+ read_mult_data_free(data);
}
static struct read_mult_data *read_mult_data_new(struct bt_gatt_server *server,
@@ -1161,8 +1152,9 @@ static void read_multiple_cb(struct bt_att_chan *chan, uint8_t opcode,
struct bt_gatt_server *server = user_data;
struct gatt_db_attribute *attr;
struct read_mult_data *data = NULL;
- uint8_t ecode = BT_ATT_ERROR_UNLIKELY;
+ uint8_t ecode;
size_t i = 0;
+ uint16_t handle = 0;
if (length < 4) {
ecode = BT_ATT_ERROR_INVALID_PDU;
@@ -1176,28 +1168,38 @@ static void read_multiple_cb(struct bt_att_chan *chan, uint8_t opcode,
for (i = 0; i < data->num_handles; i++)
data->handles[i] = get_le16(pdu + i * 2);
+ handle = data->handles[0];
+
util_debug(server->debug_callback, server->debug_data,
"%s Req - %zu handles, 1st: 0x%04x",
data->opcode == BT_ATT_OP_READ_MULT_REQ ?
"Read Multiple" : "Read Multiple Variable Length",
- data->num_handles, data->handles[0]);
+ data->num_handles, handle);
- attr = gatt_db_get_attribute(server->db, data->handles[0]);
+ attr = gatt_db_get_attribute(server->db, handle);
if (!attr) {
ecode = BT_ATT_ERROR_INVALID_HANDLE;
goto error;
}
+ ecode = check_permissions(data->server, attr, BT_ATT_PERM_READ |
+ BT_ATT_PERM_READ_AUTHEN |
+ BT_ATT_PERM_READ_ENCRYPT);
+ if (ecode)
+ goto error;
+
if (gatt_db_attribute_read(attr, 0, opcode, server->att,
read_multiple_complete_cb, data))
return;
+ ecode = BT_ATT_ERROR_UNLIKELY;
+
error:
if (data)
read_mult_data_free(data);
- bt_att_chan_send_error_rsp(chan, opcode, 0, ecode);
+ bt_att_chan_send_error_rsp(chan, opcode, handle, ecode);
}
static bool append_prep_data(struct prep_write_data *prep_data, uint16_t handle,

View File

@ -1,94 +0,0 @@
From b497b5942a8beb8f89ca1c359c54ad67ec843055 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Thu, 24 Jun 2021 16:32:04 -0700
Subject: adapter: Fix storing discoverable setting
discoverable setting shall only be store when changed via Discoverable
property and not when discovery client set it as that be considered
temporary just for the lifetime of the discovery.
Conflict:NA
Reference:https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=b497b5942a8
---
src/adapter.c | 35 ++++++++++++++++++++++-------------
1 file changed, 22 insertions(+), 13 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 12e4ff5c0..663b778e4 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -560,7 +560,11 @@ static void settings_changed(struct btd_adapter *adapter, uint32_t settings)
if (changed_mask & MGMT_SETTING_DISCOVERABLE) {
g_dbus_emit_property_changed(dbus_conn, adapter->path,
ADAPTER_INTERFACE, "Discoverable");
- store_adapter_info(adapter);
+ /* Only persist discoverable setting if it was not set
+ * temporarily by discovery.
+ */
+ if (!adapter->discovery_discoverable)
+ store_adapter_info(adapter);
btd_adv_manager_refresh(adapter->adv_manager);
}
@@ -2162,8 +2166,6 @@ static bool filters_equal(struct mgmt_cp_start_service_discovery *a,
static int update_discovery_filter(struct btd_adapter *adapter)
{
struct mgmt_cp_start_service_discovery *sd_cp;
- GSList *l;
-
DBG("");
@@ -2173,17 +2175,24 @@ static int update_discovery_filter(struct btd_adapter *adapter)
return -ENOMEM;
}
- for (l = adapter->discovery_list; l; l = g_slist_next(l)) {
- struct discovery_client *client = l->data;
+ /* Only attempt to overwrite current discoverable setting when not
+ * discoverable.
+ */
+ if (!(adapter->current_settings & MGMT_OP_SET_DISCOVERABLE)) {
+ GSList *l;
- if (!client->discovery_filter)
- continue;
+ for (l = adapter->discovery_list; l; l = g_slist_next(l)) {
+ struct discovery_client *client = l->data;
- if (client->discovery_filter->discoverable)
- break;
- }
+ if (!client->discovery_filter)
+ continue;
- set_discovery_discoverable(adapter, l ? true : false);
+ if (client->discovery_filter->discoverable) {
+ set_discovery_discoverable(adapter, true);
+ break;
+ }
+ }
+ }
/*
* If filters are equal, then don't update scan, except for when
@@ -2216,8 +2225,7 @@ static int discovery_stop(struct discovery_client *client, bool exit)
return 0;
}
- if (adapter->discovery_discoverable)
- set_discovery_discoverable(adapter, false);
+ set_discovery_discoverable(adapter, false);
/*
* In the idle phase of a discovery, there is no need to stop it
@@ -6913,6 +6921,7 @@ static void adapter_stop(struct btd_adapter *adapter)
g_free(adapter->current_discovery_filter);
adapter->current_discovery_filter = NULL;
+ set_discovery_discoverable(adapter, false);
adapter->discovering = false;
while (adapter->connections) {
--
cgit 1.2.3-1.el7

View File

@ -1,37 +0,0 @@
From 0388794dc5fdb73a4ea88bcf148de0a12b4364d4 Mon Sep 17 00:00:00 2001
From: Archie Pusaka <apusaka@chromium.org>
Date: Thu, 17 Jun 2021 08:53:34 +0800
Subject: avdtp: Fix parsing capabilities
This patch fixes size comparison and variable misassignment.
Reviewed-by: Alain Michaud <alainm@chromium.org>
Reviewed-by: Michael Sun <michaelfsun@google.com>
---
profiles/audio/avdtp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index c7bf99f42..5d13104c1 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -1323,7 +1323,7 @@ static GSList *caps_to_list(uint8_t *data, size_t size,
cap = (struct avdtp_service_capability *)data;
- if (sizeof(*cap) + cap->length >= size) {
+ if (sizeof(*cap) + cap->length > size) {
error("Invalid capability data in getcap resp");
break;
}
@@ -1345,7 +1345,7 @@ static GSList *caps_to_list(uint8_t *data, size_t size,
switch (cap->category) {
case AVDTP_MEDIA_CODEC:
if (codec)
- *codec = cap;
+ *codec = cpy;
break;
case AVDTP_DELAY_REPORTING:
if (delay_reporting)
--
cgit

View File

@ -1,159 +0,0 @@
From a23fa59b09bbda8a35596ebccb78d352b6f5561d Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Wed, 6 Jan 2021 15:22:41 -0800
Subject: [PATCH] shared/gatt-server: Fix not accepting multiple requests
With introduction of EATT it is possible to send multiple requests using
different channels therefore bt_gatt_server shall not attempt to check
if there is already an outstanding request.
gh issue: https://github.com/bluez/bluez/issues/75
Conflict:NA
Reference:https://github.com/bluez/bluez/commit/a23fa59b09bbda8a35596ebccb78d352b6f5561d
---
src/shared/gatt-server.c | 53 +++++-----------------------------------
1 file changed, 6 insertions(+), 47 deletions(-)
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 0ce994be3e..b5f7de7dc3 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -108,9 +108,6 @@ struct bt_gatt_server {
struct queue *prep_queue;
unsigned int max_prep_queue_len;
- struct async_read_op *pending_read_op;
- struct async_write_op *pending_write_op;
-
bt_gatt_server_debug_func_t debug_callback;
bt_gatt_server_destroy_func_t debug_destroy;
void *debug_data;
@@ -140,12 +137,6 @@ static void bt_gatt_server_free(struct bt_gatt_server *server)
bt_att_unregister(server->att, server->prep_write_id);
bt_att_unregister(server->att, server->exec_write_id);
- if (server->pending_read_op)
- server->pending_read_op->server = NULL;
-
- if (server->pending_write_op)
- server->pending_write_op->server = NULL;
-
queue_destroy(server->prep_queue, prep_write_data_destroy);
gatt_db_unref(server->db);
@@ -324,9 +315,7 @@ static void read_by_grp_type_cb(struct bt_att_chan *chan, uint8_t opcode,
static void async_read_op_destroy(struct async_read_op *op)
{
- if (op->server)
- op->server->pending_read_op = NULL;
-
+ bt_gatt_server_unref(op->server);
queue_destroy(op->db_data, NULL);
free(op->pdu);
free(op);
@@ -343,11 +332,6 @@ static void read_by_type_read_complete_cb(struct gatt_db_attribute *attr,
uint16_t mtu;
uint16_t handle;
- if (!server) {
- async_read_op_destroy(op);
- return;
- }
-
mtu = bt_att_get_mtu(server->att);
handle = gatt_db_attribute_get_handle(attr);
@@ -524,11 +508,6 @@ static void read_by_type_cb(struct bt_att_chan *chan, uint8_t opcode,
goto error;
}
- if (server->pending_read_op) {
- ecode = BT_ATT_ERROR_UNLIKELY;
- goto error;
- }
-
op = new0(struct async_read_op, 1);
op->pdu = malloc(bt_att_get_mtu(server->att));
if (!op->pdu) {
@@ -539,9 +518,8 @@ static void read_by_type_cb(struct bt_att_chan *chan, uint8_t opcode,
op->chan = chan;
op->opcode = opcode;
- op->server = server;
+ op->server = bt_gatt_server_ref(server);
op->db_data = q;
- server->pending_read_op = op;
process_read_by_type(op);
@@ -764,9 +742,7 @@ static void find_by_type_val_cb(struct bt_att_chan *chan, uint8_t opcode,
static void async_write_op_destroy(struct async_write_op *op)
{
- if (op->server)
- op->server->pending_write_op = NULL;
-
+ bt_gatt_server_unref(op->server);
free(op);
}
@@ -777,7 +753,7 @@ static void write_complete_cb(struct gatt_db_attribute *attr, int err,
struct bt_gatt_server *server = op->server;
uint16_t handle;
- if (!server || op->opcode == BT_ATT_OP_WRITE_CMD) {
+ if (op->opcode == BT_ATT_OP_WRITE_CMD) {
async_write_op_destroy(op);
return;
}
@@ -841,16 +817,10 @@ static void write_cb(struct bt_att_chan *chan, uint8_t opcode, const void *pdu,
if (ecode)
goto error;
- if (server->pending_write_op) {
- ecode = BT_ATT_ERROR_UNLIKELY;
- goto error;
- }
-
op = new0(struct async_write_op, 1);
op->chan = chan;
- op->server = server;
+ op->server = bt_gatt_server_ref(server);
op->opcode = opcode;
- server->pending_write_op = op;
if (gatt_db_attribute_write(attr, 0, pdu + 2, length - 2, opcode,
server->att,
@@ -901,11 +871,6 @@ static void read_complete_cb(struct gatt_db_attribute *attr, int err,
uint16_t mtu;
uint16_t handle;
- if (!server) {
- async_read_op_destroy(op);
- return;
- }
-
util_debug(server->debug_callback, server->debug_data,
"Read Complete: err %d", err);
@@ -954,16 +919,10 @@ static void handle_read_req(struct bt_att_chan *chan,
if (ecode)
goto error;
- if (server->pending_read_op) {
- ecode = BT_ATT_ERROR_UNLIKELY;
- goto error;
- }
-
op = new0(struct async_read_op, 1);
op->chan = chan;
op->opcode = opcode;
- op->server = server;
- server->pending_read_op = op;
+ op->server = bt_gatt_server_ref(server);
if (gatt_db_attribute_read(attr, offset, opcode, server->att,
read_complete_cb, op))

View File

@ -1,107 +0,0 @@
From 00da0fb4972cf59e1c075f313da81ea549cb8738 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Tue, 2 Mar 2021 11:38:33 -0800
Subject: [PATCH] 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.
Conflict:NA
Reference:https://github.com/bluez/bluez/commit/00da0fb4972cf59e1c075f313da81ea549cb8738
---
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 7108b4e94a..3adc05d9e3 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 b5f7de7dc3..970c35f94e 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;

View File

@ -1,145 +0,0 @@
From 1cd644db8c23a2f530ddb93cebed7dacc5f5721a Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Wed, 15 Jul 2020 18:25:37 -0700
Subject: [PATCH] shared/att: Fix possible crash on disconnect
If there are pending request while disconnecting they would be notified
but clients may endup being freed in the proccess which will then be
calling bt_att_cancel to cancal its requests causing the following
trace:
Invalid read of size 4
at 0x1D894C: enable_ccc_callback (gatt-client.c:1627)
by 0x1D247B: disc_att_send_op (att.c:417)
by 0x1CCC17: queue_remove_all (queue.c:354)
by 0x1D47B7: disconnect_cb (att.c:635)
by 0x1E0707: watch_callback (io-glib.c:170)
by 0x48E963B: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.6400.4)
by 0x48E9AC7: ??? (in /usr/lib/libglib-2.0.so.0.6400.4)
by 0x48E9ECF: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.6400.4)
by 0x1E0E97: mainloop_run (mainloop-glib.c:79)
by 0x1E13B3: mainloop_run_with_signal (mainloop-notify.c:201)
by 0x12BC3B: main (main.c:770)
Address 0x7d40a28 is 24 bytes inside a block of size 32 free'd
at 0x484A2E0: free (vg_replace_malloc.c:540)
by 0x1CCC17: queue_remove_all (queue.c:354)
by 0x1CCC83: queue_destroy (queue.c:73)
by 0x1D7DD7: bt_gatt_client_free (gatt-client.c:2209)
by 0x16497B: batt_free (battery.c:77)
by 0x16497B: batt_remove (battery.c:286)
by 0x1A0013: service_remove (service.c:176)
by 0x1A9B7B: device_remove_gatt_service (device.c:3691)
by 0x1A9B7B: gatt_service_removed (device.c:3805)
by 0x1CC90B: queue_foreach (queue.c:220)
by 0x1DE27B: notify_service_changed.isra.0.part.0 (gatt-db.c:369)
by 0x1DE387: notify_service_changed (gatt-db.c:361)
by 0x1DE387: gatt_db_service_destroy (gatt-db.c:385)
by 0x1DE3EF: gatt_db_remove_service (gatt-db.c:519)
by 0x1D674F: discovery_op_complete (gatt-client.c:388)
by 0x1D6877: discover_primary_cb (gatt-client.c:1260)
by 0x1E220B: discovery_op_complete (gatt-helpers.c:628)
by 0x1E249B: read_by_grp_type_cb (gatt-helpers.c:730)
by 0x1D247B: disc_att_send_op (att.c:417)
by 0x1CCC17: queue_remove_all (queue.c:354)
by 0x1D47B7: disconnect_cb (att.c:635)
---
src/shared/att.c | 46 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 40 insertions(+), 6 deletions(-)
diff --git a/src/shared/att.c b/src/shared/att.c
index 948a554..8c3df91 100644
--- a/src/shared/att.c
+++ b/src/shared/att.c
@@ -84,6 +84,7 @@ struct bt_att {
struct queue *req_queue; /* Queued ATT protocol requests */
struct queue *ind_queue; /* Queued ATT protocol indications */
struct queue *write_queue; /* Queue of PDUs ready to send */
+ bool in_disc; /* Cleanup queues on disconnect_cb */
bt_att_timeout_func_t timeout_callback;
bt_att_destroy_func_t timeout_destroy;
@@ -222,8 +223,10 @@ static void destroy_att_send_op(void *data)
free(op);
}
-static void cancel_att_send_op(struct att_send_op *op)
+static void cancel_att_send_op(void *data)
{
+ struct att_send_op *op = data;
+
if (op->destroy)
op->destroy(op->user_data);
@@ -631,11 +634,6 @@ static bool disconnect_cb(struct io *io, void *user_data)
/* Dettach channel */
queue_remove(att->chans, chan);
- /* Notify request callbacks */
- queue_remove_all(att->req_queue, NULL, NULL, disc_att_send_op);
- queue_remove_all(att->ind_queue, NULL, NULL, disc_att_send_op);
- queue_remove_all(att->write_queue, NULL, NULL, disc_att_send_op);
-
if (chan->pending_req) {
disc_att_send_op(chan->pending_req);
chan->pending_req = NULL;
@@ -654,6 +652,15 @@ static bool disconnect_cb(struct io *io, void *user_data)
bt_att_ref(att);
+ att->in_disc = true;
+
+ /* Notify request callbacks */
+ queue_remove_all(att->req_queue, NULL, NULL, disc_att_send_op);
+ queue_remove_all(att->ind_queue, NULL, NULL, disc_att_send_op);
+ queue_remove_all(att->write_queue, NULL, NULL, disc_att_send_op);
+
+ att->in_disc = false;
+
queue_foreach(att->disconn_list, disconn_handler, INT_TO_PTR(err));
bt_att_unregister_all(att);
@@ -1575,6 +1582,30 @@ bool bt_att_chan_cancel(struct bt_att_chan *chan, unsigned int id)
return true;
}
+static bool bt_att_disc_cancel(struct bt_att *att, unsigned int id)
+{
+ struct att_send_op *op;
+
+ op = queue_find(att->req_queue, match_op_id, UINT_TO_PTR(id));
+ if (op)
+ goto done;
+
+ op = queue_find(att->ind_queue, match_op_id, UINT_TO_PTR(id));
+ if (op)
+ goto done;
+
+ op = queue_find(att->write_queue, match_op_id, UINT_TO_PTR(id));
+
+done:
+ if (!op)
+ return false;
+
+ /* Just cancel since disconnect_cb will be cleaning up */
+ cancel_att_send_op(op);
+
+ return true;
+}
+
bool bt_att_cancel(struct bt_att *att, unsigned int id)
{
const struct queue_entry *entry;
@@ -1592,6 +1623,9 @@ bool bt_att_cancel(struct bt_att *att, unsigned int id)
return true;
}
+ if (att->in_disc)
+ return bt_att_disc_cancel(att, id);
+
op = queue_remove_if(att->req_queue, match_op_id, UINT_TO_PTR(id));
if (op)
goto done;
--
2.27.0

View File

@ -1,33 +0,0 @@
From 9e6889d3b9d8f4dcc1ba57e6345d1efb2fbe1e77 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Mon, 4 Jan 2021 10:41:53 -0800
Subject: [PATCH] gatt: Fix potential buffer out-of-bound
When client features is read check if the offset is within the cli_feat
bounds.
Fixes: https://github.com/bluez/bluez/issues/70
---
src/gatt-database.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/gatt-database.c b/src/gatt-database.c
index c11d14b..a6530ba 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -1082,6 +1082,11 @@ static void cli_feat_read_cb(struct gatt_db_attribute *attrib,
goto done;
}
+ if (offset >= sizeof(state->cli_feat)) {
+ ecode = BT_ATT_ERROR_INVALID_OFFSET;
+ goto done;
+ }
+
len = sizeof(state->cli_feat) - offset;
value = len ? &state->cli_feat[offset] : NULL;
--
2.23.0

View File

@ -1,464 +0,0 @@
From e79417ed7185b150a056d4eb3a1ab528b91d2fc0 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Thu, 15 Jul 2021 11:01:20 -0700
Subject: 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
Conflict:NA
Reference:https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=e79417ed7185b150a056d4eb3a1ab528b91d2fc0
---
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 9f4b51dac..748cbeb61 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 9488535d3..d4b8f2f5b 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);
--
cgit 1.2.3-1.el7

View File

@ -1,336 +0,0 @@
From 838c0dc7641e1c991c0f3027bf94bee4606012f8 Mon Sep 17 00:00:00 2001
From: Bernie Conrad <bernie@allthenticate.net>
Date: Wed, 9 Feb 2022 15:03:19 +0800
Subject: [PATCH] backport-0003-CVE-2021-43400
There is a current use after free possible on a gatt server if a client
disconnects while a WriteValue call is being processed with dbus.
This patch includes the addition of a pending disconnect callback to handle
cleanup better if a disconnect occurs during a write, an acquire write
or read operation using bt_att_register_disconnect with the cb.
Conflict:NA
Reference:https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=b497b5942a8
---
src/gatt-database.c | 130 +++++++++++++++++++++++++-------------------
1 file changed, 74 insertions(+), 56 deletions(-)
diff --git a/src/gatt-database.c b/src/gatt-database.c
index a6530ba..6dde821 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -148,8 +148,9 @@ struct external_desc {
};
struct pending_op {
- struct btd_device *device;
+ struct bt_att *att;
unsigned int id;
+ unsigned int disconn_id;
uint16_t offset;
uint8_t link_type;
struct gatt_db_attribute *attrib;
@@ -924,6 +925,25 @@ static struct btd_device *att_get_device(struct bt_att *att)
return btd_adapter_find_device(adapter, &dst, dst_type);
}
+static void pending_op_free(void *data)
+{
+ struct pending_op *op = data;
+
+ if (op->owner_queue)
+ queue_remove(op->owner_queue, op);
+
+ bt_att_unregister_disconnect(op->att, op->disconn_id);
+ bt_att_unref(op->att);
+ free(op);
+}
+
+static void pending_disconnect_cb(int err, void *user_data)
+{
+ struct pending_op *op = user_data;
+
+ op->owner_queue = NULL;
+}
+
static struct pending_op *pending_ccc_new(struct bt_att *att,
struct gatt_db_attribute *attrib,
uint16_t value,
@@ -943,21 +963,16 @@ static struct pending_op *pending_ccc_new(struct bt_att *att,
op->data.iov_base = UINT_TO_PTR(value);
op->data.iov_len = sizeof(value);
- op->device = device;
+ op->att = bt_att_ref(att);
op->attrib = attrib;
op->link_type = link_type;
- return op;
-}
+ bt_att_register_disconnect(att,
+ pending_disconnect_cb,
+ op,
+ NULL);
-static void pending_op_free(void *data)
-{
- struct pending_op *op = data;
-
- if (op->owner_queue)
- queue_remove(op->owner_queue, op);
-
- free(op);
+ return op;
}
static void gatt_ccc_write_cb(struct gatt_db_attribute *attrib,
@@ -2110,31 +2125,34 @@ done:
gatt_db_attribute_read_result(op->attrib, op->id, ecode, value, len);
}
-static struct pending_op *pending_read_new(struct btd_device *device,
+static struct pending_op *pending_read_new(struct bt_att *att,
struct queue *owner_queue,
struct gatt_db_attribute *attrib,
- unsigned int id, uint16_t offset,
- uint8_t link_type)
+ unsigned int id, uint16_t offset)
{
struct pending_op *op;
op = new0(struct pending_op, 1);
op->owner_queue = owner_queue;
- op->device = device;
+ op->att = bt_att_ref(att);
op->attrib = attrib;
op->id = id;
op->offset = offset;
- op->link_type = link_type;
+ op->link_type = bt_att_get_link_type(att);
queue_push_tail(owner_queue, op);
+ op->disconn_id = bt_att_register_disconnect(att, pending_disconnect_cb,
+ op, NULL);
+
return op;
}
static void append_options(DBusMessageIter *iter, void *user_data)
{
struct pending_op *op = user_data;
- const char *path = device_get_path(op->device);
+ struct btd_device *device = att_get_device(op->att);
+ const char *path = device_get_path(device);
struct bt_gatt_server *server;
const char *link;
uint16_t mtu;
@@ -2161,7 +2179,7 @@ static void append_options(DBusMessageIter *iter, void *user_data)
dict_append_entry(iter, "prepare-authorize", DBUS_TYPE_BOOLEAN,
&op->prep_authorize);
- server = btd_device_get_gatt_server(op->device);
+ server = btd_device_get_gatt_server(device);
mtu = bt_gatt_server_get_mtu(server);
dict_append_entry(iter, "mtu", DBUS_TYPE_UINT16, &mtu);
@@ -2184,18 +2202,16 @@ static void read_setup_cb(DBusMessageIter *iter, void *user_data)
dbus_message_iter_close_container(iter, &dict);
}
-static struct pending_op *send_read(struct btd_device *device,
+static struct pending_op *send_read(struct bt_att *att,
struct gatt_db_attribute *attrib,
GDBusProxy *proxy,
struct queue *owner_queue,
unsigned int id,
- uint16_t offset,
- uint8_t link_type)
+ uint16_t offset)
{
struct pending_op *op;
- op = pending_read_new(device, owner_queue, attrib, id, offset,
- link_type);
+ op = pending_read_new(att, owner_queue, attrib, id, offset);
if (g_dbus_proxy_method_call(proxy, "ReadValue", read_setup_cb,
read_reply_cb, op, pending_op_free) == TRUE)
@@ -2278,15 +2294,17 @@ static void write_reply_cb(DBusMessage *message, void *user_data)
}
done:
- gatt_db_attribute_write_result(op->attrib, op->id, ecode);
+ /* Make sure that only reply if the device is connected */
+ if (!bt_att_get_fd(op->att))
+ gatt_db_attribute_write_result(op->attrib, op->id, ecode);
}
-static struct pending_op *pending_write_new(struct btd_device *device,
+static struct pending_op *pending_write_new(struct bt_att *att,
struct queue *owner_queue,
struct gatt_db_attribute *attrib,
unsigned int id,
const uint8_t *value, size_t len,
- uint16_t offset, uint8_t link_type,
+ uint16_t offset,
bool is_characteristic,
bool prep_authorize)
{
@@ -2297,33 +2315,37 @@ static struct pending_op *pending_write_new(struct btd_device *device,
op->data.iov_base = (uint8_t *) value;
op->data.iov_len = len;
- op->device = device;
+ op->att = bt_att_ref(att);
op->owner_queue = owner_queue;
op->attrib = attrib;
op->id = id;
op->offset = offset;
- op->link_type = link_type;
+ op->link_type = bt_att_get_link_type(att);
op->is_characteristic = is_characteristic;
op->prep_authorize = prep_authorize;
queue_push_tail(owner_queue, op);
+ bt_att_register_disconnect(att,
+ pending_disconnect_cb,
+ op, NULL);
+
return op;
}
-static struct pending_op *send_write(struct btd_device *device,
+static struct pending_op *send_write(struct bt_att *att,
struct gatt_db_attribute *attrib,
GDBusProxy *proxy,
struct queue *owner_queue,
unsigned int id,
const uint8_t *value, size_t len,
- uint16_t offset, uint8_t link_type,
+ uint16_t offset,
bool is_characteristic,
bool prep_authorize)
{
struct pending_op *op;
- op = pending_write_new(device, owner_queue, attrib, id, value, len,
- offset, link_type, is_characteristic,
+ op = pending_write_new(att, owner_queue, attrib, id, value, len,
+ offset, is_characteristic,
prep_authorize);
if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup_cb,
@@ -2439,9 +2461,9 @@ static void acquire_write_reply(DBusMessage *message, void *user_data)
return;
retry:
- send_write(op->device, op->attrib, chrc->proxy, NULL, op->id,
+ send_write(op->att, op->attrib, chrc->proxy, NULL, op->id,
op->data.iov_base, op->data.iov_len, 0,
- op->link_type, false, false);
+ false, false);
}
static void acquire_write_setup(DBusMessageIter *iter, void *user_data)
@@ -2462,16 +2484,15 @@ static void acquire_write_setup(DBusMessageIter *iter, void *user_data)
}
static struct pending_op *acquire_write(struct external_chrc *chrc,
- struct btd_device *device,
+ struct bt_att *att,
struct gatt_db_attribute *attrib,
unsigned int id,
- const uint8_t *value, size_t len,
- uint8_t link_type)
+ const uint8_t *value, size_t len)
{
struct pending_op *op;
- op = pending_write_new(device, NULL, attrib, id, value, len, 0,
- link_type, false, false);
+ op = pending_write_new(att, NULL, attrib, id, value,
+ len, 0, false, false);
if (g_dbus_proxy_method_call(chrc->proxy, "AcquireWrite",
acquire_write_setup,
@@ -2737,8 +2758,8 @@ static void desc_read_cb(struct gatt_db_attribute *attrib,
goto fail;
}
- if (send_read(device, attrib, desc->proxy, desc->pending_reads, id,
- offset, bt_att_get_link_type(att)))
+ if (send_read(att, attrib, desc->proxy, desc->pending_reads, id,
+ offset))
return;
fail:
@@ -2769,10 +2790,9 @@ static void desc_write_cb(struct gatt_db_attribute *attrib,
if (opcode == BT_ATT_OP_PREP_WRITE_REQ) {
if (!device_is_trusted(device) && !desc->prep_authorized &&
desc->req_prep_authorization)
- send_write(device, attrib, desc->proxy,
+ send_write(att, attrib, desc->proxy,
desc->pending_writes, id, value, len,
- offset, bt_att_get_link_type(att),
- false, true);
+ offset, false, true);
else
gatt_db_attribute_write_result(attrib, id, 0);
@@ -2782,9 +2802,8 @@ static void desc_write_cb(struct gatt_db_attribute *attrib,
if (opcode == BT_ATT_OP_EXEC_WRITE_REQ)
desc->prep_authorized = false;
- if (send_write(device, attrib, desc->proxy, desc->pending_writes, id,
- value, len, offset, bt_att_get_link_type(att), false,
- false))
+ if (send_write(att, attrib, desc->proxy, desc->pending_writes, id,
+ value, len, offset, false, false))
return;
fail:
@@ -2863,8 +2882,8 @@ static void chrc_read_cb(struct gatt_db_attribute *attrib,
goto fail;
}
- if (send_read(device, attrib, chrc->proxy, chrc->pending_reads, id,
- offset, bt_att_get_link_type(att)))
+ if (send_read(att, attrib, chrc->proxy, chrc->pending_reads, id,
+ offset))
return;
fail:
@@ -2902,9 +2921,9 @@ static void chrc_write_cb(struct gatt_db_attribute *attrib,
if (opcode == BT_ATT_OP_PREP_WRITE_REQ) {
if (!device_is_trusted(device) && !chrc->prep_authorized &&
chrc->req_prep_authorization)
- send_write(device, attrib, chrc->proxy, queue,
+ send_write(att, attrib, chrc->proxy, queue,
id, value, len, offset,
- bt_att_get_link_type(att), true, true);
+ true, true);
else
gatt_db_attribute_write_result(attrib, id, 0);
@@ -2925,13 +2944,12 @@ static void chrc_write_cb(struct gatt_db_attribute *attrib,
}
if (g_dbus_proxy_get_property(chrc->proxy, "WriteAcquired", &iter)) {
- if (acquire_write(chrc, device, attrib, id, value, len,
- bt_att_get_link_type(att)))
+ if (acquire_write(chrc, att, attrib, id, value, len))
return;
}
- if (send_write(device, attrib, chrc->proxy, queue, id, value, len,
- offset, bt_att_get_link_type(att), false, false))
+ if (send_write(att, attrib, chrc->proxy, queue, id, value, len,
+ offset, false, false))
return;
fail:
--
2.27.0

View File

@ -1,61 +0,0 @@
From 591c546c536b42bef696d027f64aa22434f8c3f0 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Tue, 8 Jun 2021 16:46:49 -0700
Subject: [PATCH] shared/gatt-server: Fix heap overflow when appending prepare
writes
The code shall check if the prepare writes would append more the
allowed maximum attribute length.
Fixes https://github.com/bluez/bluez/security/advisories/GHSA-479m-xcq5-9g2q
---
src/shared/gatt-server.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index dc4e681c9c..9beec44bed 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -779,6 +779,20 @@ static uint8_t authorize_req(struct bt_gatt_server *server,
server->authorize_data);
}
+static uint8_t check_length(uint16_t length, uint16_t offset)
+{
+ if (length > BT_ATT_MAX_VALUE_LEN)
+ return BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN;
+
+ if (offset > BT_ATT_MAX_VALUE_LEN)
+ return BT_ATT_ERROR_INVALID_OFFSET;
+
+ if (length + offset > BT_ATT_MAX_VALUE_LEN)
+ return BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN;
+
+ return 0;
+}
+
static void write_cb(struct bt_att_chan *chan, uint8_t opcode, const void *pdu,
uint16_t length, void *user_data)
{
@@ -809,6 +823,10 @@ 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_length(length, 0);
+ if (ecode)
+ goto error;
+
ecode = check_permissions(server, attr, BT_ATT_PERM_WRITE_MASK);
if (ecode)
goto error;
@@ -1299,6 +1317,10 @@ 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_length(length, offset);
+ if (ecode)
+ goto error;
+
ecode = check_permissions(server, attr, BT_ATT_PERM_WRITE_MASK);
if (ecode)
goto error;

View File

@ -1,33 +0,0 @@
From e2b0f0d8d63e1223bb714a9efb37e2257818268b Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Thu, 29 Apr 2021 18:18:57 -0700
Subject: avrcp: Fix not checking if params_len match number of received bytes
This makes sure the number of bytes in the params_len matches the
remaining bytes received so the code don't end up accessing invalid
memory.
---
profiles/audio/avrcp.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 05dd791de..c6a342ee3 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1914,6 +1914,14 @@ static size_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
goto err_metadata;
}
+ operands += sizeof(*pdu);
+ operand_count -= sizeof(*pdu);
+
+ if (pdu->params_len != operand_count) {
+ DBG("AVRCP PDU parameters length don't match");
+ pdu->params_len = operand_count;
+ }
+
for (handler = session->control_handlers; handler->pdu_id; handler++) {
if (handler->pdu_id == pdu->pdu_id)
break;
--
cgit

View File

@ -1,46 +0,0 @@
From f54299a850676d92c3dafd83e9174fcfe420ccc9 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Wed, 22 Mar 2023 11:34:24 -0700
Subject: avrcp: Fix crash while handling unsupported events
The following crash can be observed if the remote peer send and
unsupported event:
ERROR: AddressSanitizer: heap-use-after-free on address 0x60b000148f11
at pc 0x559644552088 bp 0x7ffe28b3c7b0 sp 0x7ffe28b3c7a0
WRITE of size 1 at 0x60b000148f11 thread T0
#0 0x559644552087 in avrcp_handle_event profiles/audio/avrcp.c:3907
#1 0x559644536c22 in control_response profiles/audio/avctp.c:939
#2 0x5596445379ab in session_cb profiles/audio/avctp.c:1108
#3 0x7fbcb3e51c43 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x55c43)
#4 0x7fbcb3ea66c7 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0xaa6c7)
#5 0x7fbcb3e512b2 in g_main_loop_run (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x552b2)
#6 0x559644754ab6 in mainloop_run src/shared/mainloop-glib.c:66
#7 0x559644755606 in mainloop_run_with_signal src/shared/mainloop-notify.c:188
#8 0x5596445bb963 in main src/main.c:1289
#9 0x7fbcb3bafd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#10 0x7fbcb3bafe3f in __libc_start_main_impl ../csu/libc-start.c:392
#11 0x5596444e8224 in _start (/usr/local/libexec/bluetooth/bluetoothd+0xf0224)
---
profiles/audio/avrcp.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 80f34c7a7..dda9a303f 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -3901,6 +3901,12 @@ static gboolean avrcp_handle_event(struct avctp *conn, uint8_t code,
case AVRCP_EVENT_UIDS_CHANGED:
avrcp_uids_changed(session, pdu);
break;
+ default:
+ if (event > AVRCP_EVENT_LAST) {
+ warn("Unsupported event: %u", event);
+ return FALSE;
+ }
+ break;
}
session->registered_events |= (1 << event);
--
cgit

View File

@ -1,47 +0,0 @@
From 25a471a83e02e1effb15d5a488b3f0085eaeb675 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Tue, 10 Oct 2023 13:03:12 -0700
Subject: input.conf: Change default of ClassicBondedOnly
This changes the default of ClassicBondedOnly since defaulting to false
is not inline with HID specification which mandates the of Security Mode
4:
BLUETOOTH SPECIFICATION Page 84 of 123
Human Interface Device (HID) Profile:
5.4.3.4.2 Security Modes
Bluetooth HID Hosts shall use Security Mode 4 when interoperating with
Bluetooth HID devices that are compliant to the Bluetooth Core
Specification v2.1+EDR[6].
---
profiles/input/device.c | 2 +-
profiles/input/input.conf | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/profiles/input/device.c b/profiles/input/device.c
index d89da2d..e6f9e84 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -92,7 +92,7 @@ struct input_device {
static int idle_timeout = 0;
static bool uhid_enabled = false;
-static bool classic_bonded_only = false;
+static bool classic_bonded_only = true;
void input_set_idle_timeout(int timeout)
{
diff --git a/profiles/input/input.conf b/profiles/input/input.conf
index 166aff4..d0b6449 100644
--- a/profiles/input/input.conf
+++ b/profiles/input/input.conf
@@ -17,5 +17,5 @@
# platforms may want to make sure that input connections only come from bonded
# device connections. Several older mice have been known for not supporting
# pairing/encryption.
-# Defaults to false to maximize device compatibility.
+# Defaults to true for security.
#ClassicBondedOnly=true
--
2.33.0

View File

@ -1,63 +0,0 @@
From 5ab5352531a9cc7058cce569607f3a6831464443 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Tue, 19 Sep 2023 12:14:01 -0700
Subject: [PATCH] pbap: Fix not checking Primary/Secundary Counter length
Primary/Secundary Counters are supposed to be 16 bytes values, if the
server has implemented them incorrectly it may lead to the following
crash:
=================================================================
==31860==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x607000001878 at pc 0x7f95a1575638 bp 0x7fff58c6bb80 sp 0x7fff58c6b328
READ of size 48 at 0x607000001878 thread T0
#0 0x7f95a1575637 in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long) ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:860
#1 0x7f95a1575ba6 in __interceptor_memcmp ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:892
#2 0x7f95a1575ba6 in __interceptor_memcmp ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:887
#3 0x564df69c77a0 in read_version obexd/client/pbap.c:288
#4 0x564df69c77a0 in read_return_apparam obexd/client/pbap.c:352
#5 0x564df69c77a0 in phonebook_size_callback obexd/client/pbap.c:374
#6 0x564df69bea3c in session_terminate_transfer obexd/client/session.c:921
#7 0x564df69d56b0 in get_xfer_progress_first obexd/client/transfer.c:729
#8 0x564df698b9ee in handle_response gobex/gobex.c:1140
#9 0x564df698cdea in incoming_data gobex/gobex.c:1385
#10 0x7f95a12fdc43 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x55c43)
#11 0x7f95a13526c7 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0xaa6c7)
#12 0x7f95a12fd2b2 in g_main_loop_run (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x552b2)
#13 0x564df6977d41 in main obexd/src/main.c:307
#14 0x7f95a10a7d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#15 0x7f95a10a7e3f in __libc_start_main_impl ../csu/libc-start.c:392
#16 0x564df6978704 in _start (/usr/local/libexec/bluetooth/obexd+0x8b704)
0x607000001878 is located 0 bytes to the right of 72-byte region [0x607000001830,0x607000001878)
allocated by thread T0 here:
#0 0x7f95a1595a37 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
#1 0x564df69c8b6a in pbap_probe obexd/client/pbap.c:1259
---
obexd/client/pbap.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/obexd/client/pbap.c b/obexd/client/pbap.c
index 1ed8c68ecc..2d2aa95089 100644
--- a/obexd/client/pbap.c
+++ b/obexd/client/pbap.c
@@ -285,7 +285,7 @@ static void read_version(struct pbap_data *pbap, GObexApparam *apparam)
data = value;
}
- if (memcmp(pbap->primary, data, len)) {
+ if (len == sizeof(pbap->primary) && memcmp(pbap->primary, data, len)) {
memcpy(pbap->primary, data, len);
g_dbus_emit_property_changed(conn,
obc_session_get_path(pbap->session),
@@ -299,7 +299,8 @@ static void read_version(struct pbap_data *pbap, GObexApparam *apparam)
data = value;
}
- if (memcmp(pbap->secondary, data, len)) {
+ if (len == sizeof(pbap->secondary) &&
+ memcmp(pbap->secondary, data, len)) {
memcpy(pbap->secondary, data, len);
g_dbus_emit_property_changed(conn,
obc_session_get_path(pbap->session),

View File

@ -1,42 +0,0 @@
From 124dee151746b4a8a2e8a7194af78f2c82f75d79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 3 Mar 2021 08:57:36 +0100
Subject: [PATCH] media: rename local function conflicting with pause(2)
profiles/audio/media.c:1284:13: error: conflicting types for 'pause'; have '_Bool(void *)'
1284 | static bool pause(void *user_data)
| ^~~~~
In file included from /usr/include/bits/sigstksz.h:24,
from /usr/include/signal.h:315,
from /usr/include/glib-2.0/glib/gbacktrace.h:36,
from /usr/include/glib-2.0/glib.h:34,
from profiles/audio/media.c:21:
/usr/include/unistd.h:478:12: note: previous declaration of 'pause' with type 'int(void)'
478 | extern int pause (void);
| ^~~~~
---
profiles/audio/media.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index c84bbe22dc..3d8c4b69c3 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -1281,7 +1281,7 @@ static bool stop(void *user_data)
return media_player_send(mp, "Stop");
}
-static bool pause(void *user_data)
+static bool pause_play(void *user_data)
{
struct media_player *mp = user_data;
@@ -1331,7 +1331,7 @@ static struct avrcp_player_cb player_cb = {
.set_volume = set_volume,
.play = play,
.stop = stop,
- .pause = pause,
+ .pause = pause_play,
.next = next,
.previous = previous,
};

Binary file not shown.

BIN
bluez-5.71.tar.xz Normal file

Binary file not shown.

View File

@ -1,7 +1,7 @@
Name: bluez
Summary: Bluetooth utilities
Version: 5.54
Release: 19
Version: 5.71
Release: 1
License: GPLv2+
URL: http://www.bluez.org/
Source0: http://www.kernel.org/pub/linux/bluetooth/bluez-%{version}.tar.xz
@ -11,39 +11,16 @@ Source2: 69-btattach-bcm.rules
Source3: btattach-bcm@.service
Source4: btattach-bcm-service.sh
Patch0001: 0001-obex-Use-GLib-helper-function-to-manipulate-paths.patch
Patch0002: 0001-build-Always-define-confdir-and-statedir.patch
Patch0003: 0002-systemd-Add-PrivateTmp-and-NoNewPrivileges-options.patch
Patch0004: 0003-systemd-Add-more-filesystem-lockdown.patch
Patch0005: 0004-systemd-More-lockdown.patch
Patch0006: backport-CVE-2021-3588.patch
# workaround for broken tests (reported upstream but not yet fixed)
# upstream:https://github.com/bluez/bluez/commit/5fc60b2ce7c4370ff8d9bc3d3c3434b212465f40
Patch0007: backport-bluez-disable-test-mesh-crypto.patch
Patch0008: backport-media-rename-local-function-conflicting-with-pause-2.patch
Patch6000: backport-CVE-2020-27153.patch
Patch6001: backport-0001-CVE-2021-3658.patch
Patch6002: backport-0002-CVE-2021-3658.patch
Patch6003: backport-CVE-2021-43400.patch
Patch6004: backport-0001-CVE-2021-0129.patch
Patch6005: backport-0002-CVE-2021-0129.patch
Patch6006: backport-0003-CVE-2021-0129.patch
Patch6007: backport-0004-CVE-2021-0129.patch
Patch6008: backport-CVE-2022-0204.patch
Patch6009: backport-CVE-2021-41229.patch
Patch6010: backport-CVE-2022-39176.patch
Patch6011: backport-0001-CVE-2022-39177.patch
Patch6012: backport-0002-CVE-2022-39177.patch
Patch6000: backport-bluez-disable-test-mesh-crypto.patch
%ifarch sw_64
Patch6013: bluez-5.54-sw.patch
%endif
Patch6014: backport-CVE-2023-27349.patch
Patch6015: backport-CVE-2023-45866.patch
Patch6016: backport-CVE-2023-50229-CVE-2023-50230.patch
BuildRequires: dbus-devel >= 1.6 libell-devel >= 0.28 autoconf
BuildRequires: glib2-devel libical-devel readline-devel
BuildRequires: json-c-devel systemd-devel cups-devel libtool automake
BuildRequires: json-c-devel systemd-devel cups-devel libtool automake python3-docutils
Requires: dbus >= 1.6 %{name}-libs = %{version}-%{release}
Requires(post): systemd
Requires(preun): systemd
@ -93,7 +70,7 @@ libtoolize -f
autoreconf -f -i
%configure --enable-tools --enable-library --enable-deprecated \
--enable-sixaxis --enable-cups --enable-nfc --enable-mesh \
--enable-testing \
--enable-hid2hci --enable-testing \
--with-systemdsystemunitdir=%{_unitdir} \
--with-systemduserunitdir=%{_userunitdir}
%make_build V=1
@ -154,8 +131,8 @@ make check
%license COPYING
%config %{_sysconfdir}/bluetooth/main.conf
%config %{_sysconfdir}/bluetooth/mesh-main.conf
%config %{_sysconfdir}/dbus-1/system.d/bluetooth.conf
%config %{_sysconfdir}/dbus-1/system.d/bluetooth-mesh.conf
%{_datadir}/dbus-1/system.d/bluetooth.conf
%{_datadir}/dbus-1/system.d/bluetooth-mesh.conf
%{_bindir}/*
%{_libdir}/bluetooth/
%{_prefix}/lib/udev/hid2hci
@ -193,9 +170,13 @@ make check
%files help
%defattr(-,root,root)
%{_mandir}/man1/*
%{_mandir}/man5/*
%{_mandir}/man8/*
%changelog
* Tue Jan 23 2024 zhangpan <zhangpan103@h-partners.com> - 5.71-1
- update to 5.71
* Fri Dec 22 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 5.54-19
- fix CVE-2023-50229,CVE-2023-50230