main/bluez: fix CVE-2020-27153

See: #12053
This commit is contained in:
Leo 2020-12-09 21:34:04 -03:00
parent 35e92aa084
commit cd7fe7b4b4
2 changed files with 101 additions and 2 deletions

View File

@ -1,7 +1,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=bluez
pkgver=5.50
pkgrel=4
pkgrel=5
pkgdesc="Tools for the Bluetooth protocol stack"
url="http://www.bluez.org/"
arch="all"
@ -25,10 +25,13 @@ source="https://www.kernel.org/pub/linux/bluetooth/bluez-$pkgver.tar.xz
disable-lock-test.patch
fix-endianness.patch
CVE-2020-0556.patch
CVE-2020-27153.patch
"
builddir="$srcdir/$pkgname-$pkgver"
# secfixes:
# 5.50-r5:
# - CVE-2020-27153
# 5.50-r4:
# - CVE-2020-0556
@ -126,4 +129,5 @@ d5fd1c962bd846eaa6fff879bab85f753eb367d514f82d133b5d3242e1da989af5eddd942c60a87d
41ce7ccf78cca97563f0ef31e01dac6eb4484c24fe57be360b5e8de8c5bff5845e9d395766f891bd3f123788344456c88c9fc00cd1bb7c6a1dca89d09f19172b bluez-5.40-obexd_without_systemd-1.patch
04c4889372c8e790bb338dde7ffa76dc32fcf7370025c71b9184fcf17fd01ade4a6613d84d648303af3bbc54043ad489f29fc0cd4679ec8c9029dcb846d7e026 disable-lock-test.patch
118d55183860f395fc4bdc93efffb13902ebf7388cad722b9061cd2860d404333e500af521741c3d92c0f8a161f6810348fbeb6682e49c372383f417aed8c76a fix-endianness.patch
1f7c41399e746942e091db22c1b42a0bd87dafd83c5074a34c24f51efd88ed4d2957308f9b4da0fdcd6cd99ea5b9e1885d628ae01ddde56cf31140ccc895be61 CVE-2020-0556.patch"
1f7c41399e746942e091db22c1b42a0bd87dafd83c5074a34c24f51efd88ed4d2957308f9b4da0fdcd6cd99ea5b9e1885d628ae01ddde56cf31140ccc895be61 CVE-2020-0556.patch
c8e65bdfb5edc8edd0d1f9a153a7d5b953f0c5700aa61645af251cd857117990090a27c0ee133056fc045d0f6b6a3c1aad60ff0dfd3707c2c5ba29c518fccca8 CVE-2020-27153.patch"

View File

@ -0,0 +1,95 @@
Adapted from https://github.com/bluez/bluez/commit/1cd644db8c23a2f530ddb93cebed7dacc5f5721a
diff --git a/src/shared/att.c b/src/shared/att.c
index 0ea6d55..b0fdb8e 100644
--- 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 *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);
@@ -572,11 +575,6 @@ static bool disconnect_cb(struct io *io, void *user_data)
att->io = NULL;
att->fd = -1;
- /* 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;
@@ -589,6 +587,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);
@@ -1306,6 +1313,30 @@ static bool match_op_id(const void *a, const void *b)
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;
@@ -1325,6 +1356,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;