2021-07-13 03:53:37

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v2] a2dp: Fix crash in channel_free while waiting cmd resp

From: Yun-Hao Chung <[email protected]>

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 <[email protected]>
---
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 v2:
- Implement helper function finalize_all
- Add setup_ref before finalize_all, in case the setup is freed during
finalize

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

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index d31ed845cbe7..5d7c416a5deb 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -404,6 +404,69 @@ static void finalize_discover(struct a2dp_setup *s)
}
}

+static void finalize_all(struct a2dp_setup *s)
+{
+ 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->seps,
+ error_to_errno(s->err), cb->user_data);
+ } else if (cb->suspend_cb) {
+ cb->suspend_cb(s->session, s->seps,
+ error_to_errno(s->err), cb->user_data);
+ } else if (cb->resume_cb) {
+ cb->resume_cb(s->session, s->seps,
+ error_to_errno(s->err), cb->user_data);
+ } else if (cb->config_cb) {
+ cb->config_cb(s->session, s->seps,
+ error_to_errno(s->err), cb->user_data);
+ } else
+ warn("setup_cb doesn't have any callback function");
+
+ setup_cb_free(cb);
+ }
+}
+
+static void finalize_all(struct a2dp_setup *s)
+{
+ GSList *l;
+ struct avdtp_stream *stream = s->err ? NULL : s->stream;
+
+ 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->seps, 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->seps, stream,
+ error_to_errno(s->err), cb->user_data);
+ } else
+ warn("setup_cb doesn't have any callback function");
+
+ setup_cb_free(cb);
+ }
+}
+
static struct a2dp_setup *find_setup_by_session(struct avdtp *session)
{
GSList *l;
@@ -1540,9 +1603,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


2021-07-13 04:41:58

by bluez.test.bot

[permalink] [raw]
Subject: RE: [Bluez,v2] a2dp: Fix crash in channel_free while waiting cmd resp

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=514437

---Test result---

Test Summary:
CheckPatch PASS 0.46 seconds
GitLint FAIL 0.12 seconds
Prep - Setup ELL PASS 42.89 seconds
Build - Prep PASS 0.15 seconds
Build - Configure PASS 7.46 seconds
Build - Make FAIL 143.49 seconds
Make Check FAIL 0.49 seconds
Make Distcheck FAIL 129.00 seconds
Build w/ext ELL - Configure PASS 7.46 seconds
Build w/ext ELL - Make FAIL 131.89 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 - FAIL
Desc: Build the BlueZ source tree
Output:
profiles/audio/a2dp.c: In function ‘finalize_all’:
profiles/audio/a2dp.c:420:31: error: passing argument 2 of ‘cb->select_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
420 | cb->select_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:420:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:421:6: error: passing argument 3 of ‘cb->select_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
421 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:421:6: note: expected ‘GSList *’ {aka ‘struct _GSList *’} but argument is of type ‘int’
profiles/audio/a2dp.c:421:32: error: passing argument 4 of ‘cb->select_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
421 | error_to_errno(s->err), cb->user_data);
| ~~^~~~~~~~~~~
| |
| void *
profiles/audio/a2dp.c:421:32: note: expected ‘int’ but argument is of type ‘void *’
profiles/audio/a2dp.c:420:4: error: too few arguments to function ‘cb->select_cb’
420 | cb->select_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c:423:32: error: passing argument 2 of ‘cb->suspend_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
423 | cb->suspend_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:423:32: note: expected ‘int’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:424:6: error: passing argument 3 of ‘cb->suspend_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
424 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:424:6: note: expected ‘void *’ but argument is of type ‘int’
profiles/audio/a2dp.c:423:4: error: too many arguments to function ‘cb->suspend_cb’
423 | cb->suspend_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c:426:31: error: passing argument 2 of ‘cb->resume_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
426 | cb->resume_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:426:31: note: expected ‘int’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:427:6: error: passing argument 3 of ‘cb->resume_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
427 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:427:6: note: expected ‘void *’ but argument is of type ‘int’
profiles/audio/a2dp.c:426:4: error: too many arguments to function ‘cb->resume_cb’
426 | cb->resume_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c:429:31: error: passing argument 2 of ‘cb->config_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
429 | cb->config_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:429:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:430:6: error: passing argument 3 of ‘cb->config_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
430 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:430:6: note: expected ‘struct avdtp_stream *’ but argument is of type ‘int’
profiles/audio/a2dp.c:430:32: error: passing argument 4 of ‘cb->config_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
430 | error_to_errno(s->err), cb->user_data);
| ~~^~~~~~~~~~~
| |
| void *
profiles/audio/a2dp.c:430:32: note: expected ‘int’ but argument is of type ‘void *’
profiles/audio/a2dp.c:429:4: error: too few arguments to function ‘cb->config_cb’
429 | cb->config_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c: At top level:
profiles/audio/a2dp.c:438:13: error: redefinition of ‘finalize_all’
438 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
profiles/audio/a2dp.c:407:13: note: previous definition of ‘finalize_all’ was here
407 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
profiles/audio/a2dp.c: In function ‘finalize_all’:
profiles/audio/a2dp.c:452:31: error: passing argument 2 of ‘cb->select_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
452 | cb->select_cb(s->session, s->seps, s->caps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:452:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:461:31: error: passing argument 2 of ‘cb->config_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
461 | cb->config_cb(s->session, s->seps, stream,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:461:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c: In function ‘channel_free’:
profiles/audio/a2dp.c:1608:42: error: passing argument 3 of ‘finalize_setup_errno’ from incompatible pointer type [-Werror=incompatible-pointer-types]
1608 | finalize_setup_errno(setup, -ENOTCONN, finalize_all, NULL);
| ^~~~~~~~~~~~
| |
| void (*)(struct a2dp_setup *)
profiles/audio/a2dp.c:262:18: note: expected ‘GSourceFunc’ {aka ‘int (*)(void *)’} but argument is of type ‘void (*)(struct a2dp_setup *)’
262 | GSourceFunc cb1, ...)
| ~~~~~~~~~~~~^~~
At top level:
profiles/audio/a2dp.c:407:13: error: ‘finalize_all’ defined but not used [-Werror=unused-function]
407 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8531: profiles/audio/bluetoothd-a2dp.o] Error 1
make: *** [Makefile:4134: all] Error 2


