All of lore.kernel.org
 help / color / mirror / Atom feed
* [Bluez PATCH v4] a2dp: Fix crash in channel_free while waiting cmd resp
@ 2021-07-14  9:02 Howard Chung
  2021-07-14  9:36 ` [Bluez,v4] " bluez.test.bot
  0 siblings, 1 reply; 3+ messages in thread
From: Howard Chung @ 2021-07-14  9:02 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz; +Cc: Yun-Hao Chung, Archie Pusaka

From: Yun-Hao Chung <howardchung@chromium.org>

When channel_free is called and we are waiting for a command response
from the peer, bluez NULL the setup->session but would not free its
setup_cb. Since setup_cb holds a ref of setup, the setup wouldn't be
freed and if service_removed is called after channel_free, a2dp_cancel
tries to abort the ongoing avdtp commands, which accesses the
setup->session and triggers a crash.

This change finalizes all avdtp commands before assigning setup->session
to NULL in channel_free.

Crash stack trace:
0x000059f01943e688	(bluetoothd -avdtp.c:3690)
avdtp_abort
0x000059f01943928a	(bluetoothd -a2dp.c:3069)
a2dp_cancel
0x000059f0194377fa	(bluetoothd -sink.c:324)
sink_unregister
0x000059f01948715a	(bluetoothd -service.c:177)
service_remove
0x000059f01948d77c	(bluetoothd -device.c:5346)
device_remove
0x000059f019476d14	(bluetoothd -adapter.c:7202)
adapter_remove
0x000059f019476c3e	(bluetoothd -adapter.c:10827)
adapter_cleanup
0x000059f01949d8d7	(bluetoothd -main.c:1114)		main
0x0000787b36185d74	(libc.so.6 -libc-start.c:308)
__libc_start_main
0x000059f019433e39	(bluetoothd + 0x00026e39)		_start
0x00007fff2d2c0127

Reviewed-by: Archie Pusaka <apusaka@chromium.org>
---
There are two other options to fix this crash.
1. add a NULL check in a2dp_cancel before calling avdtp_abort.
2. call setup_cb_free to every setup_cb in setup->cb in channel_free.

Since each setup_cb needs setup->session, I think there is no need to
keep the setup_cb after assigning setup->session to NULL. So the first
option is not ideal. If the second option is adopted, there would be
some time that sink/source->connect_id/disconnect_id is not zero, but
there is no corresponding setup_cb.

Test steps:
Reproduce the crash with the following steps. Verify the crash is
no longer observed after this change.
1. ignore AVDTP_SET_CONFIGURATION resp by modifying avdtp.c
2. turn on a paired headset
3. check the bluetooth.log, while bluez is waiting for
   AVDTP_SET_CONFIGURATION resp, stop bluetoothd immediately.
   This will trigger:
   session_cb (I/O error) -> connection_lost
   -> avdtp_set_state (AVDTP_SESSION_STATE_DISCONNECTED)
   -> avdtp_state_cb -> channel_remove -> channel_free
   then:
   adapter_cleanup -> adapter_remove -> device_remove -> service_remove
   -> a2dp_sink_remove -> sink_unregister -> sink_free -> a2dp_cancel
4. check if bluetoothd crash
The above steps can trigger the crash 100%.

Changes in v4:
- Fix compiling errors in finalize_all

Changes in v3:
- Remove the duplicated finalize_all

Changes in v2:
- Implement helper function finalize_all
- add setup_ref before finalize_all, in case the setup is freed during
  finalize

 profiles/audio/a2dp.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index d31ed845cbe7..86bc02994f75 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -404,6 +404,41 @@ static void finalize_discover(struct a2dp_setup *s)
 	}
 }
 
+static gboolean finalize_all(gpointer data)
+{
+	struct a2dp_setup *s = data;
+	struct avdtp_stream *stream = s->err ? NULL : s->stream;
+	GSList *l;
+
+	for (l = s->cb; l != NULL; ) {
+		struct a2dp_setup_cb *cb = l->data;
+
+		l = l->next;
+
+		if (cb->discover_cb) {
+			cb->discover_cb(s->session, s->seps,
+					error_to_errno(s->err), cb->user_data);
+		} else if (cb->select_cb) {
+			cb->select_cb(s->session, s->sep, s->caps,
+					error_to_errno(s->err), cb->user_data);
+		} else if (cb->suspend_cb) {
+			cb->suspend_cb(s->session,
+					error_to_errno(s->err), cb->user_data);
+		} else if (cb->resume_cb) {
+			cb->resume_cb(s->session,
+					error_to_errno(s->err), cb->user_data);
+		} else if (cb->config_cb) {
+			cb->config_cb(s->session, s->sep, stream,
+					error_to_errno(s->err), cb->user_data);
+		} else
+			warn("setup_cb doesn't have any callback function");
+
+		setup_cb_free(cb);
+	}
+
+	return FALSE;
+}
+
 static struct a2dp_setup *find_setup_by_session(struct avdtp *session)
 {
 	GSList *l;
@@ -1540,9 +1575,12 @@ static void channel_free(void *data)
 	setup = find_setup_by_session(chan->session);
 	if (setup) {
 		setup->chan = NULL;
+		setup_ref(setup);
+		/* Finalize pending commands before we NULL setup->session */
+		finalize_setup_errno(setup, -ENOTCONN, finalize_all, NULL);
 		avdtp_unref(setup->session);
 		setup->session = NULL;
-		finalize_setup_errno(setup, -ENOTCONN, NULL);
+		setup_unref(setup);
 	}
 
 	g_free(chan);
-- 
2.32.0.93.g670b81a890-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* RE: [Bluez,v4] a2dp: Fix crash in channel_free while waiting cmd resp
  2021-07-14  9:02 [Bluez PATCH v4] a2dp: Fix crash in channel_free while waiting cmd resp Howard Chung
@ 2021-07-14  9:36 ` bluez.test.bot
  2021-07-14 18:41   ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 3+ messages in thread
