Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package bluez for openSUSE:Factory checked in at 2024-09-25 21:52:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/bluez (Old) and /work/SRC/openSUSE:Factory/.bluez.new.29891 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "bluez" Wed Sep 25 21:52:47 2024 rev:208 rq:1202919 version:5.78 Changes: -------- --- /work/SRC/openSUSE:Factory/bluez/bluez.changes 2024-09-13 14:31:55.649830439 +0200 +++ /work/SRC/openSUSE:Factory/.bluez.new.29891/bluez.changes 2024-09-25 21:52:50.383154888 +0200 @@ -1,0 +2,6 @@ +Wed Sep 18 08:35:40 UTC 2024 - pallas wept <[email protected]> + +- add Fix-crash-after-bt_uhid_unregister_all.patch to fix crashes + when devices disconnect or go to sleep + +------------------------------------------------------------------- New: ---- Fix-crash-after-bt_uhid_unregister_all.patch BETA DEBUG BEGIN: New: - add Fix-crash-after-bt_uhid_unregister_all.patch to fix crashes when devices disconnect or go to sleep BETA DEBUG END: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ bluez.spec ++++++ --- /var/tmp/diff_new_pack.uF17do/_old 2024-09-25 21:52:51.187188330 +0200 +++ /var/tmp/diff_new_pack.uF17do/_new 2024-09-25 21:52:51.195188663 +0200 @@ -62,6 +62,8 @@ Patch15: hcidump-Fix-memory-leak-with-malformed-packet.patch # bsc#1013712 CVE-2016-9798 Patch16: hcidump-Fixed-malformed-segment-frame-length.patch +# Fix crash when devices disconnect or go to sleep. Upstream issue 952 +Patch17: Fix-crash-after-bt_uhid_unregister_all.patch # Upstream suggests to use btmon instead of hcidump and does not want those patches # => PATCH-FIX-OPENSUSE for those two :-) # fix some memory leak with malformed packet (reported upstream but not yet fixed) ++++++ Fix-crash-after-bt_uhid_unregister_all.patch ++++++ >From 9a6a84a8a2b9336c2cdb943146207cb8a5a5260c Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz <[email protected]> Date: Mon, 16 Sep 2024 16:00:31 -0400 Subject: [PATCH] shared/uhid: Fix crash after bt_uhid_unregister_all This fixes the following crash which happens when bt_uhid_unregister_all is called from a notification callback: Invalid read of size 8 at 0x1D9EFF: queue_foreach (queue.c:206) by 0x1DEE58: uhid_read_handler (uhid.c:164) Address 0x51286d8 is 8 bytes inside a block of size 16 free'd at 0x48478EF: free (vg_replace_malloc.c:989) by 0x1DA08D: queue_remove_if (queue.c:292) by 0x1DA12F: queue_remove_all (queue.c:321) by 0x1DE592: bt_uhid_unregister_all (uhid.c:300) Fixes: https://github.com/bluez/bluez/issues/952 --- src/shared/uhid.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/shared/uhid.c b/src/shared/uhid.c index ed21e1399..20bd26781 100644 --- a/src/shared/uhid.c +++ b/src/shared/uhid.c @@ -42,6 +42,7 @@ struct bt_uhid { int ref_count; struct io *io; unsigned int notify_id; + bool notifying; struct queue *notify_list; struct queue *input; uint8_t type; @@ -56,6 +57,7 @@ struct uhid_notify { uint32_t event; bt_uhid_callback_t func; void *user_data; + bool removed; }; static void uhid_replay_free(struct uhid_replay *replay) @@ -134,6 +136,28 @@ static int bt_uhid_record(struct bt_uhid *uhid, bool input, return 0; } +static bool match_removed(const void *a, const void *b) +{ + const struct uhid_notify *notify = a; + + return notify->removed; +} + +static void uhid_notify(struct bt_uhid *uhid, struct uhid_event *ev) +{ + /* Add a reference to the uhid to ensure it doesn't get freed while at + * notify_handler. + */ + bt_uhid_ref(uhid); + + uhid->notifying = true; + queue_foreach(uhid->notify_list, notify_handler, ev); + uhid->notifying = false; + queue_remove_all(uhid->notify_list, match_removed, NULL, free); + + bt_uhid_unref(uhid); +} + static bool uhid_read_handler(struct io *io, void *user_data) { struct bt_uhid *uhid = user_data; @@ -161,7 +185,7 @@ static bool uhid_read_handler(struct io *io, void *user_data) break; } - queue_foreach(uhid->notify_list, notify_handler, &ev); + uhid_notify(uhid, &ev); return true; } @@ -292,13 +316,30 @@ static bool match_not_id(const void *a, const void *b) return notify->id != id; } +static void uhid_notify_removed(void *data, void *user_data) +{ + struct uhid_notify *notify = data; + struct bt_uhid *uhid = user_data; + + /* Skip marking start_id as removed since that is not removed with + * unregister all. + */ + if (notify->id == uhid->start_id) + return; + + notify->removed = true; +} + bool bt_uhid_unregister_all(struct bt_uhid *uhid) { if (!uhid) return false; - queue_remove_all(uhid->notify_list, match_not_id, + if (!uhid->notifying) + queue_remove_all(uhid->notify_list, match_not_id, UINT_TO_PTR(uhid->start_id), free); + else + queue_foreach(uhid->notify_list, uhid_notify_removed, uhid); return true; } @@ -588,7 +629,7 @@ int bt_uhid_replay(struct bt_uhid *uhid) return 0; } - queue_foreach(uhid->notify_list, notify_handler, ev); + uhid_notify(uhid, ev); return 0; }