##############################
Test: Make Check - FAIL
Desc: Run 'make check'
Output:
profiles/audio/a2dp.c: In function ‘finalize_all’:
profiles/audio/a2dp.c:420:31: error: passing argument 2 of ‘cb->select_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
420 | cb->select_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:420:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:421:6: error: passing argument 3 of ‘cb->select_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
421 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:421:6: note: expected ‘GSList *’ {aka ‘struct _GSList *’} but argument is of type ‘int’
profiles/audio/a2dp.c:421:32: error: passing argument 4 of ‘cb->select_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
421 | error_to_errno(s->err), cb->user_data);
| ~~^~~~~~~~~~~
| |
| void *
profiles/audio/a2dp.c:421:32: note: expected ‘int’ but argument is of type ‘void *’
profiles/audio/a2dp.c:420:4: error: too few arguments to function ‘cb->select_cb’
420 | cb->select_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c:423:32: error: passing argument 2 of ‘cb->suspend_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
423 | cb->suspend_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:423:32: note: expected ‘int’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:424:6: error: passing argument 3 of ‘cb->suspend_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
424 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:424:6: note: expected ‘void *’ but argument is of type ‘int’
profiles/audio/a2dp.c:423:4: error: too many arguments to function ‘cb->suspend_cb’
423 | cb->suspend_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c:426:31: error: passing argument 2 of ‘cb->resume_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
426 | cb->resume_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:426:31: note: expected ‘int’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:427:6: error: passing argument 3 of ‘cb->resume_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
427 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:427:6: note: expected ‘void *’ but argument is of type ‘int’
profiles/audio/a2dp.c:426:4: error: too many arguments to function ‘cb->resume_cb’
426 | cb->resume_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c:429:31: error: passing argument 2 of ‘cb->config_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
429 | cb->config_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:429:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:430:6: error: passing argument 3 of ‘cb->config_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
430 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:430:6: note: expected ‘struct avdtp_stream *’ but argument is of type ‘int’
profiles/audio/a2dp.c:430:32: error: passing argument 4 of ‘cb->config_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
430 | error_to_errno(s->err), cb->user_data);
| ~~^~~~~~~~~~~
| |
| void *
profiles/audio/a2dp.c:430:32: note: expected ‘int’ but argument is of type ‘void *’
profiles/audio/a2dp.c:429:4: error: too few arguments to function ‘cb->config_cb’
429 | cb->config_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c: At top level:
profiles/audio/a2dp.c:438:13: error: redefinition of ‘finalize_all’
438 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
profiles/audio/a2dp.c:407:13: note: previous definition of ‘finalize_all’ was here
407 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
profiles/audio/a2dp.c: In function ‘finalize_all’:
profiles/audio/a2dp.c:452:31: error: passing argument 2 of ‘cb->select_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
452 | cb->select_cb(s->session, s->seps, s->caps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:452:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:461:31: error: passing argument 2 of ‘cb->config_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
461 | cb->config_cb(s->session, s->seps, stream,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:461:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c: In function ‘channel_free’:
profiles/audio/a2dp.c:1608:42: error: passing argument 3 of ‘finalize_setup_errno’ from incompatible pointer type [-Werror=incompatible-pointer-types]
1608 | finalize_setup_errno(setup, -ENOTCONN, finalize_all, NULL);
| ^~~~~~~~~~~~
| |
| void (*)(struct a2dp_setup *)
profiles/audio/a2dp.c:262:18: note: expected ‘GSourceFunc’ {aka ‘int (*)(void *)’} but argument is of type ‘void (*)(struct a2dp_setup *)’
262 | GSourceFunc cb1, ...)
| ~~~~~~~~~~~~^~~
At top level:
profiles/audio/a2dp.c:407:13: error: ‘finalize_all’ defined but not used [-Werror=unused-function]
407 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8531: profiles/audio/bluetoothd-a2dp.o] Error 1
make: *** [Makefile:10406: check] Error 2


