!110 update to 5.71
From: @zppzhangpan Reviewed-by: @yanan-rock Signed-off-by: @yanan-rock
This commit is contained in:
commit
188827b676
@ -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
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
|
|
||||||
@ -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);
|
|
||||||
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
@ -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,
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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))
|
|
||||||
|
|
||||||
@ -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;
|
|
||||||
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
|
|
||||||
@ -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;
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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),
|
|
||||||
@ -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
BIN
bluez-5.71.tar.xz
Normal file
Binary file not shown.
41
bluez.spec
41
bluez.spec
@ -1,7 +1,7 @@
|
|||||||
Name: bluez
|
Name: bluez
|
||||||
Summary: Bluetooth utilities
|
Summary: Bluetooth utilities
|
||||||
Version: 5.54
|
Version: 5.71
|
||||||
Release: 19
|
Release: 1
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
URL: http://www.bluez.org/
|
URL: http://www.bluez.org/
|
||||||
Source0: http://www.kernel.org/pub/linux/bluetooth/bluez-%{version}.tar.xz
|
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
|
Source3: btattach-bcm@.service
|
||||||
Source4: btattach-bcm-service.sh
|
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)
|
# workaround for broken tests (reported upstream but not yet fixed)
|
||||||
# upstream:https://github.com/bluez/bluez/commit/5fc60b2ce7c4370ff8d9bc3d3c3434b212465f40
|
# upstream:https://github.com/bluez/bluez/commit/5fc60b2ce7c4370ff8d9bc3d3c3434b212465f40
|
||||||
Patch0007: backport-bluez-disable-test-mesh-crypto.patch
|
Patch6000: 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
|
|
||||||
%ifarch sw_64
|
%ifarch sw_64
|
||||||
Patch6013: bluez-5.54-sw.patch
|
Patch6013: bluez-5.54-sw.patch
|
||||||
%endif
|
%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: dbus-devel >= 1.6 libell-devel >= 0.28 autoconf
|
||||||
BuildRequires: glib2-devel libical-devel readline-devel
|
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: dbus >= 1.6 %{name}-libs = %{version}-%{release}
|
||||||
Requires(post): systemd
|
Requires(post): systemd
|
||||||
Requires(preun): systemd
|
Requires(preun): systemd
|
||||||
@ -93,7 +70,7 @@ libtoolize -f
|
|||||||
autoreconf -f -i
|
autoreconf -f -i
|
||||||
%configure --enable-tools --enable-library --enable-deprecated \
|
%configure --enable-tools --enable-library --enable-deprecated \
|
||||||
--enable-sixaxis --enable-cups --enable-nfc --enable-mesh \
|
--enable-sixaxis --enable-cups --enable-nfc --enable-mesh \
|
||||||
--enable-testing \
|
--enable-hid2hci --enable-testing \
|
||||||
--with-systemdsystemunitdir=%{_unitdir} \
|
--with-systemdsystemunitdir=%{_unitdir} \
|
||||||
--with-systemduserunitdir=%{_userunitdir}
|
--with-systemduserunitdir=%{_userunitdir}
|
||||||
%make_build V=1
|
%make_build V=1
|
||||||
@ -154,8 +131,8 @@ make check
|
|||||||
%license COPYING
|
%license COPYING
|
||||||
%config %{_sysconfdir}/bluetooth/main.conf
|
%config %{_sysconfdir}/bluetooth/main.conf
|
||||||
%config %{_sysconfdir}/bluetooth/mesh-main.conf
|
%config %{_sysconfdir}/bluetooth/mesh-main.conf
|
||||||
%config %{_sysconfdir}/dbus-1/system.d/bluetooth.conf
|
%{_datadir}/dbus-1/system.d/bluetooth.conf
|
||||||
%config %{_sysconfdir}/dbus-1/system.d/bluetooth-mesh.conf
|
%{_datadir}/dbus-1/system.d/bluetooth-mesh.conf
|
||||||
%{_bindir}/*
|
%{_bindir}/*
|
||||||
%{_libdir}/bluetooth/
|
%{_libdir}/bluetooth/
|
||||||
%{_prefix}/lib/udev/hid2hci
|
%{_prefix}/lib/udev/hid2hci
|
||||||
@ -193,9 +170,13 @@ make check
|
|||||||
%files help
|
%files help
|
||||||
%defattr(-,root,root)
|
%defattr(-,root,root)
|
||||||
%{_mandir}/man1/*
|
%{_mandir}/man1/*
|
||||||
|
%{_mandir}/man5/*
|
||||||
%{_mandir}/man8/*
|
%{_mandir}/man8/*
|
||||||
|
|
||||||
%changelog
|
%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
|
* Fri Dec 22 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 5.54-19
|
||||||
- fix CVE-2023-50229,CVE-2023-50230
|
- fix CVE-2023-50229,CVE-2023-50230
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user