Skip to content
Snippets Groups Projects
Commit 142c5e39 authored by Salvatore Bonaccorso's avatar Salvatore Bonaccorso Committed by Apertis CI robot
Browse files

Import Debian changes 5.50-1.2~deb10u2

parent 275e8f65
No related branches found
No related tags found
4 merge requests!29Merge changes from apertis/v2021-security into apertis/v2021,!28Merge changes from apertis/v2020-security into apertis/v2020,!27Release bluez version 5.50-1.2~deb10u2+apertis1,!25Update from debian/buster-security for apertis/v2021-security
Pipeline #432447 canceled
bluez (5.50-1.2~deb10u2) buster-security; urgency=high
* Non-maintainer upload by the Security Team.
* shared/att: Fix possible crash on disconnect (CVE-2020-27153)
* shared/gatt-server: Fix not properly checking for secure flags
(CVE-2020-26558, CVE-2021-0129) (Closes: #989614)
-- Salvatore Bonaccorso <carnil@debian.org> Wed, 04 Aug 2021 21:18:19 +0200
bluez (5.50-1.2~deb10u1) buster-security; urgency=high
* Non-maintainer upload by the Security Team.
......
......@@ -13,3 +13,5 @@ HOGP-must-only-accept-data-from-bonded-devices.patch
HID-accepts-bonded-device-connections-only.patch
input-hog-Attempt-to-set-security-level-if-not-bonde.patch
input-Add-LEAutoSecurity-setting-to-input.conf.patch
shared-att-Fix-possible-crash-on-disconnect.patch
shared-gatt-server-Fix-not-properly-checking-for-sec.patch
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Wed, 15 Jul 2020 18:25:37 -0700
Subject: shared/att: Fix possible crash on disconnect
Origin: https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=1cd644db8c23a2f530ddb93cebed7dacc5f5721a
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2020-27153
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)
[Salvatore Bonaccorso: Backport to 5.50 for context changes for version before
0379b6c8761d ("share/att: Add EATT support")]
---
src/shared/att.c | 46 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 40 insertions(+), 6 deletions(-)
--- a/src/shared/att.c
+++ b/src/shared/att.c
@@ -62,6 +62,7 @@ struct bt_att {
struct queue *ind_queue; /* Queued ATT protocol indications */
struct att_send_op *pending_ind;
struct queue *write_queue; /* Queue of PDUs ready to send */
+ bool in_disc; /* Cleanup queues on disconnect_cb */
bool writer_active;
struct queue *notify_list; /* List of registered callbacks */
@@ -211,8 +212,10 @@ static void destroy_att_send_op(void *da
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);
@@ -571,11 +574,6 @@ static bool disconnect_cb(struct io *io,
io_destroy(att->io);
att->io = NULL;
- /* 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 (att->pending_req) {
disc_att_send_op(att->pending_req);
att->pending_req = NULL;
@@ -588,6 +586,15 @@ static bool disconnect_cb(struct io *io,
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);
@@ -1288,6 +1295,30 @@ static bool match_op_id(const void *a, c
return op->id == id;
}
+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)
{
struct att_send_op *op;
@@ -1307,6 +1338,9 @@ bool bt_att_cancel(struct bt_att *att, u
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;
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Tue, 2 Mar 2021 11:38:33 -0800
Subject: shared/gatt-server: Fix not properly checking for secure flags
Origin: https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit?id=00da0fb4972cf59e1c075f313da81ea549cb8738
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2020-26558
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-0129
Bug-Debian: https://bugs.debian.org/989614
When passing the mask to check_permissions all valid permissions for
the operation must be set including BT_ATT_PERM_SECURE flags.
[Salvatore Bonaccorso: Backport to 5.50, context changes before ee49fb1d1361
("shared/gatt-server: Fix read multiple charc values")]
---
src/shared/att-types.h | 8 ++++++++
src/shared/gatt-server.c | 25 +++++++------------------
2 files changed, 15 insertions(+), 18 deletions(-)
--- a/src/shared/att-types.h
+++ b/src/shared/att-types.h
@@ -132,6 +132,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
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -456,9 +456,7 @@ static void process_read_by_type(struct
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(uint8_t opcode, con
(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;
@@ -917,9 +913,7 @@ static void handle_read_req(struct bt_ga
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;
@@ -1014,9 +1008,7 @@ static void read_multiple_complete_cb(st
return;
}
- 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) {
bt_att_send_error_rsp(data->server->att,
BT_ATT_OP_READ_MULT_REQ, handle, ecode);
@@ -1279,9 +1271,7 @@ static void prep_write_cb(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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment