* [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only
@ 2025-04-24 14:48 Ludovico de Nittis
2025-04-24 14:48 ` [PATCH BlueZ v3 1/7] src: Add new CablePairing property Ludovico de Nittis
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: Ludovico de Nittis @ 2025-04-24 14:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ludovico de Nittis
This series adds a new "CablePairing" property to allow us to
indentify devices that have been paired using a custom USB cable
cable method and that don't support the canonical bonding with
encryption. With that information, we can dynamically enforce
encryption to drastically reduce the attack surface, compared to just
disabling the "ClassicBondedOnly" property.
The "CablePairing" property is exposed via D-Bus to allow
clients to potentually show this information to end users.
As far as I can tell, starting the listening input server with
BT_IO_SEC_LOW and then bumping it in `hidp_add_connection()` should not
have any negative effect regarding the overall security. However,
please let me know if it turns out not being the case.
Addresses https://github.com/bluez/bluez/issues/1165
Changes in v2:
- Start the listening input server with BT_IO_SEC_LOW only if we
actually have a known sixaxis device
Changes in v3:
- Change the property from being sixaxis specific to a generic
"CablePairing"
- Remove the manual validation of Sixaxis HID report descriptor
because we already replace it with a pre-dermined SDP record
in `sixaxis.c`
Ludovico de Nittis (7):
src: Add new CablePairing property
client: Print CablePairing property
sixaxis: Set CablePairing when pairing a Sixaxis with USB
adapter: Add btd_adapter_has_cable_pairing_devices()
input: Automatically use sec level low when using a cable paired
device
adapter: Set server security level in load_devices()
sixaxis: Set security level when adding a sixaxis device
client/main.c | 1 +
doc/org.bluez.Device.rst | 7 +++++
plugins/sixaxis.c | 8 ++++-
profiles/input/device.c | 9 ++++--
profiles/input/manager.c | 3 +-
profiles/input/server.c | 63 ++++++++++++++++++++++++++++++++++++++--
profiles/input/server.h | 3 +-
src/adapter.c | 24 +++++++++++++++
src/adapter.h | 1 +
src/device.c | 40 +++++++++++++++++++++++++
src/device.h | 2 ++
11 files changed, 153 insertions(+), 8 deletions(-)
--
2.49.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH BlueZ v3 1/7] src: Add new CablePairing property 2025-04-24 14:48 [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only Ludovico de Nittis @ 2025-04-24 14:48 ` Ludovico de Nittis 2025-04-24 17:16 ` Support Sixaxis gamepad with classic bonded only bluez.test.bot 2025-04-24 14:48 ` [PATCH BlueZ v3 2/7] client: Print CablePairing property Ludovico de Nittis ` (5 subsequent siblings) 6 siblings, 1 reply; 12+ messages in thread From: Ludovico de Nittis @ 2025-04-24 14:48 UTC (permalink / raw) To: linux-bluetooth; +Cc: Ludovico de Nittis This adds initial support for a new CablePairing property. The property can be used for devices that are paired using a cable and don't support the expected bonding (with pairing/encryption), for example like the Sixaxis gamepads. --- doc/org.bluez.Device.rst | 7 +++++++ src/device.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/device.h | 2 ++ 3 files changed, 49 insertions(+) diff --git a/doc/org.bluez.Device.rst b/doc/org.bluez.Device.rst index 13328249b..80501eddd 100644 --- a/doc/org.bluez.Device.rst +++ b/doc/org.bluez.Device.rst @@ -279,6 +279,13 @@ boolean LegacyPairing [readonly] Bluetooth 2.1 (or newer) devices that have disabled Extended Inquiry Response support. +boolean CablePairing [readonly] +``````````````````````````````` + + Set to true if the device was cable paired and it doesn't support the + canonical bonding with encryption, e.g. the Sixaxis gamepad. + If true, BlueZ will establish a connection without enforcing encryption. + string Modalias [readonly, optional] ```````````````````````````````````` diff --git a/src/device.c b/src/device.c index b82a905f9..123d44c14 100644 --- a/src/device.c +++ b/src/device.c @@ -239,6 +239,7 @@ struct btd_device { GSList *watches; /* List of disconnect_data */ bool temporary; bool connectable; + bool cable_pairing; unsigned int disconn_timer; unsigned int discov_timer; unsigned int temporary_timer; /* Temporary/disappear timer */ @@ -507,6 +508,9 @@ static gboolean store_device_info_cb(gpointer user_data) g_key_file_set_boolean(key_file, "General", "Blocked", device->blocked); + g_key_file_set_boolean(key_file, "General", "CablePairing", + device->cable_pairing); + if (device->wake_override != WAKE_FLAG_DEFAULT) { g_key_file_set_boolean(key_file, "General", "WakeAllowed", device->wake_override == @@ -908,6 +912,11 @@ bool btd_device_is_trusted(struct btd_device *device) return device->trusted; } +bool device_is_cable_pairing(struct btd_device *device) +{ + return device->cable_pairing; +} + static gboolean dev_property_get_address(const GDBusPropertyTable *property, DBusMessageIter *iter, void *data) { @@ -1153,6 +1162,17 @@ static gboolean dev_property_get_legacy(const GDBusPropertyTable *property, return TRUE; } +static gboolean dev_property_get_cable_pairing(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct btd_device *device = data; + dbus_bool_t val = device->cable_pairing; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val); + + return TRUE; +} + static gboolean dev_property_get_rssi(const GDBusPropertyTable *property, DBusMessageIter *iter, void *data) { @@ -3483,6 +3503,7 @@ static const GDBusPropertyTable device_properties[] = { { "Trusted", "b", dev_property_get_trusted, dev_property_set_trusted }, { "Blocked", "b", dev_property_get_blocked, dev_property_set_blocked }, { "LegacyPairing", "b", dev_property_get_legacy }, + { "CablePairing", "b", dev_property_get_cable_pairing }, { "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi }, { "Connected", "b", dev_property_get_connected }, { "UUIDs", "as", dev_property_get_uuids }, @@ -4062,6 +4083,9 @@ next: if (blocked) device_block(device, FALSE); + device->cable_pairing = g_key_file_get_boolean(key_file, "General", + "CablePairing", NULL); + /* Load device profile list */ uuids = g_key_file_get_string_list(key_file, "General", "Services", NULL, NULL); @@ -6416,6 +6440,22 @@ void device_set_legacy(struct btd_device *device, bool legacy) DEVICE_INTERFACE, "LegacyPairing"); } +void device_set_cable_pairing(struct btd_device *device, bool cable_pairing) +{ + if (!device) + return; + + if (device->cable_pairing == cable_pairing) + return; + + DBG("setting cable pairing %d", cable_pairing); + + device->cable_pairing = cable_pairing; + + g_dbus_emit_property_changed(dbus_conn, device->path, + DEVICE_INTERFACE, "CablePairing"); +} + void device_store_svc_chng_ccc(struct btd_device *device, uint8_t bdaddr_type, uint16_t value) { diff --git a/src/device.h b/src/device.h index 2e4a9771d..a35bb1386 100644 --- a/src/device.h +++ b/src/device.h @@ -94,6 +94,7 @@ bool device_is_connectable(struct btd_device *device); bool device_is_paired(struct btd_device *device, uint8_t bdaddr_type); bool device_is_bonded(struct btd_device *device, uint8_t bdaddr_type); bool btd_device_is_trusted(struct btd_device *device); +bool device_is_cable_pairing(struct btd_device *device); void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type); void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type); void btd_device_set_temporary(struct btd_device *device, bool temporary); @@ -101,6 +102,7 @@ void btd_device_set_trusted(struct btd_device *device, gboolean trusted); void btd_device_set_connectable(struct btd_device *device, bool connectable); void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type); void device_set_legacy(struct btd_device *device, bool legacy); +void device_set_cable_pairing(struct btd_device *device, bool cable_pairing); void device_set_rssi_with_delta(struct btd_device *device, int8_t rssi, int8_t delta_threshold); void device_set_rssi(struct btd_device *device, int8_t rssi); -- 2.49.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* RE: Support Sixaxis gamepad with classic bonded only 2025-04-24 14:48 ` [PATCH BlueZ v3 1/7] src: Add new CablePairing property Ludovico de Nittis @ 2025-04-24 17:16 ` bluez.test.bot 0 siblings, 0 replies; 12+ messages in thread From: bluez.test.bot @ 2025-04-24 17:16 UTC (permalink / raw) To: linux-bluetooth, ludovico.denittis [-- Attachment #1: Type: text/plain, Size: 30550 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=956666 ---Test result--- Test Summary: CheckPatch PENDING 0.23 seconds GitLint PENDING 0.24 seconds BuildEll PASS 20.76 seconds BluezMake FAIL 71.15 seconds MakeCheck FAIL 3042.85 seconds MakeDistcheck PASS 204.38 seconds CheckValgrind FAIL 52.60 seconds CheckSmatch FAIL 182.97 seconds bluezmakeextell FAIL 97.81 seconds IncrementalBuild PENDING 0.28 seconds ScanBuild FAIL 206.72 seconds Details ############################## Test: CheckPatch - PENDING Desc: Run checkpatch.pl script Output: ############################## Test: GitLint - PENDING Desc: Run gitlint Output: ############################## Test: BluezMake - FAIL Desc: Build BlueZ Output: tools/mgmt-tester.c: In function ‘main’: tools/mgmt-tester.c:12907:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without 12907 | int main(int argc, char *argv[]) | ^~~~ profiles/input/server.c: In function ‘get_necessary_sec_level’: profiles/input/server.c:274:2: error: "/*" within comment [-Werror=comment] 274 | /* hidp_add_connection() */ | cc1: all warnings being treated as errors make[1]: *** [Makefile:10380: profiles/input/bluetoothd-server.o] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:4681: all] Error 2 ############################## Test: MakeCheck - FAIL Desc: Run Bluez Make Check Output: unit/test-avdtp.c: In function ‘main’: unit/test-avdtp.c:766:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without 766 | int main(int argc, char *argv[]) | ^~~~ unit/test-avrcp.c: In function ‘main’: unit/test-avrcp.c:989:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without 989 | int main(int argc, char *argv[]) | ^~~~ profiles/input/server.c: In function ‘get_necessary_sec_level’: profiles/input/server.c:274:2: error: "/*" within comment [-Werror=comment] 274 | /* hidp_add_connection() */ | cc1: all warnings being treated as errors make[1]: *** [Makefile:10380: profiles/input/bluetoothd-server.o] Error 1 make: *** [Makefile:12319: check] Error 2 ############################## Test: CheckValgrind - FAIL Desc: Run Bluez Make Check with Valgrind Output: tools/mgmt-tester.c: In function ‘main’: tools/mgmt-tester.c:12907:5: note: variable tracking size limit exceeded with ‘-fvar-tracking-assignments’, retrying without 12907 | int main(int argc, char *argv[]) | ^~~~ profiles/input/server.c: In function ‘get_necessary_sec_level’: profiles/input/server.c:274:2: error: "/*" within comment [-Werror=comment] 274 | /* hidp_add_connection() */ | cc1: all warnings being treated as errors make[1]: *** [Makefile:10380: profiles/input/bluetoothd-server.o] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:12319: check] Error 2 ############################## Test: CheckSmatch - FAIL Desc: Run smatch tool with source Output: src/shared/crypto.c:271:21: warning: Variable length array is used. src/shared/crypto.c:272:23: warning: Variable length array is used. src/shared/gatt-helpers.c:768:31: warning: Variable length array is used. src/shared/gatt-helpers.c:830:31: warning: Variable length array is used. src/shared/gatt-helpers.c:1323:31: warning: Variable length array is used. src/shared/gatt-helpers.c:1354:23: warning: Variable length array is used. src/shared/gatt-server.c:278:25: warning: Variable length array is used. src/shared/gatt-server.c:618:25: warning: Variable length array is used. src/shared/gatt-server.c:716:25: warning: Variable length array is used. src/shared/bap.c:315:25: warning: array of flexible structures src/shared/bap.c: note: in included file: ./src/shared/ascs.h:88:25: warning: array of flexible structures src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h): /usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function' /usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction' /usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction' /usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction' src/shared/crypto.c:271:21: warning: Variable length array is used. src/shared/crypto.c:272:23: warning: Variable length array is used. src/shared/gatt-helpers.c:768:31: warning: Variable length array is used. src/shared/gatt-helpers.c:830:31: warning: Variable length array is used. src/shared/gatt-helpers.c:1323:31: warning: Variable length array is used. src/shared/gatt-helpers.c:1354:23: warning: Variable length array is used. src/shared/gatt-server.c:278:25: warning: Variable length array is used. src/shared/gatt-server.c:618:25: warning: Variable length array is used. src/shared/gatt-server.c:716:25: warning: Variable length array is used. src/shared/bap.c:315:25: warning: array of flexible structures src/shared/bap.c: note: in included file: ./src/shared/ascs.h:88:25: warning: array of flexible structures src/shared/shell.c: note: in included file (through /usr/include/readline/readline.h): /usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function' /usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction' /usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction' /usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction' tools/mesh-cfgtest.c:1453:17: warning: unknown escape sequence: '\%' tools/sco-tester.c: note: in included file: ./lib/bluetooth.h:232:15: warning: array of flexible structures ./lib/bluetooth.h:237:31: warning: array of flexible structures tools/bneptest.c:634:39: warning: unknown escape sequence: '\%' tools/seq2bseq.c:57:26: warning: Variable length array is used. tools/obex-client-tool.c: note: in included file (through /usr/include/readline/readline.h): /usr/include/readline/rltypedefs.h:35:23: warning: non-ANSI function declaration of function 'Function' /usr/include/readline/rltypedefs.h:36:25: warning: non-ANSI function declaration of function 'VFunction' /usr/include/readline/rltypedefs.h:37:27: warning: non-ANSI function declaration of function 'CPFunction' /usr/include/readline/rltypedefs.h:38:29: warning: non-ANSI function declaration of function 'CPPFunction' android/avctp.c:505:34: warning: Variable length array is used. android/avctp.c:556:34: warning: Variable length array is used. unit/test-avrcp.c:373:26: warning: Variable length array is used. unit/test-avrcp.c:398:26: warning: Variable length array is used. unit/test-avrcp.c:414:24: warning: Variable length array is used. android/avrcp-lib.c:1085:34: warning: Variable length array is used. android/avrcp-lib.c:1583:34: warning: Variable length array is used. android/avrcp-lib.c:1612:34: warning: Variable length array is used. android/avrcp-lib.c:1638:34: warning: Variable length array is used. profiles/input/server.c: In function ‘get_necessary_sec_level’: profiles/input/server.c:274:2: error: "/*" within comment [-Werror=comment] 274 | /* hidp_add_connection() */ | cc1: all warnings being treated as errors make[1]: *** [Makefile:10380: profiles/input/bluetoothd-server.o] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:4681: all] Error 2 ############################## Test: bluezmakeextell - FAIL Desc: Build Bluez with External ELL Output: profiles/input/server.c: In function ‘get_necessary_sec_level’: profiles/input/server.c:274:2: error: "/*" within comment [-Werror=comment] 274 | /* hidp_add_connection() */ | cc1: all warnings being treated as errors make[1]: *** [Makefile:10380: profiles/input/bluetoothd-server.o] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:4681: all] Error 2 ############################## Test: IncrementalBuild - PENDING Desc: Incremental build with the patches in the series Output: ############################## Test: ScanBuild - FAIL Desc: Run Scan Build Output: src/shared/gatt-client.c:451:21: warning: Use of memory after it is freed gatt_db_unregister(op->client->db, op->db_id); ^~~~~~~~~~ src/shared/gatt-client.c:696:2: warning: Use of memory after it is freed discovery_op_complete(op, false, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:996:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1102:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1296:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1361:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1636:6: warning: Use of memory after it is freed if (read_db_hash(op)) { ^~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1641:2: warning: Use of memory after it is freed discover_all(op); ^~~~~~~~~~~~~~~~ src/shared/gatt-client.c:2147:6: warning: Use of memory after it is freed if (read_db_hash(op)) { ^~~~~~~~~~~~~~~~ src/shared/gatt-client.c:2155:8: warning: Use of memory after it is freed discovery_op_ref(op), ^~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:3244:2: warning: Use of memory after it is freed complete_write_long_op(req, success, 0, false); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:3266:2: warning: Use of memory after it is freed request_unref(req); ^~~~~~~~~~~~~~~~~~ 12 warnings generated. src/shared/bap.c:1495:8: warning: Use of memory after it is freed bap = bt_bap_ref_safe(bap); ^~~~~~~~~~~~~~~~~~~~ src/shared/bap.c:2245:20: warning: Use of memory after it is freed return queue_find(stream->bap->streams, NULL, stream); ^~~~~~~~~~~~~~~~~~~~ 2 warnings generated. src/shared/gatt-client.c:451:21: warning: Use of memory after it is freed gatt_db_unregister(op->client->db, op->db_id); ^~~~~~~~~~ src/shared/gatt-client.c:696:2: warning: Use of memory after it is freed discovery_op_complete(op, false, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:996:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1102:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1296:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1361:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1636:6: warning: Use of memory after it is freed if (read_db_hash(op)) { ^~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1641:2: warning: Use of memory after it is freed discover_all(op); ^~~~~~~~~~~~~~~~ src/shared/gatt-client.c:2147:6: warning: Use of memory after it is freed if (read_db_hash(op)) { ^~~~~~~~~~~~~~~~ src/shared/gatt-client.c:2155:8: warning: Use of memory after it is freed discovery_op_ref(op), ^~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:3244:2: warning: Use of memory after it is freed complete_write_long_op(req, success, 0, false); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:3266:2: warning: Use of memory after it is freed request_unref(req); ^~~~~~~~~~~~~~~~~~ 12 warnings generated. tools/hciattach.c:817:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n' if ((n = read_hci_event(fd, resp, 10)) < 0) { ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/hciattach.c:865:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n' if ((n = read_hci_event(fd, resp, 4)) < 0) { ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/hciattach.c:887:8: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n' if ((n = read_hci_event(fd, resp, 10)) < 0) { ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/hciattach.c:909:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n' if ((n = read_hci_event(fd, resp, 4)) < 0) { ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/hciattach.c:930:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n' if ((n = read_hci_event(fd, resp, 4)) < 0) { ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/hciattach.c:974:7: warning: Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n' if ((n = read_hci_event(fd, resp, 6)) < 0) { ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6 warnings generated. src/shared/bap.c:1495:8: warning: Use of memory after it is freed bap = bt_bap_ref_safe(bap); ^~~~~~~~~~~~~~~~~~~~ src/shared/bap.c:2245:20: warning: Use of memory after it is freed return queue_find(stream->bap->streams, NULL, stream); ^~~~~~~~~~~~~~~~~~~~ 2 warnings generated. src/oui.c:50:2: warning: Value stored to 'hwdb' is never read hwdb = udev_hwdb_unref(hwdb); ^ ~~~~~~~~~~~~~~~~~~~~~ src/oui.c:53:2: warning: Value stored to 'udev' is never read udev = udev_unref(udev); ^ ~~~~~~~~~~~~~~~~ 2 warnings generated. tools/rfcomm.c:234:3: warning: Value stored to 'i' is never read i = execvp(cmdargv[0], cmdargv); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/rfcomm.c:234:7: warning: Null pointer passed to 1st parameter expecting 'nonnull' i = execvp(cmdargv[0], cmdargv); ^~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/rfcomm.c:354:8: warning: Although the value stored to 'fd' is used in the enclosing expression, the value is never actually read from 'fd' if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/rfcomm.c:497:14: warning: Assigned value is garbage or undefined req.channel = raddr.rc_channel; ^ ~~~~~~~~~~~~~~~~ tools/rfcomm.c:515:8: warning: Although the value stored to 'fd' is used in the enclosing expression, the value is never actually read from 'fd' if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 warnings generated. tools/hcidump.c:180:9: warning: Potential leak of memory pointed to by 'dp' if (fds[i].fd == sock) ^~~ tools/hcidump.c:248:17: warning: Assigned value is garbage or undefined dh->ts_sec = htobl(frm.ts.tv_sec); ^ ~~~~~~~~~~~~~~~~~~~~ tools/hcidump.c:326:9: warning: 1st function call argument is an uninitialized value if (be32toh(dp.flags) & 0x02) { ^~~~~~~~~~~~~~~~~ /usr/include/endian.h:46:22: note: expanded from macro 'be32toh' # define be32toh(x) __bswap_32 (x) ^~~~~~~~~~~~~~ tools/hcidump.c:341:20: warning: 1st function call argument is an uninitialized value frm.data_len = be32toh(dp.len); ^~~~~~~~~~~~~~~ /usr/include/endian.h:46:22: note: expanded from macro 'be32toh' # define be32toh(x) __bswap_32 (x) ^~~~~~~~~~~~~~ tools/hcidump.c:346:14: warning: 1st function call argument is an uninitialized value opcode = be32toh(dp.flags) & 0xffff; ^~~~~~~~~~~~~~~~~ /usr/include/endian.h:46:22: note: expanded from macro 'be32toh' # define be32toh(x) __bswap_32 (x) ^~~~~~~~~~~~~~ tools/hcidump.c:384:17: warning: Assigned value is garbage or undefined frm.data_len = btohs(dh.len); ^ ~~~~~~~~~~~~~ tools/hcidump.c:394:11: warning: Assigned value is garbage or undefined frm.len = frm.data_len; ^ ~~~~~~~~~~~~ tools/hcidump.c:398:9: warning: 1st function call argument is an uninitialized value ts = be64toh(ph.ts); ^~~~~~~~~~~~~~ /usr/include/endian.h:51:22: note: expanded from macro 'be64toh' # define be64toh(x) __bswap_64 (x) ^~~~~~~~~~~~~~ tools/hcidump.c:403:13: warning: 1st function call argument is an uninitialized value frm.in = be32toh(dp.flags) & 0x01; ^~~~~~~~~~~~~~~~~ /usr/include/endian.h:46:22: note: expanded from macro 'be32toh' # define be32toh(x) __bswap_32 (x) ^~~~~~~~~~~~~~ tools/hcidump.c:408:11: warning: Assigned value is garbage or undefined frm.in = dh.in; ^ ~~~~~ tools/hcidump.c:437:7: warning: Null pointer passed to 1st parameter expecting 'nonnull' fd = open(file, open_flags, 0644); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11 warnings generated. tools/ciptool.c:350:7: warning: 5th function call argument is an uninitialized value sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. src/sdp-xml.c:126:10: warning: Assigned value is garbage or undefined buf[1] = data[i + 1]; ^ ~~~~~~~~~~~ src/sdp-xml.c:300:11: warning: Assigned value is garbage or undefined buf[1] = data[i + 1]; ^ ~~~~~~~~~~~ src/sdp-xml.c:338:11: warning: Assigned value is garbage or undefined buf[1] = data[i + 1]; ^ ~~~~~~~~~~~ 3 warnings generated. tools/sdptool.c:941:26: warning: Result of 'malloc' is converted to a pointer of type 'uint32_t', which is incompatible with sizeof operand type 'int' uint32_t *value_int = malloc(sizeof(int)); ~~~~~~~~~~ ^~~~~~ ~~~~~~~~~~~ tools/sdptool.c:980:4: warning: 1st function call argument is an uninitialized value free(allocArray[i]); ^~~~~~~~~~~~~~~~~~~ tools/sdptool.c:3777:2: warning: Potential leak of memory pointed to by 'si.name' return add_service(0, &si); ^~~~~~~~~~~~~~~~~~~~~~~~~~ tools/sdptool.c:4112:4: warning: Potential leak of memory pointed to by 'context.svc' return -1; ^~~~~~~~~ 4 warnings generated. tools/avtest.c:243:5: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:253:5: warning: Value stored to 'len' is never read len = write(sk, buf, 4); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:262:5: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:276:5: warning: Value stored to 'len' is never read len = write(sk, buf, ^ ~~~~~~~~~~~~~~ tools/avtest.c:283:5: warning: Value stored to 'len' is never read len = write(sk, buf, ^ ~~~~~~~~~~~~~~ tools/avtest.c:290:5: warning: Value stored to 'len' is never read len = write(sk, buf, ^ ~~~~~~~~~~~~~~ tools/avtest.c:297:5: warning: Value stored to 'len' is never read len = write(sk, buf, ^ ~~~~~~~~~~~~~~ tools/avtest.c:309:5: warning: Value stored to 'len' is never read len = write(sk, buf, 4); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:313:5: warning: Value stored to 'len' is never read len = write(sk, buf, 2); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:322:5: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:326:5: warning: Value stored to 'len' is never read len = write(sk, buf, 2); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:335:5: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:342:5: warning: Value stored to 'len' is never read len = write(sk, buf, 2); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:364:5: warning: Value stored to 'len' is never read len = write(sk, buf, 4); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:368:5: warning: Value stored to 'len' is never read len = write(sk, buf, 2); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:377:5: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:381:5: warning: Value stored to 'len' is never read len = write(sk, buf, 2); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:394:5: warning: Value stored to 'len' is never read len = write(sk, buf, 4); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:398:5: warning: Value stored to 'len' is never read len = write(sk, buf, 2); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:405:4: warning: Value stored to 'len' is never read len = write(sk, buf, 2); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:415:4: warning: Value stored to 'len' is never read len = write(sk, buf, 2); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:580:3: warning: Value stored to 'len' is never read len = write(sk, buf, 2); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:588:3: warning: Value stored to 'len' is never read len = write(sk, buf, invalid ? 2 : 3); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/avtest.c:602:3: warning: Value stored to 'len' is never read len = write(sk, buf, 4 + media_transport_size); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/avtest.c:615:3: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:625:3: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:637:3: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:652:3: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:664:3: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:673:3: warning: Value stored to 'len' is never read len = write(sk, buf, 3); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:680:3: warning: Value stored to 'len' is never read len = write(sk, buf, 2); ^ ~~~~~~~~~~~~~~~~~ tools/avtest.c:716:2: warning: Value stored to 'len' is never read len = write(sk, buf, AVCTP_HEADER_LENGTH + sizeof(play_pressed)); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 32 warnings generated. tools/btproxy.c:836:15: warning: Null pointer passed to 1st parameter expecting 'nonnull' tcp_port = atoi(optarg); ^~~~~~~~~~~~ tools/btproxy.c:839:8: warning: Null pointer passed to 1st parameter expecting 'nonnull' if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3)) ^~~~~~~~~~~~~~ 2 warnings generated. tools/create-image.c:76:3: warning: Value stored to 'fd' is never read fd = -1; ^ ~~ tools/create-image.c:84:3: warning: Value stored to 'fd' is never read fd = -1; ^ ~~ tools/create-image.c:92:3: warning: Value stored to 'fd' is never read fd = -1; ^ ~~ tools/create-image.c:105:2: warning: Value stored to 'fd' is never read fd = -1; ^ ~~ 4 warnings generated. tools/check-selftest.c:42:3: warning: Value stored to 'ptr' is never read ptr = fgets(result, sizeof(result), fp); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. tools/gatt-service.c:294:2: warning: 2nd function call argument is an uninitialized value chr_write(chr, value, len); ^~~~~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. tools/btgatt-server.c:1212:2: warning: Value stored to 'argv' is never read argv -= optind; ^ ~~~~~~ 1 warning generated. tools/btgatt-client.c:1824:2: warning: Value stored to 'argv' is never read argv += optind; ^ ~~~~~~ 1 warning generated. tools/obex-server-tool.c:133:13: warning: Null pointer passed to 1st parameter expecting 'nonnull' data->fd = open(name, O_WRONLY | O_CREAT | O_NOCTTY, 0600); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tools/obex-server-tool.c:192:13: warning: Null pointer passed to 1st parameter expecting 'nonnull' data->fd = open(name, O_RDONLY | O_NOCTTY, 0); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 warnings generated. tools/btpclientctl.c:402:3: warning: Value stored to 'bit' is never read bit = 0; ^ ~ tools/btpclientctl.c:1655:2: warning: Null pointer passed to 2nd parameter expecting 'nonnull' memcpy(cp->data, ad_data, ad_len); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 warnings generated. src/sdpd-request.c:211:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint16_t' pElem = malloc(sizeof(uint16_t)); ^~~~~~ ~~~~~~~~~~~~~~~~ src/sdpd-request.c:239:13: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'uint32_t' pElem = malloc(sizeof(uint32_t)); ^~~~~~ ~~~~~~~~~~~~~~~~ 2 warnings generated. android/avrcp-lib.c:1968:3: warning: 1st function call argument is an uninitialized value g_free(text[i]); ^~~~~~~~~~~~~~~ 1 warning generated. profiles/audio/avdtp.c:896:25: warning: Use of memory after it is freed session->prio_queue = g_slist_remove(session->prio_queue, req); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ profiles/audio/avdtp.c:903:24: warning: Use of memory after it is freed session->req_queue = g_slist_remove(session->req_queue, req); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 warnings generated. profiles/audio/a2dp.c:371:8: warning: Use of memory after it is freed if (!cb->resume_cb) ^~~~~~~~~~~~~ 1 warning generated. profiles/input/server.c: In function ‘get_necessary_sec_level’: profiles/input/server.c:274:2: error: "/*" within comment [-Werror=comment] 274 | /* hidp_add_connection() */ | cc1: all warnings being treated as errors make[1]: *** [Makefile:10380: profiles/input/bluetoothd-server.o] Error 1 make[1]: *** Waiting for unfinished jobs.... profiles/audio/avrcp.c:1961:2: warning: Value stored to 'operands' is never read operands += sizeof(*pdu); ^ ~~~~~~~~~~~~ 1 warning generated. make: *** [Makefile:4681: all] Error 2 --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH BlueZ v3 2/7] client: Print CablePairing property 2025-04-24 14:48 [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 1/7] src: Add new CablePairing property Ludovico de Nittis @ 2025-04-24 14:48 ` Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 3/7] sixaxis: Set CablePairing when pairing a Sixaxis with USB Ludovico de Nittis ` (4 subsequent siblings) 6 siblings, 0 replies; 12+ messages in thread From: Ludovico de Nittis @ 2025-04-24 14:48 UTC (permalink / raw) To: linux-bluetooth; +Cc: Ludovico de Nittis When using the `info` command, include the new CablePairing value. --- client/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.c b/client/main.c index 6039aa50c..a2d9d88bf 100644 --- a/client/main.c +++ b/client/main.c @@ -1705,6 +1705,7 @@ static void cmd_info(int argc, char *argv[]) print_property(proxy, "Connected"); print_property(proxy, "WakeAllowed"); print_property(proxy, "LegacyPairing"); + print_property(proxy, "CablePairing"); print_uuids(proxy); print_property(proxy, "Modalias"); print_property(proxy, "ManufacturerData"); -- 2.49.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH BlueZ v3 3/7] sixaxis: Set CablePairing when pairing a Sixaxis with USB 2025-04-24 14:48 [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 1/7] src: Add new CablePairing property Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 2/7] client: Print CablePairing property Ludovico de Nittis @ 2025-04-24 14:48 ` Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 4/7] adapter: Add btd_adapter_has_cable_pairing_devices() Ludovico de Nittis ` (3 subsequent siblings) 6 siblings, 0 replies; 12+ messages in thread From: Ludovico de Nittis @ 2025-04-24 14:48 UTC (permalink / raw) To: linux-bluetooth; +Cc: Ludovico de Nittis Sixaxis gamepads don't support encryption. When doing the USB cable pairing, set the CablePairing property to keep the connection to the device unencrypted. --- plugins/sixaxis.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c index 3e69f1dd2..ea160c65d 100644 --- a/plugins/sixaxis.c +++ b/plugins/sixaxis.c @@ -296,10 +296,13 @@ static void agent_auth_cb(DBusError *derr, void *user_data) remove_device = false; btd_device_set_temporary(closure->device, false); - if (closure->type == CABLE_PAIRING_SIXAXIS) + if (closure->type == CABLE_PAIRING_SIXAXIS) { btd_device_set_record(closure->device, HID_UUID, SIXAXIS_HID_SDP_RECORD); + device_set_cable_pairing(closure->device, true); + } + ba2str(&closure->bdaddr, device_addr); ba2str(¢ral_bdaddr, central_addr); ba2str(adapter_bdaddr, adapter_addr); -- 2.49.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH BlueZ v3 4/7] adapter: Add btd_adapter_has_cable_pairing_devices() 2025-04-24 14:48 [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only Ludovico de Nittis ` (2 preceding siblings ...) 2025-04-24 14:48 ` [PATCH BlueZ v3 3/7] sixaxis: Set CablePairing when pairing a Sixaxis with USB Ludovico de Nittis @ 2025-04-24 14:48 ` Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 5/7] input: Automatically use sec level low when using a cable paired device Ludovico de Nittis ` (2 subsequent siblings) 6 siblings, 0 replies; 12+ messages in thread From: Ludovico de Nittis @ 2025-04-24 14:48 UTC (permalink / raw) To: linux-bluetooth; +Cc: Ludovico de Nittis Add a function that can be used to know if any of the known devices have the `CablePaired` property set. --- src/adapter.c | 17 +++++++++++++++++ src/adapter.h | 1 + 2 files changed, 18 insertions(+) diff --git a/src/adapter.c b/src/adapter.c index c21b38095..fd425e6d2 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -412,6 +412,23 @@ uint16_t btd_adapter_get_index(struct btd_adapter *adapter) return adapter->dev_id; } +bool btd_adapter_has_cable_pairing_devices(struct btd_adapter *adapter) +{ + GSList *l; + + if (!adapter) + return false; + + for (l = adapter->devices; l; l = l->next) { + struct btd_device *device = l->data; + + if (device_is_cable_pairing(device)) + return true; + } + + return false; +} + static gboolean process_auth_queue(gpointer user_data); static void dev_class_changed_callback(uint16_t index, uint16_t length, diff --git a/src/adapter.h b/src/adapter.h index 8dfbe762e..6b2bc28f6 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -30,6 +30,7 @@ struct queue; struct btd_adapter *btd_adapter_get_default(void); bool btd_adapter_is_default(struct btd_adapter *adapter); uint16_t btd_adapter_get_index(struct btd_adapter *adapter); +bool btd_adapter_has_cable_pairing_devices(struct btd_adapter *adapter); typedef void (*adapter_cb) (struct btd_adapter *adapter, gpointer user_data); -- 2.49.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH BlueZ v3 5/7] input: Automatically use sec level low when using a cable paired device 2025-04-24 14:48 [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only Ludovico de Nittis ` (3 preceding siblings ...) 2025-04-24 14:48 ` [PATCH BlueZ v3 4/7] adapter: Add btd_adapter_has_cable_pairing_devices() Ludovico de Nittis @ 2025-04-24 14:48 ` Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 6/7] adapter: Set server security level in load_devices() Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 7/7] sixaxis: Set security level when adding a sixaxis device Ludovico de Nittis 6 siblings, 0 replies; 12+ messages in thread From: Ludovico de Nittis @ 2025-04-24 14:48 UTC (permalink / raw) To: linux-bluetooth; +Cc: Ludovico de Nittis BT_IO_SEC_LOW is the only way to allow devices that use cable pairing to establish a connection. This adds the ability to start the listening input server with BT_IO_SEC_LOW to avoid breaking support for these devices, and then, in `hidp_add_connection()`, we check if either `classic_bonded_only` was disabled or if this device has `CablePairing`. If neither are true, we bump the security back to BT_IO_SEC_MEDIUM, i.e. enforcing encryption. This allows supporting these devices without having to change the classic bonded only option. This doesn't cover the case where a device with `CablePairing` gets loaded from storage. That case will be handled with a followup commit. --- profiles/input/device.c | 9 ++++-- profiles/input/manager.c | 3 +- profiles/input/server.c | 63 ++++++++++++++++++++++++++++++++++++++-- profiles/input/server.h | 3 +- 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/profiles/input/device.c b/profiles/input/device.c index 3627573e7..806177a0b 100644 --- a/profiles/input/device.c +++ b/profiles/input/device.c @@ -1065,6 +1065,7 @@ static gboolean encrypt_notify(GIOChannel *io, GIOCondition condition, static int hidp_add_connection(struct input_device *idev) { struct hidp_connadd_req *req; + bool cable_pairing; GError *gerr = NULL; int err; @@ -1088,8 +1089,10 @@ static int hidp_add_connection(struct input_device *idev) if (device_name_known(idev->device)) device_get_name(idev->device, req->name, sizeof(req->name)); + cable_pairing = device_is_cable_pairing(idev->device); + /* Make sure the device is bonded if required */ - if (classic_bonded_only && !input_device_bonded(idev)) { + if (!cable_pairing && classic_bonded_only && !input_device_bonded(idev)) { error("Rejected connection from !bonded device %s", idev->path); goto cleanup; } @@ -1098,7 +1101,9 @@ static int hidp_add_connection(struct input_device *idev) /* Some platforms may choose to require encryption for all devices */ /* Note that this only matters for pre 2.1 devices as otherwise the */ /* device is encrypted by default by the lower layers */ - if (classic_bonded_only || idev->type == BT_UHID_KEYBOARD) { + /* Don't enforce encryption for cable paired devices because they */ + /* don't support it */ + if (!cable_pairing && (classic_bonded_only || idev->type == BT_UHID_KEYBOARD)) { if (!bt_io_set(idev->intr_io, &gerr, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, BT_IO_OPT_INVALID)) { diff --git a/profiles/input/manager.c b/profiles/input/manager.c index d1accc24f..95ca0a7ee 100644 --- a/profiles/input/manager.c +++ b/profiles/input/manager.c @@ -33,7 +33,8 @@ static int hid_server_probe(struct btd_profile *p, struct btd_adapter *adapter) { - return server_start(btd_adapter_get_address(adapter)); + return server_start(btd_adapter_get_address(adapter), + btd_adapter_has_cable_pairing_devices(adapter)); } static void hid_server_remove(struct btd_profile *p, diff --git a/profiles/input/server.c b/profiles/input/server.c index 79cf08a66..e1160d668 100644 --- a/profiles/input/server.c +++ b/profiles/input/server.c @@ -266,12 +266,23 @@ drop: g_io_channel_shutdown(chan, TRUE, NULL); } -int server_start(const bdaddr_t *src) +static BtIOSecLevel get_necessary_sec_level(bool device_cable_pairing) +{ + /* Use lower security to allow the cable paired devices to connect. */ + /* Unless classic bonded only mode is disabled, the security level */ + /* will be bumped again for non cable paired devices in + /* hidp_add_connection() */ + if (device_cable_pairing) + return BT_IO_SEC_LOW; + + return input_get_classic_bonded_only() ? BT_IO_SEC_MEDIUM : BT_IO_SEC_LOW; +} + +int server_start(const bdaddr_t *src, bool device_sixaxis_cable_pairing) { struct input_server *server; GError *err = NULL; - BtIOSecLevel sec_level = input_get_classic_bonded_only() ? - BT_IO_SEC_MEDIUM : BT_IO_SEC_LOW; + const BtIOSecLevel sec_level = get_necessary_sec_level(device_sixaxis_cable_pairing); server = g_new0(struct input_server, 1); bacpy(&server->src, src); @@ -308,6 +319,52 @@ int server_start(const bdaddr_t *src) return 0; } +int server_set_cable_pairing(const bdaddr_t *src, bool device_cable_pairing) +{ + struct input_server *server; + GSList *l; + BtIOSecLevel sec_level; + const BtIOSecLevel new_sec_level = get_necessary_sec_level(device_cable_pairing); + GError *err = NULL; + + l = g_slist_find_custom(servers, src, server_cmp); + if (!l) + return -1; + + server = l->data; + + bt_io_get(server->ctrl, &err, BT_IO_OPT_SEC_LEVEL, &sec_level, + BT_IO_OPT_INVALID); + if (err) { + error("%s", err->message); + g_error_free(err); + return -1; + } + + if (sec_level == new_sec_level) { + DBG("The listening input server is already using the expected security level"); + return -1; + } + + DBG("Applying the new security level to the listening input server"); + + if (!bt_io_set(server->ctrl, &err, BT_IO_OPT_SEC_LEVEL, new_sec_level, + BT_IO_OPT_INVALID)) { + error("bt_io_set(OPT_SEC_LEVEL): %s", err->message); + g_error_free(err); + return -1; + } + + if (!bt_io_set(server->intr, &err, BT_IO_OPT_SEC_LEVEL, new_sec_level, + BT_IO_OPT_INVALID)) { + error("bt_io_set(OPT_SEC_LEVEL): %s", err->message); + g_error_free(err); + return -1; + } + + return 0; +} + void server_stop(const bdaddr_t *src) { struct input_server *server; diff --git a/profiles/input/server.h b/profiles/input/server.h index 50f4b6135..4ad82c10e 100644 --- a/profiles/input/server.h +++ b/profiles/input/server.h @@ -8,5 +8,6 @@ * */ -int server_start(const bdaddr_t *src); +int server_start(const bdaddr_t *src, bool device_cable_pairing); +int server_set_cable_pairing(const bdaddr_t *src, bool device_cable_pairing); void server_stop(const bdaddr_t *src); -- 2.49.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH BlueZ v3 6/7] adapter: Set server security level in load_devices() 2025-04-24 14:48 [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only Ludovico de Nittis ` (4 preceding siblings ...) 2025-04-24 14:48 ` [PATCH BlueZ v3 5/7] input: Automatically use sec level low when using a cable paired device Ludovico de Nittis @ 2025-04-24 14:48 ` Ludovico de Nittis 2025-04-24 14:57 ` Luiz Augusto von Dentz 2025-04-24 14:48 ` [PATCH BlueZ v3 7/7] sixaxis: Set security level when adding a sixaxis device Ludovico de Nittis 6 siblings, 1 reply; 12+ messages in thread From: Ludovico de Nittis @ 2025-04-24 14:48 UTC (permalink / raw) To: linux-bluetooth; +Cc: Ludovico de Nittis After loading known devices from storage, change the security level if we have a device with `CablePairing`. This will allow it to successfully establish a connection. --- src/adapter.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/adapter.c b/src/adapter.c index fd425e6d2..8d875013c 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -68,6 +68,7 @@ #include "adv_monitor.h" #include "eir.h" #include "battery.h" +#include "profiles/input/server.h" #define MODE_OFF 0x00 #define MODE_CONNECTABLE 0x01 @@ -5090,6 +5091,12 @@ free: g_key_file_free(key_file); } + if (btd_adapter_has_cable_pairing_devices(adapter)) { + DBG("There is at least one known cable paired device, setting the " + "listening input server security level accordingly"); + server_set_cable_pairing(&adapter->bdaddr, true); + } + closedir(dir); load_link_keys(adapter, keys, btd_opts.debug_keys); -- 2.49.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH BlueZ v3 6/7] adapter: Set server security level in load_devices() 2025-04-24 14:48 ` [PATCH BlueZ v3 6/7] adapter: Set server security level in load_devices() Ludovico de Nittis @ 2025-04-24 14:57 ` Luiz Augusto von Dentz 2025-04-24 15:10 ` Ludovico de Nittis 0 siblings, 1 reply; 12+ messages in thread From: Luiz Augusto von Dentz @ 2025-04-24 14:57 UTC (permalink / raw) To: Ludovico de Nittis; +Cc: linux-bluetooth Hi Ludovico, On Thu, Apr 24, 2025 at 10:50 AM Ludovico de Nittis <ludovico.denittis@collabora.com> wrote: > > After loading known devices from storage, change the security level if > we have a device with `CablePairing`. > This will allow it to successfully establish a connection. > --- > src/adapter.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/src/adapter.c b/src/adapter.c > index fd425e6d2..8d875013c 100644 > --- a/src/adapter.c > +++ b/src/adapter.c > @@ -68,6 +68,7 @@ > #include "adv_monitor.h" > #include "eir.h" > #include "battery.h" > +#include "profiles/input/server.h" > > #define MODE_OFF 0x00 > #define MODE_CONNECTABLE 0x01 > @@ -5090,6 +5091,12 @@ free: > g_key_file_free(key_file); > } > > + if (btd_adapter_has_cable_pairing_devices(adapter)) { > + DBG("There is at least one known cable paired device, setting the " > + "listening input server security level accordingly"); > + server_set_cable_pairing(&adapter->bdaddr, true); > + } This creates a dependency on the input which is a plugin that can be excluded/not loaded at runtime, so we can't really do this at daemon core. > closedir(dir); > > load_link_keys(adapter, keys, btd_opts.debug_keys); > -- > 2.49.0 > > -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH BlueZ v3 6/7] adapter: Set server security level in load_devices() 2025-04-24 14:57 ` Luiz Augusto von Dentz @ 2025-04-24 15:10 ` Ludovico de Nittis 2025-04-24 15:20 ` Luiz Augusto von Dentz 0 siblings, 1 reply; 12+ messages in thread From: Ludovico de Nittis @ 2025-04-24 15:10 UTC (permalink / raw) To: Luiz Augusto von Dentz; +Cc: linux-bluetooth Hi Luiz, On 4/24/25 4:57 PM, Luiz Augusto von Dentz wrote: > Hi Ludovico, > > On Thu, Apr 24, 2025 at 10:50 AM Ludovico de Nittis > <ludovico.denittis@collabora.com> wrote: >> After loading known devices from storage, change the security level if >> we have a device with `CablePairing`. >> This will allow it to successfully establish a connection. >> --- >> src/adapter.c | 7 +++++++ >> 1 file changed, 7 insertions(+) >> >> diff --git a/src/adapter.c b/src/adapter.c >> index fd425e6d2..8d875013c 100644 >> --- a/src/adapter.c >> +++ b/src/adapter.c >> @@ -68,6 +68,7 @@ >> #include "adv_monitor.h" >> #include "eir.h" >> #include "battery.h" >> +#include "profiles/input/server.h" >> >> #define MODE_OFF 0x00 >> #define MODE_CONNECTABLE 0x01 >> @@ -5090,6 +5091,12 @@ free: >> g_key_file_free(key_file); >> } >> >> + if (btd_adapter_has_cable_pairing_devices(adapter)) { >> + DBG("There is at least one known cable paired device, setting the " >> + "listening input server security level accordingly"); >> + server_set_cable_pairing(&adapter->bdaddr, true); >> + } > This creates a dependency on the input which is a plugin that can be > excluded/not loaded at runtime, so we can't really do this at daemon > core. Do you have any suggestions on how to shuffle this around to avoid calling `server_set_cable_pairing()` directly from `adapter.c`? Because in theory that should still happen after we ensured we loaded all devices from storage. >> closedir(dir); >> >> load_link_keys(adapter, keys, btd_opts.debug_keys); >> -- >> 2.49.0 >> >> > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH BlueZ v3 6/7] adapter: Set server security level in load_devices() 2025-04-24 15:10 ` Ludovico de Nittis @ 2025-04-24 15:20 ` Luiz Augusto von Dentz 0 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2025-04-24 15:20 UTC (permalink / raw) To: Ludovico de Nittis; +Cc: linux-bluetooth Hi Ludovico, On Thu, Apr 24, 2025 at 11:10 AM Ludovico de Nittis <ludovico.denittis@collabora.com> wrote: > > Hi Luiz, > > On 4/24/25 4:57 PM, Luiz Augusto von Dentz wrote: > > Hi Ludovico, > > > > On Thu, Apr 24, 2025 at 10:50 AM Ludovico de Nittis > > <ludovico.denittis@collabora.com> wrote: > >> After loading known devices from storage, change the security level if > >> we have a device with `CablePairing`. > >> This will allow it to successfully establish a connection. > >> --- > >> src/adapter.c | 7 +++++++ > >> 1 file changed, 7 insertions(+) > >> > >> diff --git a/src/adapter.c b/src/adapter.c > >> index fd425e6d2..8d875013c 100644 > >> --- a/src/adapter.c > >> +++ b/src/adapter.c > >> @@ -68,6 +68,7 @@ > >> #include "adv_monitor.h" > >> #include "eir.h" > >> #include "battery.h" > >> +#include "profiles/input/server.h" > >> > >> #define MODE_OFF 0x00 > >> #define MODE_CONNECTABLE 0x01 > >> @@ -5090,6 +5091,12 @@ free: > >> g_key_file_free(key_file); > >> } > >> > >> + if (btd_adapter_has_cable_pairing_devices(adapter)) { > >> + DBG("There is at least one known cable paired device, setting the " > >> + "listening input server security level accordingly"); > >> + server_set_cable_pairing(&adapter->bdaddr, true); > >> + } > > This creates a dependency on the input which is a plugin that can be > > excluded/not loaded at runtime, so we can't really do this at daemon > > core. > > Do you have any suggestions on how to shuffle this around to avoid calling > `server_set_cable_pairing()` directly from `adapter.c`? Because in > theory that > should still happen after we ensured we loaded all devices from storage. We should probably evaluate this on probe, if the device has been marked with cable pairing flag then it should call server_set_cable_pairing, if we cannot evaluate it at that point then we need some callback mechanism to notify the plugin when the cable pairing property changes. > >> closedir(dir); > >> > >> load_link_keys(adapter, keys, btd_opts.debug_keys); > >> -- > >> 2.49.0 > >> > >> > > > -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH BlueZ v3 7/7] sixaxis: Set security level when adding a sixaxis device 2025-04-24 14:48 [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only Ludovico de Nittis ` (5 preceding siblings ...) 2025-04-24 14:48 ` [PATCH BlueZ v3 6/7] adapter: Set server security level in load_devices() Ludovico de Nittis @ 2025-04-24 14:48 ` Ludovico de Nittis 6 siblings, 0 replies; 12+ messages in thread From: Ludovico de Nittis @ 2025-04-24 14:48 UTC (permalink / raw) To: linux-bluetooth; +Cc: Ludovico de Nittis When doing the cable pairing for a sixaxis, we may need to change the listening input server security level. This is because sixaxis gamepads can only work with the level BT_IO_SEC_LOW. --- plugins/sixaxis.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c index ea160c65d..1fab8ae59 100644 --- a/plugins/sixaxis.c +++ b/plugins/sixaxis.c @@ -36,6 +36,7 @@ #include "src/plugin.h" #include "src/log.h" #include "src/shared/util.h" +#include "profiles/input/server.h" #include "profiles/input/sixaxis.h" struct authentication_closure { @@ -301,6 +302,8 @@ static void agent_auth_cb(DBusError *derr, void *user_data) SIXAXIS_HID_SDP_RECORD); device_set_cable_pairing(closure->device, true); + + server_set_cable_pairing(adapter_bdaddr, true); } ba2str(&closure->bdaddr, device_addr); -- 2.49.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-04-24 17:16 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-04-24 14:48 [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 1/7] src: Add new CablePairing property Ludovico de Nittis 2025-04-24 17:16 ` Support Sixaxis gamepad with classic bonded only bluez.test.bot 2025-04-24 14:48 ` [PATCH BlueZ v3 2/7] client: Print CablePairing property Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 3/7] sixaxis: Set CablePairing when pairing a Sixaxis with USB Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 4/7] adapter: Add btd_adapter_has_cable_pairing_devices() Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 5/7] input: Automatically use sec level low when using a cable paired device Ludovico de Nittis 2025-04-24 14:48 ` [PATCH BlueZ v3 6/7] adapter: Set server security level in load_devices() Ludovico de Nittis 2025-04-24 14:57 ` Luiz Augusto von Dentz 2025-04-24 15:10 ` Ludovico de Nittis 2025-04-24 15:20 ` Luiz Augusto von Dentz 2025-04-24 14:48 ` [PATCH BlueZ v3 7/7] sixaxis: Set security level when adding a sixaxis device Ludovico de Nittis
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox