From: Eduardo de Souza Alves <noreply@github.com>
To: linux-bluetooth@vger.kernel.org
Subject: [bluez/bluez] 7d263c: a2dp: Fix UAF after rejected SetConfiguration
Date: Thu, 01 Oct 2026 08:45:59 -0700 [thread overview]
Message-ID: <bluez/bluez/push/refs/heads/1177732/000000-814917@github.com> (raw)
Branch: refs/heads/1177732
Home: https://github.com/bluez/bluez
Commit: 7d263ccc3d71d3e962b064606efab97f88863f49
https://github.com/bluez/bluez/commit/7d263ccc3d71d3e962b064606efab97f88863f49
Author: Eduardo Alves <eduardoalves8006@gmail.com>
Date: 2026-10-01 (Thu, 01 Oct 2026)
Changed paths:
M profiles/audio/a2dp.c
Log Message:
-----------
a2dp: Fix UAF after rejected SetConfiguration
When the MediaEndpoint1 rejects SetConfiguration, auto_config() calls
setconf_cb() with an error and avdtp frees the avdtp_stream, but the
a2dp_stream wrapping it is left on sep->streams with a dangling stream
pointer. The next stream configured on the same session finds it in
a2dp_config() and reads the freed avdtp_stream:
ERROR: AddressSanitizer: heap-use-after-free
READ of size 4
#0 avdtp_stream_get_state profiles/audio/avdtp.c:3952
#1 a2dp_config profiles/audio/a2dp.c:3282
#2 select_complete profiles/audio/source.c:200
#3 finalize_select profiles/audio/a2dp.c:486
freed by thread T0 here:
#1 stream_free profiles/audio/avdtp.c:747
#2 setconf_cb profiles/audio/avdtp.c:1504
#3 auto_config profiles/audio/a2dp.c:752
#4 endpoint_setconf_cb profiles/audio/a2dp.c:768
Fix it by destroying the a2dp_stream when the configuration is
rejected, which also drops the session reference it holds.
This can be reproduced with test-functional using two VMs over btvirt,
where the A2DP Sink endpoint replies to SetConfiguration with an error
and the sink then connects to the source on the same session.
Assisted-by: Claude:claude-opus-5-5
Commit: 81491780ae3af461d199e85904d27d3b3b5aa94e
https://github.com/bluez/bluez/commit/81491780ae3af461d199e85904d27d3b3b5aa94e
Author: Eduardo Alves <eduardoalves8006@gmail.com>
Date: 2026-10-01 (Thu, 01 Oct 2026)
Changed paths:
M profiles/audio/a2dp.c
M profiles/audio/media.c
Log Message:
-----------
a2dp: Fix crash on NULL session in auto_config
If the AVDTP channel is disconnected while bluetoothd is still waiting
for the MediaEndpoint1 to reply to SetConfiguration, channel_free()
sets setup->session to NULL but the setup stays alive since the pending
endpoint request holds a reference to it. Once the endpoint replies, or
the call times out and the request is canceled, endpoint_setconf_cb()
calls auto_config() which passes the NULL session to avdtp_get_device()
and then dereferences the resulting NULL device:
bluetoothd[820]: profiles/audio/media.c:endpoint_reply() Endpoint
replied with an error: org.freedesktop.DBus.Error.NoReply
kernel: bluetoothd[820]: segfault at 1a0 ip 00005633dd741323
sp 00007ffe51923650 error 4 in bluetoothd
#0 auto_config (data=0x56340361a120) at profiles/audio/a2dp.c:723
#1 endpoint_setconf_cb (setup=...) at profiles/audio/a2dp.c:768
#2 media_endpoint_cancel (request=...) at profiles/audio/media.c:208
#3 media_endpoint_cancel_all () at profiles/audio/media.c:216
#4 clear_endpoint () at profiles/audio/media.c:379
#5 endpoint_reply (user_data=...) at profiles/audio/media.c:407
(gdb) p *setup
$1 = {chan = 0x0, session = 0x0, ...,
setconf_cb = 0x5633dd74c780 <setconf_cb>, ..., ref = 2}
Commit 14750a2e48f4 ("audio/a2dp: Fix Access session device only when
its valid") fixed the same crash, but commit 77932f2dac1a
("profiles/audio: add nullity checks") moved avdtp_get_device() back
ahead of the checks. Just reordering is not enough though: the
a2dp_stream is still on sep->streams, so the aborted check passes and
setconf_cb() would then be called with a NULL session as well.
Fix it by rejecting the pending Set Configuration in channel_free()
while the session is still valid, which also frees the pending
avdtp_stream and the a2dp_stream, both previously leaked together with
the session reference held by the latter, and by making auto_config()
bail out when setup->session is NULL, releasing its setup reference.
setconf_cb is cleared once called so it cannot be called twice.
channel_free() also clears the endpoint configuration, which sends
ClearConfiguration and removes the MediaTransport created for the
request. Otherwise a late successful reply leaves the transport
registered and the next connection fails with "Resource temporarily
unavailable". Since the transport may now be freed while the request
is pending, endpoint_remove_transport() resets the transport of the
pending requests so a late error reply does not free it twice.
The crash can be reproduced with test-functional using two VMs over
btvirt, where the A2DP Sink endpoint delays or never sends its
SetConfiguration reply and the A2DP Source disconnects meanwhile.
Assisted-by: Claude:claude-opus-5-5
Compare: https://github.com/bluez/bluez/compare/7d263ccc3d71%5E...81491780ae3a
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
reply other threads:[~2026-10-01 15:46 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=bluez/bluez/push/refs/heads/1177732/000000-814917@github.com \
--to=noreply@github.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox