Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ v2] adapter/advertising: fix mgmt endian bug
@ 2026-09-03  9:10 Nicolas Thibert
  2026-09-03 10:11 ` Bastien Nocera
  2026-09-03 11:59 ` [BlueZ,v2] " bluez.test.bot
  0 siblings, 2 replies; 3+ messages in thread
From: Nicolas Thibert @ 2026-09-03  9:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Nicolas Thibert

Several places in adapter.c and advertising.c write a native-endian
value directly into a __le16/__le32 field of an mgmt command struct,
skipping the cpu_to_le16()/cpu_to_le32() conversion used everywhere
else in this codebase for the same purpose. This is a no-op on
little-endian hosts (where cpu_to_le16()/cpu_to_le32() are themselves
no-ops), which is why it has gone unnoticed, but corrupts the value on
big-endian hosts.

Confirmed live on MIPS big-endian (OpenWrt/ath79): set_blocked_keys()
sends key_count=2 (2 blocked keys), which the kernel's
__le16_to_cpu() correctly interprets as 512 (0x0002 byte-swapped is
0x0200) since the wire bytes were never actually swapped to little-
endian on the way out -- producing "expected 8706 bytes, got 36
bytes" / "Failed to set blocked keys: Invalid Parameters" errors in
dmesg/bluetoothd logs.

add_advertising()'s cp->duration and refresh_extended_adv()'s
cp.duration/cp.min_interval/cp.max_interval have the identical bug. It
is inert with bluetoothctl's default (0) duration/interval values (0
byte-swapped is still 0), but A/B tested live (patch removed vs.
applied, bluetoothctl's advertise submenu "interval 100 100" set
explicitly) confirms this is not just a theoretical correctness fix:
with the bug present, the device stops being discoverable by a real
BLE scanner the moment a non-default interval is requested, and
becomes discoverable again immediately once patched. Any application
that sets an explicit advertising interval or duration hits this.

v2: use cpu_to_le16()/cpu_to_le32() instead of htobs()/htobl(), as
requested by Luiz. Retested live on the same MIPS big-endian board
(blocked keys + explicit advertising interval): behaves identically
to the v1 fix, no regressions.
---
 src/adapter.c     | 5 +++--
 src/advertising.c | 8 ++++----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 7390ceeee..edbdb53b5 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -10219,10 +10219,11 @@ static bool set_blocked_keys(struct btd_adapter *adapter)
 					sizeof(blocked_keys)] = { 0 };
 	struct mgmt_cp_set_blocked_keys *cp =
 				(struct mgmt_cp_set_blocked_keys *)buffer;
+	const uint16_t key_count = ARRAY_SIZE(blocked_keys);
 	int i;
 
-	cp->key_count = ARRAY_SIZE(blocked_keys);
-	for (i = 0; i < cp->key_count; ++i) {
+	cp->key_count = cpu_to_le16(key_count);
+	for (i = 0; i < key_count; ++i) {
 		cp->keys[i].type = blocked_keys[i].type;
 		memcpy(cp->keys[i].val, blocked_keys[i].val,
 						sizeof(cp->keys[i].val));
diff --git a/src/advertising.c b/src/advertising.c
index 1ed09c902..3f70fb4e9 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -1042,7 +1042,7 @@ static int refresh_legacy_adv(struct btd_adv_client *client,
 
 	cp->flags = htobl(flags);
 	cp->instance = client->instance;
-	cp->duration = client->duration;
+	cp->duration = cpu_to_le16(client->duration);
 	cp->adv_data_len = adv_data_len;
 	cp->scan_rsp_len = scan_rsp_len;
 	memcpy(cp->data, adv_data, adv_data_len);
@@ -1093,13 +1093,13 @@ static int refresh_extended_adv(struct btd_adv_client *client,
 	 */
 
 	if (client->duration) {
-		cp.duration = client->duration;
+		cp.duration = cpu_to_le16(client->duration);
 		flags |= MGMT_ADV_PARAM_DURATION;
 	}
 
 	if (client->min_interval && client->max_interval) {
-		cp.min_interval = client->min_interval;
-		cp.max_interval = client->max_interval;
+		cp.min_interval = cpu_to_le32(client->min_interval);
+		cp.max_interval = cpu_to_le32(client->max_interval);
 		flags |= MGMT_ADV_PARAM_INTERVALS;
 	}
 
-- 
2.34.1


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

end of thread, other threads:[~2026-09-03 11:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-03  9:10 [PATCH BlueZ v2] adapter/advertising: fix mgmt endian bug Nicolas Thibert
2026-09-03 10:11 ` Bastien Nocera
2026-09-03 11:59 ` [BlueZ,v2] " bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox