shared/bap: Fix crash when canceling requests
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 9 Nov 2022 21:02:49 +0000 (13:02 -0800)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 5 Jan 2024 10:11:33 +0000 (15:41 +0530)
If bt_bap_unref/bap_free is called while there is an ongoing pending
request it may endup calling into bap_notify_ready which will try to
notify ready callbacks while holding a reference, but in case the
reference is already 0 that means it would switch to 1 and back 0
causing a double free.

To prevent that bap_notify_ready now checks that the reference is not 0
with use of bt_bap_ref_safe.

src/shared/bap.c

index 25369e6..21aa8aa 100644 (file)
@@ -2638,6 +2638,14 @@ struct bt_bap *bt_bap_ref(struct bt_bap *bap)
        return bap;
 }
 
+static struct bt_bap *bt_bap_ref_safe(struct bt_bap *bap)
+{
+       if (!bap || !bap->ref_count)
+               return NULL;
+
+       return bt_bap_ref(bap);
+}
+
 void bt_bap_unref(struct bt_bap *bap)
 {
        if (!bap)
@@ -2656,7 +2664,8 @@ static void bap_notify_ready(struct bt_bap *bap)
        if (!queue_isempty(bap->pending))
                return;
 
-       bt_bap_ref(bap);
+       if (!bt_bap_ref_safe(bap))
+               return;
 
        for (entry = queue_get_entries(bap->ready_cbs); entry;
                                                        entry = entry->next) {