##############################
Test: Make Distcheck - FAIL
Desc: Run distcheck to check the distribution
Output:
../../profiles/audio/a2dp.c: In function ‘finalize_all’:
../../profiles/audio/a2dp.c:420:31: warning: passing argument 2 of ‘cb->select_cb’ from incompatible pointer type [-Wincompatible-pointer-types]
420 | cb->select_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
../../profiles/audio/a2dp.c:420:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
../../profiles/audio/a2dp.c:421:6: warning: passing argument 3 of ‘cb->select_cb’ makes pointer from integer without a cast [-Wint-conversion]
421 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
../../profiles/audio/a2dp.c:421:6: note: expected ‘GSList *’ {aka ‘struct _GSList *’} but argument is of type ‘int’
../../profiles/audio/a2dp.c:421:32: warning: passing argument 4 of ‘cb->select_cb’ makes integer from pointer without a cast [-Wint-conversion]
421 | error_to_errno(s->err), cb->user_data);
| ~~^~~~~~~~~~~
| |
| void *
../../profiles/audio/a2dp.c:421:32: note: expected ‘int’ but argument is of type ‘void *’
../../profiles/audio/a2dp.c:420:4: error: too few arguments to function ‘cb->select_cb’
420 | cb->select_cb(s->session, s->seps,
| ^~
../../profiles/audio/a2dp.c:423:32: warning: passing argument 2 of ‘cb->suspend_cb’ makes integer from pointer without a cast [-Wint-conversion]
423 | cb->suspend_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
../../profiles/audio/a2dp.c:423:32: note: expected ‘int’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
../../profiles/audio/a2dp.c:424:6: warning: passing argument 3 of ‘cb->suspend_cb’ makes pointer from integer without a cast [-Wint-conversion]
424 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
../../profiles/audio/a2dp.c:424:6: note: expected ‘void *’ but argument is of type ‘int’
../../profiles/audio/a2dp.c:423:4: error: too many arguments to function ‘cb->suspend_cb’
423 | cb->suspend_cb(s->session, s->seps,
| ^~
../../profiles/audio/a2dp.c:426:31: warning: passing argument 2 of ‘cb->resume_cb’ makes integer from pointer without a cast [-Wint-conversion]
426 | cb->resume_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
../../profiles/audio/a2dp.c:426:31: note: expected ‘int’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
../../profiles/audio/a2dp.c:427:6: warning: passing argument 3 of ‘cb->resume_cb’ makes pointer from integer without a cast [-Wint-conversion]
427 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
../../profiles/audio/a2dp.c:427:6: note: expected ‘void *’ but argument is of type ‘int’
../../profiles/audio/a2dp.c:426:4: error: too many arguments to function ‘cb->resume_cb’
426 | cb->resume_cb(s->session, s->seps,
| ^~
../../profiles/audio/a2dp.c:429:31: warning: passing argument 2 of ‘cb->config_cb’ from incompatible pointer type [-Wincompatible-pointer-types]
429 | cb->config_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
../../profiles/audio/a2dp.c:429:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
../../profiles/audio/a2dp.c:430:6: warning: passing argument 3 of ‘cb->config_cb’ makes pointer from integer without a cast [-Wint-conversion]
430 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
../../profiles/audio/a2dp.c:430:6: note: expected ‘struct avdtp_stream *’ but argument is of type ‘int’
../../profiles/audio/a2dp.c:430:32: warning: passing argument 4 of ‘cb->config_cb’ makes integer from pointer without a cast [-Wint-conversion]
430 | error_to_errno(s->err), cb->user_data);
| ~~^~~~~~~~~~~
| |
| void *
../../profiles/audio/a2dp.c:430:32: note: expected ‘int’ but argument is of type ‘void *’
../../profiles/audio/a2dp.c:429:4: error: too few arguments to function ‘cb->config_cb’
429 | cb->config_cb(s->session, s->seps,
| ^~
../../profiles/audio/a2dp.c: At top level:
../../profiles/audio/a2dp.c:438:13: error: redefinition of ‘finalize_all’
438 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
../../profiles/audio/a2dp.c:407:13: note: previous definition of ‘finalize_all’ was here
407 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
../../profiles/audio/a2dp.c: In function ‘finalize_all’:
../../profiles/audio/a2dp.c:452:31: warning: passing argument 2 of ‘cb->select_cb’ from incompatible pointer type [-Wincompatible-pointer-types]
452 | cb->select_cb(s->session, s->seps, s->caps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
../../profiles/audio/a2dp.c:452:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
../../profiles/audio/a2dp.c:461:31: warning: passing argument 2 of ‘cb->config_cb’ from incompatible pointer type [-Wincompatible-pointer-types]
461 | cb->config_cb(s->session, s->seps, stream,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
../../profiles/audio/a2dp.c:461:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
../../profiles/audio/a2dp.c: In function ‘channel_free’:
../../profiles/audio/a2dp.c:1608:42: warning: passing argument 3 of ‘finalize_setup_errno’ from incompatible pointer type [-Wincompatible-pointer-types]
1608 | finalize_setup_errno(setup, -ENOTCONN, finalize_all, NULL);
| ^~~~~~~~~~~~
| |
| void (*)(struct a2dp_setup *)
../../profiles/audio/a2dp.c:262:18: note: expected ‘GSourceFunc’ {aka ‘int (*)(void *)’} but argument is of type ‘void (*)(struct a2dp_setup *)’
262 | GSourceFunc cb1, ...)
| ~~~~~~~~~~~~^~~
make[2]: *** [Makefile:8531: profiles/audio/bluetoothd-a2dp.o] Error 1
make[1]: *** [Makefile:4134: all] Error 2
make: *** [Makefile:10327: distcheck] Error 1


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

##############################
Test: Build w/ext ELL - Make - FAIL
Desc: Build BlueZ source with '--enable-external-ell' configuration
Output:
profiles/audio/a2dp.c: In function ‘finalize_all’:
profiles/audio/a2dp.c:420:31: error: passing argument 2 of ‘cb->select_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
420 | cb->select_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:420:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:421:6: error: passing argument 3 of ‘cb->select_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
421 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:421:6: note: expected ‘GSList *’ {aka ‘struct _GSList *’} but argument is of type ‘int’
profiles/audio/a2dp.c:421:32: error: passing argument 4 of ‘cb->select_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
421 | error_to_errno(s->err), cb->user_data);
| ~~^~~~~~~~~~~
| |
| void *
profiles/audio/a2dp.c:421:32: note: expected ‘int’ but argument is of type ‘void *’
profiles/audio/a2dp.c:420:4: error: too few arguments to function ‘cb->select_cb’
420 | cb->select_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c:423:32: error: passing argument 2 of ‘cb->suspend_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
423 | cb->suspend_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:423:32: note: expected ‘int’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:424:6: error: passing argument 3 of ‘cb->suspend_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
424 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:424:6: note: expected ‘void *’ but argument is of type ‘int’
profiles/audio/a2dp.c:423:4: error: too many arguments to function ‘cb->suspend_cb’
423 | cb->suspend_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c:426:31: error: passing argument 2 of ‘cb->resume_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
426 | cb->resume_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:426:31: note: expected ‘int’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:427:6: error: passing argument 3 of ‘cb->resume_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
427 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:427:6: note: expected ‘void *’ but argument is of type ‘int’
profiles/audio/a2dp.c:426:4: error: too many arguments to function ‘cb->resume_cb’
426 | cb->resume_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c:429:31: error: passing argument 2 of ‘cb->config_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
429 | cb->config_cb(s->session, s->seps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:429:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:430:6: error: passing argument 3 of ‘cb->config_cb’ makes pointer from integer without a cast [-Werror=int-conversion]
430 | error_to_errno(s->err), cb->user_data);
| ^~~~~~~~~~~~~~~~~~~~~~
| |
| int
profiles/audio/a2dp.c:430:6: note: expected ‘struct avdtp_stream *’ but argument is of type ‘int’
profiles/audio/a2dp.c:430:32: error: passing argument 4 of ‘cb->config_cb’ makes integer from pointer without a cast [-Werror=int-conversion]
430 | error_to_errno(s->err), cb->user_data);
| ~~^~~~~~~~~~~
| |
| void *
profiles/audio/a2dp.c:430:32: note: expected ‘int’ but argument is of type ‘void *’
profiles/audio/a2dp.c:429:4: error: too few arguments to function ‘cb->config_cb’
429 | cb->config_cb(s->session, s->seps,
| ^~
profiles/audio/a2dp.c: At top level:
profiles/audio/a2dp.c:438:13: error: redefinition of ‘finalize_all’
438 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
profiles/audio/a2dp.c:407:13: note: previous definition of ‘finalize_all’ was here
407 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
profiles/audio/a2dp.c: In function ‘finalize_all’:
profiles/audio/a2dp.c:452:31: error: passing argument 2 of ‘cb->select_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
452 | cb->select_cb(s->session, s->seps, s->caps,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:452:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c:461:31: error: passing argument 2 of ‘cb->config_cb’ from incompatible pointer type [-Werror=incompatible-pointer-types]
461 | cb->config_cb(s->session, s->seps, stream,
| ~^~~~~~
| |
| GSList * {aka struct _GSList *}
profiles/audio/a2dp.c:461:31: note: expected ‘struct a2dp_sep *’ but argument is of type ‘GSList *’ {aka ‘struct _GSList *’}
profiles/audio/a2dp.c: In function ‘channel_free’:
profiles/audio/a2dp.c:1608:42: error: passing argument 3 of ‘finalize_setup_errno’ from incompatible pointer type [-Werror=incompatible-pointer-types]
1608 | finalize_setup_errno(setup, -ENOTCONN, finalize_all, NULL);
| ^~~~~~~~~~~~
| |
| void (*)(struct a2dp_setup *)
profiles/audio/a2dp.c:262:18: note: expected ‘GSourceFunc’ {aka ‘int (*)(void *)’} but argument is of type ‘void (*)(struct a2dp_setup *)’
262 | GSourceFunc cb1, ...)
| ~~~~~~~~~~~~^~~
At top level:
profiles/audio/a2dp.c:407:13: error: ‘finalize_all’ defined but not used [-Werror=unused-function]
407 | static void finalize_all(struct a2dp_setup *s)
| ^~~~~~~~~~~~
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8531: profiles/audio/bluetoothd-a2dp.o] Error 1
make: *** [Makefile:4134: all] Error 2




---
Regards,
Linux Bluetooth