From: bluez.test.bot @ 2021-07-14  9:36 UTC (permalink / raw)
  To: linux-bluetooth, howardchung

[-- Attachment #1: Type: text/plain, Size: 2986 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=515283

---Test result---

Test Summary:
CheckPatch                    PASS      0.34 seconds
GitLint                       FAIL      0.09 seconds
Prep - Setup ELL              PASS      37.99 seconds
Build - Prep                  PASS      0.10 seconds
Build - Configure             PASS      6.53 seconds
Build - Make                  PASS      165.22 seconds
Make Check                    PASS      9.22 seconds
Make Distcheck                PASS      193.33 seconds
Build w/ext ELL - Configure   PASS      6.37 seconds
Build w/ext ELL - Make        PASS      153.23 seconds

Details
##############################
Test: CheckPatch - PASS
Desc: Run checkpatch.pl script with rule in .checkpatch.conf

##############################
Test: GitLint - FAIL
Desc: Run gitlint with rule in .gitlint
Output:
a2dp: Fix crash in channel_free while waiting cmd resp
14: B3 Line contains hard tab characters (\t): "0x000059f01943e688	(bluetoothd -avdtp.c:3690)"
16: B3 Line contains hard tab characters (\t): "0x000059f01943928a	(bluetoothd -a2dp.c:3069)"
18: B3 Line contains hard tab characters (\t): "0x000059f0194377fa	(bluetoothd -sink.c:324)"
20: B3 Line contains hard tab characters (\t): "0x000059f01948715a	(bluetoothd -service.c:177)"
22: B3 Line contains hard tab characters (\t): "0x000059f01948d77c	(bluetoothd -device.c:5346)"
24: B3 Line contains hard tab characters (\t): "0x000059f019476d14	(bluetoothd -adapter.c:7202)"
26: B3 Line contains hard tab characters (\t): "0x000059f019476c3e	(bluetoothd -adapter.c:10827)"
28: B3 Line contains hard tab characters (\t): "0x000059f01949d8d7	(bluetoothd -main.c:1114)		main"
29: B3 Line contains hard tab characters (\t): "0x0000787b36185d74	(libc.so.6 -libc-start.c:308)"
31: B3 Line contains hard tab characters (\t): "0x000059f019433e39	(bluetoothd + 0x00026e39)		_start"


##############################
Test: Prep - Setup ELL - PASS
Desc: Clone, build, and install ELL

##############################
Test: Build - Prep - PASS
Desc: Prepare environment for build

##############################
Test: Build - Configure - PASS
Desc: Configure the BlueZ source tree

##############################
Test: Build - Make - PASS
Desc: Build the BlueZ source tree

##############################
Test: Make Check - PASS
Desc: Run 'make check'

##############################
Test: Make Distcheck - PASS
Desc: Run distcheck to check the distribution

##############################
Test: Build w/ext ELL - Configure - PASS
Desc: Configure BlueZ source with '--enable-external-ell' configuration

##############################
Test: Build w/ext ELL - Make - PASS
Desc: Build BlueZ source with '--enable-external-ell' configuration



---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Bluez,v4] a2dp: Fix crash in channel_free while waiting cmd resp
  2021-07-14  9:36 ` [Bluez,v4] " bluez.test.bot
@ 2021-07-14 18:41   ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2021-07-14 18:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Yun-hao Chung

Hi Howard,

On Wed, Jul 14, 2021 at 2:38 AM <bluez.test.bot@gmail.com> wrote:
>
> This is automated email and please do not reply to this email!
>
> Dear submitter,
>
> Thank you for submitting the patches to the linux bluetooth mailing list.
> This is a CI test results with your patch series:
> PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=515283
>
> ---Test result---
>
> Test Summary:
> CheckPatch                    PASS      0.34 seconds
> GitLint                       FAIL      0.09 seconds
> Prep - Setup ELL              PASS      37.99 seconds
> Build - Prep                  PASS      0.10 seconds
> Build - Configure             PASS      6.53 seconds
> Build - Make                  PASS      165.22 seconds
> Make Check                    PASS      9.22 seconds
> Make Distcheck                PASS      193.33 seconds
> Build w/ext ELL - Configure   PASS      6.37 seconds
> Build w/ext ELL - Make        PASS      153.23 seconds
>
> Details
> ##############################
> Test: CheckPatch - PASS
> Desc: Run checkpatch.pl script with rule in .checkpatch.conf
>
> ##############################
> Test: GitLint - FAIL
> Desc: Run gitlint with rule in .gitlint
> Output:
> a2dp: Fix crash in channel_free while waiting cmd resp
> 14: B3 Line contains hard tab characters (\t): "0x000059f01943e688      (bluetoothd -avdtp.c:3690)"
> 16: B3 Line contains hard tab characters (\t): "0x000059f01943928a      (bluetoothd -a2dp.c:3069)"
> 18: B3 Line contains hard tab characters (\t): "0x000059f0194377fa      (bluetoothd -sink.c:324)"
> 20: B3 Line contains hard tab characters (\t): "0x000059f01948715a      (bluetoothd -service.c:177)"
> 22: B3 Line contains hard tab characters (\t): "0x000059f01948d77c      (bluetoothd -device.c:5346)"
> 24: B3 Line contains hard tab characters (\t): "0x000059f019476d14      (bluetoothd -adapter.c:7202)"
> 26: B3 Line contains hard tab characters (\t): "0x000059f019476c3e      (bluetoothd -adapter.c:10827)"
> 28: B3 Line contains hard tab characters (\t): "0x000059f01949d8d7      (bluetoothd -main.c:1114)               main"
> 29: B3 Line contains hard tab characters (\t): "0x0000787b36185d74      (libc.so.6 -libc-start.c:308)"
> 31: B3 Line contains hard tab characters (\t): "0x000059f019433e39      (bluetoothd + 0x00026e39)               _start"
>
>
> ##############################
> Test: Prep - Setup ELL - PASS
> Desc: Clone, build, and install ELL
>
> ##############################
> Test: Build - Prep - PASS
> Desc: Prepare environment for build
>
> ##############################
> Test: Build - Configure - PASS
> Desc: Configure the BlueZ source tree
>
> ##############################
> Test: Build - Make - PASS
> Desc: Build the BlueZ source tree
>
> ##############################
> Test: Make Check - PASS
> Desc: Run 'make check'
>
> ##############################
> Test: Make Distcheck - PASS
> Desc: Run distcheck to check the distribution
>
> ##############################
> Test: Build w/ext ELL - Configure - PASS
> Desc: Configure BlueZ source with '--enable-external-ell' configuration
>
> ##############################
> Test: Build w/ext ELL - Make - PASS
> Desc: Build BlueZ source with '--enable-external-ell' configuration
>
>
>
> ---
> Regards,
> Linux Bluetooth

Applied, thanks.

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-07-14 18:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-14  9:02 [Bluez PATCH v4] a2dp: Fix crash in channel_free while waiting cmd resp Howard Chung
2021-07-14  9:36 ` [Bluez,v4] " bluez.test.bot
2021-07-14 18:41   ` Luiz Augusto von Dentz

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.