From: "Frédéric Danis" <frederic.danis@collabora.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ] transport: Fix use-after-free when replacing a linked transport's owner
Date: Mon, 31 Aug 2026 16:45:56 +0200 [thread overview]
Message-ID: <20260831144556.128154-1-frederic.danis@collabora.com> (raw)
linked_transport_set_owner() unconditionally overwrote a linked
transport's owner pointer. If that transport already had a different
owner assigned (e.g. its own Acquire request was still pending when the
paired transport's owner was set), the previous media_owner was
orphaned: its D-Bus disconnect watch stayed registered and its
->transport back-pointer kept pointing at the transport. Once the
transport was later destroyed, the still-registered watch would
eventually fire media_owner_exit() and dereference the freed transport.
Tear down any pre-existing, different owner via
media_transport_remove_owner() before assigning the new one, so its
pending request is replied to, its watch is removed and the owner is
freed instead of leaked. Since media_transport_remove_owner() itself
recurses into linked_transport_remove_owner() for linked streams, also
guard linked_transport_remove_owner() so it only clears a transport's
owner when it still matches the owner being removed, preventing it
from clobbering an owner that was already reassigned during that
recursion.
Assisted-by: Claude:claude-sonnet-5
---
profiles/audio/transport.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 22a755064..e3f3df50e 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -336,6 +336,13 @@ static void linked_transport_remove_owner(void *data, void *user_data)
return;
}
+ /* Owner may have already been replaced (e.g. by a subsequent
+ * linked_transport_set_owner), in which case it is not this
+ * function's place to clear it.
+ */
+ if (transport->owner != owner)
+ return;
+
DBG("Transport %s Owner %s", transport->path, owner->name);
transport->owner = NULL;
}
@@ -728,6 +735,16 @@ static void linked_transport_set_owner(void *data, void *user_data)
return;
}
+ /* If the linked transport already has a different owner (e.g. it
+ * was Acquired separately), tear it down properly instead of
+ * silently overwriting it. Otherwise the previous owner is
+ * orphaned: its D-Bus disconnect watch stays registered and its
+ * ->transport back-pointer becomes dangling once this transport is
+ * later destroyed, causing a use-after-free when the watch fires.
+ */
+ if (transport->owner && transport->owner != owner)
+ media_transport_remove_owner(transport);
+
DBG("Transport %s Owner %s", transport->path, owner->name);
transport->owner = owner;
}
--
2.43.0
next reply other threads:[~2026-08-31 14:46 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 14:45 Frédéric Danis [this message]
2026-08-31 15:51 ` [BlueZ] transport: Fix use-after-free when replacing a linked transport's owner bluez.test.bot
2026-09-02 15:40 ` [PATCH BlueZ] " patchwork-bot+bluetooth
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260831144556.128154-1-frederic.danis@collabora.com \
--to=frederic.danis@collabora.com \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.