* [PATCH BlueZ v2 2/4] profile: Check if bearer is enabled on registration
2026-06-09 18:53 [PATCH BlueZ v2 1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop Luiz Augusto von Dentz
@ 2026-06-09 18:53 ` Luiz Augusto von Dentz
2026-06-09 18:53 ` [PATCH BlueZ v2 3/4] plugins: Check btd_profile_register return value Luiz Augusto von Dentz
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2026-06-09 18:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
btd_profile_register now verifies that the profile's bearer type is
compatible with btd_opts.mode before registering. If the required bearer
is not enabled (e.g. LE-only profile when mode is BR/EDR, or BR/EDR-only
profile when mode is LE), registration is rejected with -ENOTSUP.
---
src/profile.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/profile.c b/src/profile.c
index 65df0f7a0969..97fffe9b4d5c 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -36,6 +36,7 @@
#include "dbus-common.h"
#include "sdp-client.h"
#include "sdp-xml.h"
+#include "btd.h"
#include "adapter.h"
#include "device.h"
#include "profile.h"
@@ -802,6 +803,14 @@ struct btd_profile *btd_profile_find_remote_uuid(const char *uuid)
int btd_profile_register(struct btd_profile *profile)
{
+ if ((profile->bearer == BTD_PROFILE_BEARER_LE &&
+ btd_opts.mode == BT_MODE_BREDR) ||
+ (profile->bearer == BTD_PROFILE_BEARER_BREDR &&
+ btd_opts.mode == BT_MODE_LE)) {
+ DBG("Bearer not enabled");
+ return -ENOTSUP;
+ }
+
if (profile->experimental && !(g_dbus_get_flags() &
G_DBUS_FLAG_ENABLE_EXPERIMENTAL)) {
DBG("D-Bus experimental not enabled");
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH BlueZ v2 3/4] plugins: Check btd_profile_register return value
2026-06-09 18:53 [PATCH BlueZ v2 1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop Luiz Augusto von Dentz
2026-06-09 18:53 ` [PATCH BlueZ v2 2/4] profile: Check if bearer is enabled on registration Luiz Augusto von Dentz
@ 2026-06-09 18:53 ` Luiz Augusto von Dentz
2026-06-09 18:53 ` [PATCH BlueZ v2 4/4] bearer: Check btd_opts.mode on btd_bearer_new Luiz Augusto von Dentz
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2026-06-09 18:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Ensure all plugin init functions check the return value of
btd_profile_register. If registration fails (e.g. bearer not enabled),
the plugin init propagates the error instead of continuing with an
unregistered profile.
---
profiles/audio/a2dp.c | 14 ++++++++++++--
profiles/audio/avrcp.c | 13 +++++++++++--
profiles/audio/hfp-hf.c | 4 +---
profiles/audio/micp.c | 7 ++++++-
profiles/input/manager.c | 4 +---
profiles/network/manager.c | 5 ++++-
src/gatt-database.c | 4 +++-
7 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index c7e0fc75c09e..a5e002784c02 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -3798,9 +3798,19 @@ static struct btd_adapter_driver media_driver = {
static int a2dp_init(void)
{
+ int err;
+
btd_register_adapter_driver(&media_driver);
- btd_profile_register(&a2dp_source_profile);
- btd_profile_register(&a2dp_sink_profile);
+
+ err = btd_profile_register(&a2dp_source_profile);
+ if (err)
+ return err;
+
+ err = btd_profile_register(&a2dp_sink_profile);
+ if (err) {
+ btd_profile_unregister(&a2dp_source_profile);
+ return err;
+ }
return 0;
}
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index b6823753fe68..f63acd47091a 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -4987,8 +4987,17 @@ static struct btd_profile avrcp_controller_profile = {
static int avrcp_init(void)
{
- btd_profile_register(&avrcp_controller_profile);
- btd_profile_register(&avrcp_target_profile);
+ int err;
+
+ err = btd_profile_register(&avrcp_controller_profile);
+ if (err)
+ return err;
+
+ err = btd_profile_register(&avrcp_target_profile);
+ if (err) {
+ btd_profile_unregister(&avrcp_controller_profile);
+ return err;
+ }
populate_default_features();
diff --git a/profiles/audio/hfp-hf.c b/profiles/audio/hfp-hf.c
index c91b16426898..8de2d7a62d68 100644
--- a/profiles/audio/hfp-hf.c
+++ b/profiles/audio/hfp-hf.c
@@ -507,9 +507,7 @@ static struct btd_profile hfp_hf_profile = {
static int hfp_init(void)
{
- btd_profile_register(&hfp_hf_profile);
-
- return 0;
+ return btd_profile_register(&hfp_hf_profile);
}
static void hfp_exit(void)
diff --git a/profiles/audio/micp.c b/profiles/audio/micp.c
index 475f32daf75c..3d39ef5e147f 100644
--- a/profiles/audio/micp.c
+++ b/profiles/audio/micp.c
@@ -318,12 +318,17 @@ static unsigned int micp_id;
static int micp_init(void)
{
+ int err;
+
if (!(g_dbus_get_flags() & G_DBUS_FLAG_ENABLE_EXPERIMENTAL)) {
DBG("D-Bus experimental not enabled");
return -ENOTSUP;
}
- btd_profile_register(&micp_profile);
+ err = btd_profile_register(&micp_profile);
+ if (err)
+ return err;
+
micp_id = bt_micp_register(micp_attached, micp_detached, NULL);
return 0;
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index 0fcd6728c2fc..1fd82d82f500 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -118,12 +118,10 @@ static int input_init(void)
}
- btd_profile_register(&input_profile);
-
if (config)
g_key_file_free(config);
- return 0;
+ return btd_profile_register(&input_profile);
}
static void input_exit(void)
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index 693547d45fbc..a5f28a99ebfd 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -180,7 +180,10 @@ static int network_init(void)
if (server_init(conf_security) < 0)
return -1;
- btd_profile_register(&panu_profile);
+ err = btd_profile_register(&panu_profile);
+ if (err)
+ return err;
+
btd_profile_register(&gn_profile);
btd_profile_register(&nap_profile);
diff --git a/src/gatt-database.c b/src/gatt-database.c
index 680a52952b16..30e25b6f41ca 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -3624,7 +3624,9 @@ static void add_profile(void *data, void *user_data)
{
struct btd_adapter *adapter = user_data;
- btd_profile_register(data);
+ if (btd_profile_register(data))
+ return;
+
adapter_add_profile(adapter, data);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH BlueZ v2 4/4] bearer: Check btd_opts.mode on btd_bearer_new
2026-06-09 18:53 [PATCH BlueZ v2 1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop Luiz Augusto von Dentz
2026-06-09 18:53 ` [PATCH BlueZ v2 2/4] profile: Check if bearer is enabled on registration Luiz Augusto von Dentz
2026-06-09 18:53 ` [PATCH BlueZ v2 3/4] plugins: Check btd_profile_register return value Luiz Augusto von Dentz
@ 2026-06-09 18:53 ` Luiz Augusto von Dentz
2026-06-09 21:31 ` [BlueZ,v2,1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop bluez.test.bot
2026-06-10 18:30 ` [PATCH BlueZ v2 1/4] " patchwork-bot+bluetooth
4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2026-06-09 18:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Only create the bearer interface if the corresponding transport is
enabled. Return NULL if BREDR bearer is requested in LE-only mode or
LE bearer in BREDR-only mode, so the D-Bus interface is never
registered for unsupported bearers.
---
src/bearer.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/bearer.c b/src/bearer.c
index 02267c711431..ac3a22030770 100644
--- a/src/bearer.c
+++ b/src/bearer.c
@@ -34,6 +34,7 @@
#include "log.h"
#include "error.h"
+#include "btd.h"
#include "adapter.h"
#include "device.h"
#include "profile.h"
@@ -278,6 +279,19 @@ struct btd_bearer *btd_bearer_new(struct btd_device *device, uint8_t type)
{
struct btd_bearer *bearer;
+ switch (btd_opts.mode) {
+ case BT_MODE_LE:
+ if (type == BDADDR_BREDR)
+ return NULL;
+ break;
+ case BT_MODE_BREDR:
+ if (type != BDADDR_BREDR)
+ return NULL;
+ break;
+ case BT_MODE_DUAL:
+ break;
+ }
+
bearer = new0(struct btd_bearer, 1);
bearer->device = device;
bearer->type = type;
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* RE: [BlueZ,v2,1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop
2026-06-09 18:53 [PATCH BlueZ v2 1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop Luiz Augusto von Dentz
` (2 preceding siblings ...)
2026-06-09 18:53 ` [PATCH BlueZ v2 4/4] bearer: Check btd_opts.mode on btd_bearer_new Luiz Augusto von Dentz
@ 2026-06-09 21:31 ` bluez.test.bot
2026-06-10 18:30 ` [PATCH BlueZ v2 1/4] " patchwork-bot+bluetooth
4 siblings, 0 replies; 6+ messages in thread
From: bluez.test.bot @ 2026-06-09 21:31 UTC (permalink / raw)
To: linux-bluetooth, luiz.dentz
[-- Attachment #1: Type: text/plain, Size: 1437 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=1108786
---Test result---
Test Summary:
CheckPatch PASS 1.22 seconds
GitLint PASS 0.78 seconds
BuildEll PASS 20.04 seconds
BluezMake PASS 656.72 seconds
MakeCheck PASS 18.90 seconds
MakeDistcheck PASS 249.96 seconds
CheckValgrind PASS 295.94 seconds
CheckSmatch PASS 350.89 seconds
bluezmakeextell PASS 181.16 seconds
IncrementalBuild PASS 673.06 seconds
ScanBuild WARNING 1036.74 seconds
Details
##############################
Test: ScanBuild - WARNING
Desc: Run Scan Build
Output:
1 warning generated.
tools/btgatt-client.c:1822:2: warning: Value stored to 'argv' is never read
tools/check-selftest.c:42:3: warning: Value stored to 'ptr' is never read
argv += optind;
ptr = fgets(result, sizeof(result), fp);
^ ~~~~~~
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
https://github.com/bluez/bluez/pull/2206
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH BlueZ v2 1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop
2026-06-09 18:53 [PATCH BlueZ v2 1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop Luiz Augusto von Dentz
` (3 preceding siblings ...)
2026-06-09 21:31 ` [BlueZ,v2,1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop bluez.test.bot
@ 2026-06-10 18:30 ` patchwork-bot+bluetooth
4 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+bluetooth @ 2026-06-10 18:30 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
Hello:
This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Tue, 9 Jun 2026 14:53:10 -0400 you wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> When accept() returns EOPNOTSUPP on an L2CAP SEQPACKET server socket
> (e.g. AVCTP browsing channel, PSM 0x1b), the error is permanent and
> retrying will never succeed. Previously, only EBADFD was treated as
> fatal, causing server_cb to return TRUE for EOPNOTSUPP. Since the fd
> remains readable, this creates an infinite busy loop that hangs
> bluetoothd.
>
> [...]
Here is the summary with links:
- [BlueZ,v2,1/4] btio: Handle EOPNOTSUPP from accept() to prevent busy loop
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=8c580d30d265
- [BlueZ,v2,2/4] profile: Check if bearer is enabled on registration
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=abf0911e25ef
- [BlueZ,v2,3/4] plugins: Check btd_profile_register return value
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=7b5895d80635
- [BlueZ,v2,4/4] bearer: Check btd_opts.mode on btd_bearer_new
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=8c821a150b8f
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 6+ messages in thread