Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: 6lowpan: Defer peer channel release until RCU cleanup
From: Zhang Cen @ 2026-05-09 17:37 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: linux-bluetooth, linux-kernel, zerocling0077, Zhang Cen

A 6LoWPAN peer stores the protocol-owned L2CAP channel reference in
peer->chan. chan_close_cb() removes the peer from the RCU list, but it
also drops that reference immediately. The peer object can still be seen
by in-flight RCU readers, and some paths keep using peer->chan after the
lookup has finished.

That lets transmit and disconnect paths dereference, lock, or send
through a channel whose last reference was released by the close path.

Defer the peer-owned l2cap_chan_put() until the peer RCU callback so a
peer that remains observable through RCU still carries a live channel
reference. Then take temporary channel references in the unicast,
multicast, and explicit disconnect paths before they keep using the
channel after the lookup window closes.

If the reader reaches step 3 after teardown reaches step 4, it can hit a
freed l2cap_chan.

The buggy scenario involves two paths, with each column showing the order within that path:

  L2CAP peer teardown:                   Concurrent peer reader:
  1. l2cap_conn_del() or another         1. A reader such as
     close path takes a temporary           __peer_lookup_conn(),
     hold on the channel                    setup_header(),
                                            send_mcast_pkt(), or
                                            bt_6lowpan_disconnect()
                                            traverses the peer list and
                                            reads peer->chan
  2. l2cap_chan_del() drops the          2. The reader keeps using the
     connection-owned channel               raw channel pointer after the
     reference before 6LoWPAN               lookup or after only RCU
     close handling finishes                protection remains
  3. chan_close_cb() removes the         3. It dereferences channel
     matching lowpan_peer from the          fields or calls send or close
     peer list                              operations through that
                                            pointer
  4. The original chan_close_cb()
     also dropped the peer-owned
     l2cap_chan reference, and the
     close caller later released
     its temporary hold

A peer reader can still observe the lowpan_peer while chan_close_cb()
has already consumed the peer-owned channel reference and the close
caller is releasing the last temporary hold, leaving peer->chan stale
before the peer's RCU grace period ends.

lowpan_peer objects stay RCU-visible after peer_del() removes them from
the list.

Signed-off-by: Zhang Cen <rollkingzzc@gmail.com>

---
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 2f03b780b40d..ea3ee6929101 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -95,13 +95,20 @@ static inline void peer_add(struct lowpan_btle_dev *dev,
 	atomic_inc(&dev->peer_count);
 }
 
+static void peer_free_rcu(struct rcu_head *rcu)
+{
+	struct lowpan_peer *peer = container_of(rcu, struct lowpan_peer, rcu);
+
+	l2cap_chan_put(peer->chan);
+	kfree(peer);
+	module_put(THIS_MODULE);
+}
+
 static inline bool peer_del(struct lowpan_btle_dev *dev,
 			    struct lowpan_peer *peer)
 {
 	list_del_rcu(&peer->list);
-	kfree_rcu(peer, rcu);
-
-	module_put(THIS_MODULE);
+	call_rcu(&peer->rcu, peer_free_rcu);
 
 	if (atomic_dec_and_test(&dev->peer_count)) {
 		BT_DBG("last peer");
@@ -137,9 +144,32 @@ __peer_lookup_conn(struct lowpan_btle_dev *dev, struct l2cap_conn *conn)
 	return NULL;
 }
 
-static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
-						  struct in6_addr *daddr,
-						  struct sk_buff *skb)
+static struct l2cap_chan *lookup_peer_chan(struct l2cap_conn *conn)
+{
+	struct lowpan_btle_dev *entry;
+	struct lowpan_peer *peer;
+	struct l2cap_chan *chan = NULL;
+
+	rcu_read_lock();
+
+	list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) {
+		peer = __peer_lookup_conn(entry, conn);
+		if (peer) {
+			chan = peer->chan;
+			l2cap_chan_hold(chan);
+			break;
+		}
+	}
+
+	rcu_read_unlock();
+
+	return chan;
+}
+
+static int peer_lookup_dst(struct lowpan_btle_dev *dev, struct in6_addr *daddr,
+			   struct sk_buff *skb, u8 *lladdr,
+			   bdaddr_t *peer_addr, u8 *peer_addr_type,
+			   struct l2cap_chan **chan)
 {
 	struct rt6_info *rt = dst_rt6_info(skb_dst(skb));
 	int count = atomic_read(&dev->peer_count);
@@ -175,13 +205,20 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
 	rcu_read_lock();
 
 	list_for_each_entry_rcu(peer, &dev->peers, list) {
+		struct l2cap_chan *pchan = peer->chan;
+
 		BT_DBG("dst addr %pMR dst type %u ip %pI6c",
-		       &peer->chan->dst, peer->chan->dst_type,
+		       &pchan->dst, pchan->dst_type,
 		       &peer->peer_addr);
 
 		if (!ipv6_addr_cmp(&peer->peer_addr, nexthop)) {
+			memcpy(lladdr, peer->lladdr, ETH_ALEN);
+			*peer_addr = pchan->dst;
+			*peer_addr_type = pchan->dst_type;
+			l2cap_chan_hold(pchan);
+			*chan = pchan;
 			rcu_read_unlock();
-			return peer;
+			return 0;
 		}
 	}
 
@@ -190,9 +227,16 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
 	if (neigh) {
 		list_for_each_entry_rcu(peer, &dev->peers, list) {
 			if (!memcmp(neigh->ha, peer->lladdr, ETH_ALEN)) {
+				struct l2cap_chan *pchan = peer->chan;
+
+				memcpy(lladdr, peer->lladdr, ETH_ALEN);
+				*peer_addr = pchan->dst;
+				*peer_addr_type = pchan->dst_type;
+				l2cap_chan_hold(pchan);
+				*chan = pchan;
 				neigh_release(neigh);
 				rcu_read_unlock();
-				return peer;
+				return 0;
 			}
 		}
 		neigh_release(neigh);
@@ -200,7 +244,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
 
 	rcu_read_unlock();
 
-	return NULL;
+	return -ENOENT;
 }
 
 static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn)
@@ -379,7 +423,7 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
 	struct in6_addr ipv6_daddr;
 	struct ipv6hdr *hdr;
 	struct lowpan_btle_dev *dev;
-	struct lowpan_peer *peer;
+	u8 peer_lladdr[ETH_ALEN];
 	u8 *daddr;
 	int err, status = 0;
 
@@ -388,9 +432,9 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
 	dev = lowpan_btle_dev(netdev);
 
 	memcpy(&ipv6_daddr, &hdr->daddr, sizeof(ipv6_daddr));
+	lowpan_cb(skb)->chan = NULL;
 
 	if (ipv6_addr_is_multicast(&ipv6_daddr)) {
-		lowpan_cb(skb)->chan = NULL;
 		daddr = NULL;
 	} else {
 		BT_DBG("dest IP %pI6c", &ipv6_daddr);
@@ -400,16 +444,15 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
 		 * or user set route) so get peer according to
 		 * the destination address.
 		 */
-		peer = peer_lookup_dst(dev, &ipv6_daddr, skb);
-		if (!peer) {
+		err = peer_lookup_dst(dev, &ipv6_daddr, skb, peer_lladdr,
+				      peer_addr, peer_addr_type,
+				      &lowpan_cb(skb)->chan);
+		if (err) {
 			BT_DBG("no such peer");
-			return -ENOENT;
+			return err;
 		}
 
-		daddr = peer->lladdr;
-		*peer_addr = peer->chan->dst;
-		*peer_addr_type = peer->chan->dst_type;
-		lowpan_cb(skb)->chan = peer->chan;
+		daddr = peer_lladdr;
 
 		status = 1;
 	}
@@ -417,8 +460,13 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
 	lowpan_header_compress(skb, netdev, daddr, dev->netdev->dev_addr);
 
 	err = dev_hard_header(skb, netdev, ETH_P_IPV6, NULL, NULL, 0);
-	if (err < 0)
+	if (err < 0) {
+		if (lowpan_cb(skb)->chan) {
+			l2cap_chan_put(lowpan_cb(skb)->chan);
+			lowpan_cb(skb)->chan = NULL;
+		}
 		return err;
+	}
 
 	return status;
 }
@@ -483,15 +531,23 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
 		dev = lowpan_btle_dev(entry->netdev);
 
 		list_for_each_entry_rcu(pentry, &dev->peers, list) {
+			struct l2cap_chan *chan = pentry->chan;
 			int ret;
 
 			local_skb = skb_clone(skb, GFP_ATOMIC);
+			if (!local_skb) {
+				err = -ENOMEM;
+				continue;
+			}
+
+			l2cap_chan_hold(chan);
 
 			BT_DBG("xmit %s to %pMR type %u IP %pI6c chan %p",
 			       netdev->name,
-			       &pentry->chan->dst, pentry->chan->dst_type,
-			       &pentry->peer_addr, pentry->chan);
-			ret = send_pkt(pentry->chan, local_skb, netdev);
+			       &chan->dst, chan->dst_type,
+			       &pentry->peer_addr, chan);
+			ret = send_pkt(chan, local_skb, netdev);
+			l2cap_chan_put(chan);
 			if (ret < 0)
 				err = ret;
 
@@ -530,10 +586,14 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 	if (err) {
 		if (lowpan_cb(skb)->chan) {
+			struct l2cap_chan *chan = lowpan_cb(skb)->chan;
+
 			BT_DBG("xmit %s to %pMR type %u IP %pI6c chan %p",
 			       netdev->name, &addr, addr_type,
-			       &lowpan_cb(skb)->addr, lowpan_cb(skb)->chan);
-			err = send_pkt(lowpan_cb(skb)->chan, skb, netdev);
+			       &lowpan_cb(skb)->addr, chan);
+			err = send_pkt(chan, skb, netdev);
+			l2cap_chan_put(chan);
+			lowpan_cb(skb)->chan = NULL;
 		} else {
 			err = -ENOENT;
 		}
@@ -802,8 +862,6 @@ static void chan_close_cb(struct l2cap_chan *chan)
 			       last ? "last " : "1 ", peer);
 			BT_DBG("chan %p orig refcnt %u", chan,
 			       kref_read(&chan->kref));
-
-			l2cap_chan_put(chan);
 			break;
 		}
 	}
@@ -917,19 +975,20 @@ static int bt_6lowpan_connect(bdaddr_t *addr, u8 dst_type)
 
 static int bt_6lowpan_disconnect(struct l2cap_conn *conn, u8 dst_type)
 {
-	struct lowpan_peer *peer;
+	struct l2cap_chan *chan;
 
 	BT_DBG("conn %p dst type %u", conn, dst_type);
 
-	peer = lookup_peer(conn);
-	if (!peer)
+	chan = lookup_peer_chan(conn);
+	if (!chan)
 		return -ENOENT;
 
-	BT_DBG("peer %p chan %p", peer, peer->chan);
+	BT_DBG("chan %p", chan);
 
-	l2cap_chan_lock(peer->chan);
-	l2cap_chan_close(peer->chan, ENOENT);
-	l2cap_chan_unlock(peer->chan);
+	l2cap_chan_lock(chan);
+	l2cap_chan_close(chan, ENOENT);
+	l2cap_chan_unlock(chan);
+	l2cap_chan_put(chan);
 
 	return 0;
 }

^ permalink raw reply related

* [PATCH] Bluetooth: RFCOMM: hold listener socket in rfcomm_connect_ind()
From: Zhang Cen @ 2026-05-09 17:37 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: linux-bluetooth, linux-kernel, zerocling0077, Zhang Cen

rfcomm_get_sock_by_channel() returns a listener from rfcomm_sk_list
after dropping rfcomm_sk_list.lock, but it does not hold a reference on
that socket. rfcomm_connect_ind() then locks the listener, queues a
child on it, and may still notify it after unlocking it.

rfcomm_connect_ind()              listener close
1. Look up the parent on          1. close() enters
   rfcomm_sk_list.                   rfcomm_sock_release().
2. Drop rfcomm_sk_list.lock       2. rfcomm_sock_shutdown()
   without pinning the listener.     starts tearing the listener down.
3. Later call lock_sock(parent),  3. rfcomm_sock_kill() unlinks the
   bt_accept_enqueue(parent, ...),   listener and drops its last
   or the deferred-setup callback.   reference.

Take a socket reference on the selected listener before leaving
rfcomm_sk_list.lock, re-check that the parent is still in BT_LISTEN
after locking it, cache the deferred-setup bit while the parent is
locked, and drop the extra reference after the last parent use in
rfcomm_connect_ind().

The buggy scenario involves two paths, with each column showing the order within that path:

  rfcomm_connect_ind():                  listener close:
  1. Call                                1. close() enters
     rfcomm_get_sock_by_channel(BT_LISTEN,       rfcomm_sock_release()
     channel, &src)
  2. Return the matched listener         2. rfcomm_sock_shutdown() runs
     after                                  the BT_LISTEN close path and
     read_unlock(&rfcomm_sk_list.lock)       rfcomm_sock_cleanup_listen(parent)
     without sock_hold()                    sets parent->sk_state =
                                            BT_CLOSED and SOCK_ZAPPED
  3. Later call lock_sock(parent)        3. rfcomm_sock_release() calls
     and bt_accept_enqueue(parent,          sock_orphan(parent) and
     sk, true)                              rfcomm_sock_kill(parent)
  4. After release_sock(parent),         4. rfcomm_sock_kill() unlinks
     read bt_sk(parent)->flags and          the listener from
     may call                               rfcomm_sk_list and sock_put()
     parent->sk_state_change(parent)        can free it

The lookup path drops rfcomm_sk_list.lock without a private reference,
so listener close can mark the socket closed, unlink it, and free it
before rfcomm_connect_ind() reaches lock_sock(), bt_accept_enqueue(), or
its deferred-setup callback.

rfcomm_lock serializes RFCOMM core work but does not serialize userspace
close against rfcomm_sock_release() or rfcomm_sock_kill().

Sanitizer validation reported:
BUG: KASAN: slab-use-after-free in lock_sock_nested()
Read of size 1 at addr ffff88810da92250
Call trace:
  dump_stack_lvl() (?:?)
  print_address_description() (mm/kasan/report.c:373)
  lock_sock_nested() (net/core/sock.c:3780)
  print_report() (?:?)
  __virt_addr_valid() (?:?)
  srso_alias_return_thunk() (arch/x86/include/asm/nospec-branch.h:375)
  kasan_addr_to_slab() (mm/kasan/common.c:45)
  kasan_report() (?:?)
  __kasan_check_byte() (mm/kasan/common.c:571)
  lock_acquire() (?:?)
  rcu_is_watching() (?:?)
  rfcomm_connect_ind() (net/bluetooth/rfcomm/sock.c:952)
  rfcomm_recv_pn() (net/bluetooth/rfcomm/core.c:1432)
  trace_clock_x86_tsc() (arch/x86/kernel/trace_clock.c:14)
  __lock_acquire() (kernel/locking/lockdep.c:5077)
  rfcomm_recv_mcc() (net/bluetooth/rfcomm/core.c:1645)
  do_raw_spin_lock() (?:?)
  mark_held_locks() (kernel/locking/lockdep.c:4308)
  rfcomm_recv_frame() (net/bluetooth/rfcomm/core.c:1738)
  rfcomm_process_rx() (net/bluetooth/rfcomm/core.c:1933)
  rfcomm_run() (net/bluetooth/rfcomm/core.c:2114)
  find_held_lock() (kernel/locking/lockdep.c:5340)
  _raw_spin_unlock_irqrestore() (kernel/locking/spinlock.c:196)
  lockdep_hardirqs_on() (?:?)
  __kthread_parkme() (kernel/kthread.c:259)
  kthread() (?:?)
  _raw_spin_unlock_irq() (kernel/locking/spinlock.c:204)
  ret_from_fork() (?:?)
  __switch_to() (?:?)
  ret_from_fork_asm() (?:?)
  kasan_save_stack() (mm/kasan/common.c:52)
  kasan_save_track() (mm/kasan/common.c:74)
  __kasan_kmalloc() (?:?)
  __kmalloc_noprof() (?:?)
  sk_prot_alloc() (net/core/sock.c:2233)
  sk_alloc() (?:?)
  bt_sock_alloc() (?:?)
  rfcomm_sock_alloc() (net/bluetooth/rfcomm/sock.c:271)
  rfcomm_sock_create() (net/bluetooth/rfcomm/sock.c:305)
  bt_sock_create() (net/bluetooth/af_bluetooth.c:116)
  __sock_create() (?:?)
  __sys_socket() (net/socket.c:1801)
  __x64_sys_socket() (?:?)
  do_syscall_64() (arch/x86/entry/syscall_64.c:87)
  entry_SYSCALL_64_after_hwframe() (?:?)
  kasan_save_free_info() (?:?)
  __kasan_slab_free() (?:?)
  kfree() (?:?)
  __sk_destruct() (net/core/sock.c:2345)
  sk_destruct() (net/core/sock.c:2402)
  __sk_free() (net/core/sock.c:2417)
  sk_free() (net/core/sock.c:2428)
  rfcomm_sock_kill() (net/bluetooth/rfcomm/sock.c:192)
  rfcomm_sock_release() (net/bluetooth/rfcomm/sock.c:912)
  __sock_release() (net/socket.c:713)

Signed-off-by: Zhang Cen <rollkingzzc@gmail.com>

---
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index be6639cd6f59..677c9cd22fb2 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -122,7 +122,7 @@ static struct sock *__rfcomm_get_listen_sock_by_addr(u8 channel, bdaddr_t *src)
 }
 
 /* Find socket with channel and source bdaddr.
- * Returns closest match.
+ * Returns closest match with an extra reference held.
  */
 static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
 {
@@ -136,15 +136,25 @@ static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *
 
 		if (rfcomm_pi(sk)->channel == channel) {
 			/* Exact match. */
-			if (!bacmp(&rfcomm_pi(sk)->src, src))
+			if (!bacmp(&rfcomm_pi(sk)->src, src)) {
+				sock_hold(sk);
 				break;
+			}
 
 			/* Closest match */
-			if (!bacmp(&rfcomm_pi(sk)->src, BDADDR_ANY))
+			if (!bacmp(&rfcomm_pi(sk)->src, BDADDR_ANY)) {
+				if (sk1)
+					sock_put(sk1);
+
 				sk1 = sk;
+				sock_hold(sk1);
+			}
 		}
 	}
 
+	if (sk && sk1)
+		sock_put(sk1);
+
 	read_unlock(&rfcomm_sk_list.lock);
 
 	return sk ? sk : sk1;
@@ -934,6 +944,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
 {
 	struct sock *sk, *parent;
 	bdaddr_t src, dst;
+	bool defer_setup = false;
 	int result = 0;
 
 	BT_DBG("session %p channel %d", s, channel);
@@ -947,6 +958,11 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
 
 	lock_sock(parent);
 
+	if (parent->sk_state != BT_LISTEN)
+		goto done;
+
+	defer_setup = test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags);
+
 	/* Check for backlog size */
 	if (sk_acceptq_is_full(parent)) {
 		BT_DBG("backlog full %d", parent->sk_ack_backlog);
@@ -974,9 +990,11 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
 done:
 	release_sock(parent);
 
-	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
+	if (defer_setup)
 		parent->sk_state_change(parent);
 
+	sock_put(parent);
+
 	return result;
 }

^ permalink raw reply related

* [PATCH] Bluetooth: mgmt: validate advertising TLV envelopes before parsing
From: Zhang Cen @ 2026-05-09 17:37 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: linux-bluetooth, linux-kernel, zerocling0077, Zhang Cen

tlv_data_is_valid() loads the field length from data[i] and then inspects
data[i + 1] for managed EIR types before it proves that the element still
fits inside the supplied advertising buffer.

Move the existing per-element length check ahead of the type-byte tests so
every non-empty element is proven to fit before data[i + 1] is read.

Also reject MGMT_OP_ADD_EXT_ADV_DATA commands whose declared advertising
and scan-response lengths do not match the trailing command payload.
Unlike MGMT_OP_ADD_ADVERTISING, that path did not validate the outer
envelope before slicing cp->data for tlv_data_is_valid().

Sanitizer validation reported:
BUG: KASAN: vmalloc-out-of-bounds in tlv_data_is_valid()
Read of size 1 at addr ffffc9000031a000
Call trace:
  dump_stack_lvl() (?:?)
  print_address_description() (mm/kasan/report.c:373)
  tlv_data_is_valid() (net/bluetooth/mgmt.c:8623)
  print_report() (?:?)
  srso_alias_return_thunk() (arch/x86/include/asm/nospec-branch.h:375)
  kasan_addr_to_slab() (mm/kasan/common.c:45)
  kasan_report() (?:?)
  add_advertising() (net/bluetooth/mgmt.c:8751)
  __entry_text_end() (?:?)
  __hci_dev_get() (net/bluetooth/hci_core.c:67)
  do_raw_read_unlock() (kernel/locking/spinlock_debug.c:178)
  _raw_read_unlock() (kernel/locking/spinlock.c:262)
  hci_mgmt_cmd() (net/bluetooth/hci_sock.c:1619)
  hci_sock_sendmsg() (net/bluetooth/hci_sock.c:1800)
  sock_write_iter() (net/socket.c:1234)
  reacquire_held_locks() (kernel/locking/lockdep.c:5375)
  security_file_permission() (?:?)
  vfs_write() (fs/read_write.c:668)
  __sys_bind() (net/socket.c:1947)
  ksys_write() (fs/read_write.c:729)
  rcu_is_watching() (?:?)
  do_syscall_64() (arch/x86/entry/syscall_64.c:87)
  entry_SYSCALL_64_after_hwframe() (?:?)

Signed-off-by: Zhang Cen <rollkingzzc@gmail.com>

---
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b05bb380e5f8..827a67db4733 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -8638,6 +8638,12 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
 		if (!cur_len)
 			continue;
 
+		/* If the current field length would exceed the total data
+		 * length, then it's invalid.
+		 */
+		if (i + cur_len >= len)
+			return false;
+
 		if (data[i + 1] == EIR_FLAGS &&
 		    (!is_adv_data || flags_managed(adv_flags)))
 			return false;
@@ -8654,12 +8660,6 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
 		if (data[i + 1] == EIR_APPEARANCE &&
 		    appearance_managed(adv_flags))
 			return false;
-
-		/* If the current field length would exceed the total data
-		 * length, then it's invalid.
-		 */
-		if (i + cur_len >= len)
-			return false;
 	}
 
 	return true;
@@ -9113,6 +9113,10 @@ static int add_ext_adv_data(struct sock *sk, struct hci_dev *hdev, void *data,
 
 	BT_DBG("%s", hdev->name);
 
+	if (data_len != sizeof(*cp) + cp->adv_data_len + cp->scan_rsp_len)
+		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_EXT_ADV_DATA,
+				       MGMT_STATUS_INVALID_PARAMS);
+
 	hci_dev_lock(hdev);
 
 	adv_instance = hci_find_adv_instance(hdev, cp->instance);

^ permalink raw reply related

* Re: [PATCH] Bluetooth: btmtk: handle FUNC_CTRL events without status field
From: Tristan Madani @ 2026-05-09 15:31 UTC (permalink / raw)
  To: Mikhail Gavrilov
  Cc: Marcel Holtmann, Luiz Augusto von Dentz, Johan Hedberg,
	linux-bluetooth, linux-kernel, stable
In-Reply-To: <20260508173121.27526-1-mikhail.v.gavrilov@gmail.com>

On Fri, 2026-05-08 at 22:31 +0500, Mikhail Gavrilov wrote:
> Preserve that effective behaviour explicitly: when the status field
> is absent, set status to BTMTK_WMT_ON_UNDONE instead of failing.
> The OOB read remains closed, since skb_pull_data() still validates
> the length before any further access.

Makes sense. The hard -EINVAL was too strict for controllers that
legitimately omit the status field -- falling back to UNDONE preserves
the pre-fix behavior without reopening the OOB read.

Reviewed-by: Tristan Madani <tristan@talencesecurity.com>

^ permalink raw reply

* [bluetooth-next:master] BUILD SUCCESS 303bd23ee2e9c485ebc18c62b29ab972f56a3244
From: kernel test robot @ 2026-05-09 14:50 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
branch HEAD: 303bd23ee2e9c485ebc18c62b29ab972f56a3244  Bluetooth: serialize accept_q access

elapsed time: 726m

configs tested: 270
configs skipped: 55

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig    gcc-15.2.0
alpha                            allyesconfig    gcc-15.2.0
alpha                               defconfig    gcc-15.2.0
arc                              allmodconfig    clang-16
arc                              allmodconfig    gcc-15.2.0
arc                               allnoconfig    gcc-15.2.0
arc                              allyesconfig    clang-23
arc                              allyesconfig    gcc-15.2.0
arc                                 defconfig    gcc-15.2.0
arc                            randconfig-001    gcc-8.5.0
arc                   randconfig-001-20260509    gcc-8.5.0
arc                   randconfig-001-20260509    gcc-9.5.0
arc                            randconfig-002    gcc-8.5.0
arc                   randconfig-002-20260509    gcc-8.5.0
arc                   randconfig-002-20260509    gcc-9.5.0
arm                               allnoconfig    clang-23
arm                               allnoconfig    gcc-15.2.0
arm                              allyesconfig    clang-16
arm                              allyesconfig    gcc-15.2.0
arm                                 defconfig    gcc-15.2.0
arm                            randconfig-001    gcc-8.5.0
arm                   randconfig-001-20260509    gcc-8.5.0
arm                   randconfig-001-20260509    gcc-9.5.0
arm                            randconfig-002    gcc-8.5.0
arm                   randconfig-002-20260509    gcc-8.5.0
arm                   randconfig-002-20260509    gcc-9.5.0
arm                            randconfig-003    gcc-8.5.0
arm                   randconfig-003-20260509    gcc-8.5.0
arm                   randconfig-003-20260509    gcc-9.5.0
arm                            randconfig-004    gcc-8.5.0
arm                   randconfig-004-20260509    gcc-8.5.0
arm                   randconfig-004-20260509    gcc-9.5.0
arm64                            allmodconfig    clang-23
arm64                             allnoconfig    gcc-15.2.0
arm64                               defconfig    gcc-15.2.0
arm64                 randconfig-001-20260509    gcc-10.5.0
arm64                 randconfig-002-20260509    gcc-10.5.0
arm64                 randconfig-003-20260509    gcc-10.5.0
arm64                 randconfig-004-20260509    gcc-10.5.0
csky                             allmodconfig    gcc-15.2.0
csky                              allnoconfig    gcc-15.2.0
csky                                defconfig    gcc-15.2.0
csky                  randconfig-001-20260509    gcc-10.5.0
csky                  randconfig-002-20260509    gcc-10.5.0
hexagon                          allmodconfig    clang-17
hexagon                          allmodconfig    gcc-15.2.0
hexagon                           allnoconfig    clang-23
hexagon                           allnoconfig    gcc-15.2.0
hexagon                             defconfig    gcc-15.2.0
hexagon                        randconfig-001    gcc-11.5.0
hexagon               randconfig-001-20260509    clang-17
hexagon               randconfig-001-20260509    gcc-11.5.0
hexagon                        randconfig-002    gcc-11.5.0
hexagon               randconfig-002-20260509    clang-17
hexagon               randconfig-002-20260509    gcc-11.5.0
i386                             allmodconfig    clang-20
i386                              allnoconfig    gcc-14
i386                              allnoconfig    gcc-15.2.0
i386                             allyesconfig    clang-20
i386        buildonly-randconfig-001-20260509    gcc-14
i386        buildonly-randconfig-002-20260509    gcc-14
i386        buildonly-randconfig-003-20260509    gcc-14
i386        buildonly-randconfig-004-20260509    gcc-14
i386        buildonly-randconfig-005-20260509    gcc-14
i386        buildonly-randconfig-006-20260509    gcc-14
i386                                defconfig    gcc-15.2.0
i386                  randconfig-001-20260509    clang-20
i386                           randconfig-002    gcc-14
i386                  randconfig-002-20260509    clang-20
i386                           randconfig-003    gcc-14
i386                  randconfig-003-20260509    clang-20
i386                  randconfig-004-20260509    clang-20
i386                           randconfig-005    gcc-14
i386                  randconfig-005-20260509    clang-20
i386                           randconfig-006    gcc-14
i386                  randconfig-006-20260509    clang-20
i386                           randconfig-007    gcc-14
i386                  randconfig-007-20260509    clang-20
i386                  randconfig-007-20260509    gcc-14
i386                  randconfig-011-20260509    gcc-14
i386                  randconfig-012-20260509    gcc-14
i386                  randconfig-013-20260509    gcc-14
i386                  randconfig-014-20260509    gcc-14
i386                  randconfig-015-20260509    gcc-14
i386                  randconfig-016-20260509    gcc-14
i386                  randconfig-017-20260509    gcc-14
loongarch                        allmodconfig    clang-23
loongarch                         allnoconfig    clang-23
loongarch                         allnoconfig    gcc-15.2.0
loongarch                           defconfig    clang-19
loongarch                      randconfig-001    gcc-11.5.0
loongarch             randconfig-001-20260509    clang-17
loongarch             randconfig-001-20260509    gcc-11.5.0
loongarch             randconfig-001-20260509    gcc-15.2.0
loongarch                      randconfig-002    gcc-11.5.0
loongarch             randconfig-002-20260509    clang-17
loongarch             randconfig-002-20260509    gcc-11.5.0
m68k                             allmodconfig    gcc-15.2.0
m68k                              allnoconfig    gcc-15.2.0
m68k                             allyesconfig    clang-16
m68k                             allyesconfig    gcc-15.2.0
m68k                                defconfig    clang-19
m68k                        m5407c3_defconfig    gcc-15.2.0
microblaze                        allnoconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-15.2.0
microblaze                          defconfig    clang-19
mips                             allmodconfig    gcc-15.2.0
mips                              allnoconfig    gcc-15.2.0
mips                             allyesconfig    gcc-15.2.0
mips                           ip32_defconfig    clang-23
mips                    maltaup_xpa_defconfig    gcc-15.2.0
nios2                            allmodconfig    clang-23
nios2                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-23
nios2                             allnoconfig    gcc-11.5.0
nios2                               defconfig    clang-19
nios2                          randconfig-001    gcc-11.5.0
nios2                 randconfig-001-20260509    clang-17
nios2                 randconfig-001-20260509    gcc-11.5.0
nios2                 randconfig-001-20260509    gcc-15.2.0
nios2                          randconfig-002    gcc-11.5.0
nios2                 randconfig-002-20260509    clang-17
nios2                 randconfig-002-20260509    gcc-11.5.0
nios2                 randconfig-002-20260509    gcc-15.2.0
openrisc                         allmodconfig    clang-23
openrisc                         allmodconfig    gcc-11.5.0
openrisc                         allmodconfig    gcc-15.2.0
openrisc                          allnoconfig    clang-23
openrisc                          allnoconfig    gcc-15.2.0
openrisc                            defconfig    gcc-15.2.0
parisc                           allmodconfig    gcc-15.2.0
parisc                            allnoconfig    clang-23
parisc                            allnoconfig    gcc-15.2.0
parisc                           allyesconfig    clang-19
parisc                           allyesconfig    gcc-15.2.0
parisc                              defconfig    gcc-15.2.0
parisc                         randconfig-001    gcc-11.5.0
parisc                randconfig-001-20260509    gcc-11.5.0
parisc                         randconfig-002    gcc-11.5.0
parisc                randconfig-002-20260509    gcc-11.5.0
parisc64                            defconfig    clang-19
powerpc                          allmodconfig    gcc-15.2.0
powerpc                           allnoconfig    clang-23
powerpc                           allnoconfig    gcc-15.2.0
powerpc                       eiger_defconfig    clang-23
powerpc                      ppc64e_defconfig    gcc-15.2.0
powerpc                        randconfig-001    gcc-11.5.0
powerpc               randconfig-001-20260509    gcc-11.5.0
powerpc                        randconfig-002    gcc-11.5.0
powerpc               randconfig-002-20260509    gcc-11.5.0
powerpc64                      randconfig-001    gcc-11.5.0
powerpc64             randconfig-001-20260509    gcc-11.5.0
powerpc64                      randconfig-002    gcc-11.5.0
powerpc64             randconfig-002-20260509    gcc-11.5.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-23
riscv                             allnoconfig    gcc-15.2.0
riscv                            allyesconfig    clang-16
riscv                               defconfig    clang-23
riscv                               defconfig    gcc-15.2.0
riscv                 randconfig-001-20260509    clang-23
riscv                 randconfig-002-20260509    clang-23
s390                             allmodconfig    clang-18
s390                             allmodconfig    clang-19
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-15.2.0
s390                                defconfig    clang-23
s390                                defconfig    gcc-15.2.0
s390                  randconfig-001-20260509    clang-23
s390                  randconfig-002-20260509    clang-23
sh                               allmodconfig    gcc-15.2.0
sh                                allnoconfig    clang-23
sh                                allnoconfig    gcc-15.2.0
sh                               allyesconfig    clang-19
sh                               allyesconfig    gcc-15.2.0
sh                                  defconfig    gcc-14
sh                                  defconfig    gcc-15.2.0
sh                    randconfig-001-20260509    clang-23
sh                    randconfig-002-20260509    clang-23
sh                             shx3_defconfig    gcc-15.2.0
sparc                             allnoconfig    clang-23
sparc                             allnoconfig    gcc-15.2.0
sparc                               defconfig    gcc-15.2.0
sparc                          randconfig-001    clang-23
sparc                 randconfig-001-20260509    clang-23
sparc                          randconfig-002    clang-23
sparc                 randconfig-002-20260509    clang-23
sparc64                          allmodconfig    clang-23
sparc64                             defconfig    clang-20
sparc64                             defconfig    gcc-14
sparc64                        randconfig-001    clang-23
sparc64               randconfig-001-20260509    clang-23
sparc64                        randconfig-002    clang-23
sparc64               randconfig-002-20260509    clang-23
um                               allmodconfig    clang-19
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-14
um                               allyesconfig    gcc-15.2.0
um                                  defconfig    clang-23
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                             randconfig-001    clang-23
um                    randconfig-001-20260509    clang-23
um                             randconfig-002    clang-23
um                    randconfig-002-20260509    clang-23
um                           x86_64_defconfig    clang-23
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-20
x86_64                            allnoconfig    clang-20
x86_64                            allnoconfig    clang-23
x86_64                           allyesconfig    clang-20
x86_64      buildonly-randconfig-001-20260509    clang-20
x86_64      buildonly-randconfig-002-20260509    clang-20
x86_64      buildonly-randconfig-003-20260509    clang-20
x86_64      buildonly-randconfig-004-20260509    clang-20
x86_64      buildonly-randconfig-005-20260509    clang-20
x86_64      buildonly-randconfig-006-20260509    clang-20
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-20
x86_64                         randconfig-001    clang-20
x86_64                         randconfig-001    gcc-14
x86_64                randconfig-001-20260509    clang-20
x86_64                randconfig-001-20260509    gcc-14
x86_64                         randconfig-002    clang-20
x86_64                         randconfig-002    gcc-14
x86_64                randconfig-002-20260509    clang-20
x86_64                randconfig-002-20260509    gcc-14
x86_64                         randconfig-003    clang-20
x86_64                randconfig-003-20260509    clang-20
x86_64                randconfig-003-20260509    gcc-14
x86_64                         randconfig-004    clang-20
x86_64                randconfig-004-20260509    clang-20
x86_64                randconfig-004-20260509    gcc-14
x86_64                         randconfig-005    clang-20
x86_64                         randconfig-005    gcc-14
x86_64                randconfig-005-20260509    clang-20
x86_64                randconfig-005-20260509    gcc-14
x86_64                         randconfig-006    clang-20
x86_64                randconfig-006-20260509    clang-20
x86_64                randconfig-006-20260509    gcc-14
x86_64                randconfig-011-20260509    gcc-14
x86_64                randconfig-012-20260509    gcc-14
x86_64                randconfig-013-20260509    gcc-14
x86_64                randconfig-014-20260509    gcc-14
x86_64                randconfig-015-20260509    gcc-14
x86_64                randconfig-016-20260509    gcc-14
x86_64                randconfig-071-20260509    clang-20
x86_64                randconfig-071-20260509    gcc-14
x86_64                randconfig-072-20260509    clang-20
x86_64                randconfig-072-20260509    gcc-14
x86_64                randconfig-073-20260509    clang-20
x86_64                randconfig-074-20260509    clang-20
x86_64                randconfig-075-20260509    clang-20
x86_64                randconfig-076-20260509    clang-20
x86_64                               rhel-9.4    clang-20
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-20
x86_64                    rhel-9.4-kselftests    clang-20
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-20
xtensa                            allnoconfig    clang-23
xtensa                            allnoconfig    gcc-15.2.0
xtensa                           allyesconfig    clang-23
xtensa                           allyesconfig    gcc-11.5.0
xtensa                           allyesconfig    gcc-15.2.0
xtensa                         randconfig-001    clang-23
xtensa                randconfig-001-20260509    clang-23
xtensa                         randconfig-002    clang-23
xtensa                randconfig-002-20260509    clang-23

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* RE: Bluetooth: hci_uart: serialize close flush with write_work
From: bluez.test.bot @ 2026-05-09 10:17 UTC (permalink / raw)
  To: linux-bluetooth, wuyankun
In-Reply-To: <20260509083124.291207-1-wuyankun@uniontech.com>

[-- Attachment #1: Type: text/plain, Size: 1799 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=1091961

---Test result---

Test Summary:
CheckPatch                    FAIL      0.92 seconds
GitLint                       PASS      0.23 seconds
SubjectPrefix                 PASS      0.07 seconds
BuildKernel                   PASS      26.57 seconds
CheckAllWarning               PASS      29.35 seconds
CheckSparse                   PASS      27.96 seconds
BuildKernel32                 PASS      25.93 seconds
TestRunnerSetup               PASS      570.70 seconds
IncrementalBuild              PASS      25.68 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
Bluetooth: hci_uart: serialize close flush with write_work
WARNING: Reported-by: should be immediately followed by Closes: with a URL to the report
#97: 
Reported-by: syzbot+da2717d5c64bf7975268@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=da2717d5c64bf7975268

WARNING: The commit message has 'stable@', perhaps it also needs a 'Fixes:' tag?

total: 0 errors, 2 warnings, 11 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/patch/14562736.patch has style problems, please review.

NOTE: Ignored message types: UNKNOWN_COMMIT_ID

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.




https://github.com/bluez/bluetooth-next/pull/158

---
Regards,
Linux Bluetooth


^ permalink raw reply

* Re: [PATCH BlueZ 0/1] btmon/TDS: decode org 0x02 as Wi-Fi Alliance
From: Paul Menzel @ 2026-05-09  9:08 UTC (permalink / raw)
  To: Preston Hunt; +Cc: linux-bluetooth
In-Reply-To: <20260509002249.2771777-1-me@prestonhunt.com>

Dear Preston,


Thank you for the patch.

Am 09.05.26 um 02:22 schrieb Preston Hunt:
> Adding support to show Wi-Fi Alliance when decoding TDS frames in btmon.
> AFAIK, this code has been assigned to WFA.

I’d add this to the commit message, and maybe even document the test setup.


Kind regards,

Paul

^ permalink raw reply

* [PATCH] Bluetooth: hci_uart: serialize close flush with write_work
From: wuyankun @ 2026-05-09  8:31 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, wuyankun,
	syzbot+da2717d5c64bf7975268, stable

hci_uart_close() calls hci_uart_flush(), and flush may free hu->tx_skb.
At the same time, hci_uart_write_work() can still be running and access
the same skb (for example through skb_pull()), which leads to a
use-after-free.

Fix this by canceling write_work before calling hci_uart_flush(), so the
tx_skb lifetime is fully serialized against the TX worker.

Reported-by: syzbot+da2717d5c64bf7975268@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=da2717d5c64bf7975268
Cc: stable@vger.kernel.org
Signed-off-by: wuyankun <wuyankun@uniontech.com>
---
 drivers/bluetooth/hci_ldisc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 275ea865bc29..51cc9af0f7e8 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -263,8 +263,11 @@ static int hci_uart_open(struct hci_dev *hdev)
 /* Close device */
 static int hci_uart_close(struct hci_dev *hdev)
 {
+	struct hci_uart *hu = hci_get_drvdata(hdev);
 	BT_DBG("hdev %p", hdev);
 
+	/* Ensure write_work is not touching tx_skb while flush frees it. */
+	cancel_work_sync(&hu->write_work);
 	hci_uart_flush(hdev);
 	hdev->flush = NULL;
 	return 0;
-- 
2.20.1


^ permalink raw reply related

* RE: btmon/TDS: decode org 0x02 as Wi-Fi Alliance
From: bluez.test.bot @ 2026-05-09  2:14 UTC (permalink / raw)
  To: linux-bluetooth, me
In-Reply-To: <20260509002249.2771777-2-me@prestonhunt.com>

[-- Attachment #1: Type: text/plain, Size: 1323 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=1091848

---Test result---

Test Summary:
CheckPatch                    PASS      0.34 seconds
GitLint                       PASS      0.26 seconds
BuildEll                      PASS      20.23 seconds
BluezMake                     PASS      643.92 seconds
MakeCheck                     PASS      0.89 seconds
MakeDistcheck                 PASS      246.11 seconds
CheckValgrind                 PASS      218.86 seconds
CheckSmatch                   WARNING   346.88 seconds
bluezmakeextell               PASS      181.91 seconds
IncrementalBuild              PASS      639.76 seconds
ScanBuild                     PASS      1013.45 seconds

Details
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
monitor/packet.c:2000:26: warning: Variable length array is used.monitor/packet.c: note: in included file:monitor/bt.h:3909:52: warning: array of flexible structuresmonitor/bt.h:3897:40: warning: array of flexible structures


https://github.com/bluez/bluez/pull/2113

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [bluez/bluez] 078adb: btmon: decode 0x02 as Wi-Fi Alliance
From: Preston Hunt @ 2026-05-09  1:18 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1091848
  Home:   https://github.com/bluez/bluez
  Commit: 078adbacedc3eea2d1c9eeac052cd2b8b3a84bbf
      https://github.com/bluez/bluez/commit/078adbacedc3eea2d1c9eeac052cd2b8b3a84bbf
  Author: Preston Hunt <me@prestonhunt.com>
  Date:   2026-05-09 (Sat, 09 May 2026)

  Changed paths:
    M monitor/packet.c

  Log Message:
  -----------
  btmon: decode 0x02 as Wi-Fi Alliance



To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [PATCH BlueZ 1/1] btmon: decode 0x02 as Wi-Fi Alliance
From: Preston Hunt @ 2026-05-09  0:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Preston Hunt
In-Reply-To: <20260509002249.2771777-1-me@prestonhunt.com>

---
 monitor/packet.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/monitor/packet.c b/monitor/packet.c
index a0bf7a709..9439a74c5 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -4009,6 +4009,18 @@ static void print_mesh_data(const uint8_t *data, uint8_t len)
 	packet_hexdump(data + 1, len - 1);
 }
 
+static char *get_org_label(uint8_t org)
+{
+	switch (org) {
+	case 0x01:
+		return "Bluetooth SIG";
+	case 0x02:
+		return "Wi-Fi Alliance";
+	default:
+		return "RFU";
+	}
+}
+
 static void print_transport_data(const uint8_t *data, uint8_t len)
 {
 	print_field("Transport Discovery Data");
@@ -4016,8 +4028,8 @@ static void print_transport_data(const uint8_t *data, uint8_t len)
 	if (len < 3)
 		return;
 
-	print_field("  Organization: %s (0x%02x)",
-			data[0] == 0x01 ? "Bluetooth SIG" : "RFU", data[0]);
+	print_field("  Organization: %s (0x%02x)", get_org_label(data[0]),
+			data[0]);
 	print_field("  Flags: 0x%2.2x", data[1]);
 	print_field("    Role: 0x%2.2x", data[1] & 0x03);
 
-- 
2.51.2


^ permalink raw reply related

* [PATCH BlueZ 0/1] btmon/TDS: decode org 0x02 as Wi-Fi Alliance
From: Preston Hunt @ 2026-05-09  0:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Preston Hunt

Adding support to show Wi-Fi Alliance when decoding TDS frames in btmon.
AFAIK, this code has been assigned to WFA.

Preston Hunt (1):
  btmon: decode 0x02 as Wi-Fi Alliance

 monitor/packet.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

-- 
2.51.2


^ permalink raw reply

* RE: [RFC,BlueZ] monitor: Fix RAS CS step mode parsing issues
From: bluez.test.bot @ 2026-05-08 21:50 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz
In-Reply-To: <20260508191728.428868-1-luiz.dentz@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1981 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=1091796

---Test result---

Test Summary:
CheckPatch                    FAIL      0.49 seconds
GitLint                       PASS      0.33 seconds
BuildEll                      PASS      19.87 seconds
BluezMake                     PASS      597.89 seconds
MakeCheck                     PASS      0.94 seconds
MakeDistcheck                 PASS      231.44 seconds
CheckValgrind                 PASS      199.29 seconds
CheckSmatch                   PASS      319.52 seconds
bluezmakeextell               PASS      163.67 seconds
IncrementalBuild              PASS      599.15 seconds
ScanBuild                     PASS      913.10 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[RFC,BlueZ] monitor: Fix RAS CS step mode parsing issues
WARNING:BAD_SIGN_OFF: Non-standard signature: Assisted-by:
#113: 
Assisted-by: OpenCode:claude-opus-4.6

ERROR:BAD_SIGN_OFF: Unrecognized email address: 'OpenCode:claude-opus-4.6'
#113: 
Assisted-by: OpenCode:claude-opus-4.6

/github/workspace/src/patch/14562283.patch total: 1 errors, 1 warnings, 161 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/patch/14562283.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.




https://github.com/bluez/bluez/pull/2111

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [bluez/bluez] b58ccc: monitor: Fix RAS CS step mode parsing issues
From: Luiz Augusto von Dentz @ 2026-05-08 20:59 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1091796
  Home:   https://github.com/bluez/bluez
  Commit: b58ccc9678cba3caa765b7b70da0a47fcc8ead91
      https://github.com/bluez/bluez/commit/b58ccc9678cba3caa765b7b70da0a47fcc8ead91
  Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  Date:   2026-05-08 (Fri, 08 May 2026)

  Changed paths:
    M monitor/att.c

  Log Message:
  -----------
  monitor: Fix RAS CS step mode parsing issues

Fix double space typo in print_ranging_steps signature.

Fix ToA_ToD sign extension using proper cast via (uint32_t)(int16_t)
instead of unconditionally OR-ing with 0xFFFF0000 which corrupts
positive values.

Refactor print_step_mode_3 to reuse print_step_mode_1 and
print_step_mode_2 eliminating ~90 lines of duplicated code.

Initialize first_segment to false so the error path via goto done
does not incorrectly print remaining data when the segmentation
header was never parsed.

Improve Mode 0 step data length heuristic with better alignment
check and clearer documentation of the limitation.

Assisted-by: OpenCode:claude-opus-4.6



To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* Bluetooth: L2CAP: missing NULL guard in remaining l2cap_chan_ops callbacks
From: y2k @ 2026-05-08 20:21 UTC (permalink / raw)
  To: marcel; +Cc: luiz.dentz, linux-bluetooth, linux-kernel

Commits 0a120d961663, 78a88d43dab8, and 2ff1a41a912d added NULL guards
for chan->data in l2cap_sock_new_connection_cb(), l2cap_sock_get_sndtimeo_cb(),
and l2cap_sock_state_change_cb() respectively.

The same NULL guard is still missing in five other l2cap_chan_ops callbacks
in net/bluetooth/l2cap_sock.c:

  - l2cap_sock_defer_cb()       (.defer)
  - l2cap_sock_suspend_cb()     (.suspend)
  - l2cap_sock_set_shutdown_cb() (.set_shutdown)
  - l2cap_sock_get_peer_pid_cb() (.get_peer_pid)
  - l2cap_sock_filter()          (.filter)

All five dereference chan->data directly without checking for NULL:

  struct sock *sk = chan->data;
  lock_sock(sk);  /* or direct sk-> access */

The fix mirrors the existing guards:

  struct sock *sk = chan->data;
  if (!sk)
      return;  /* or appropriate return value */

Fixes: 80808e431e1e ("Bluetooth: Add l2cap_chan_ops abstraction")
Reported-by: y2k <y2k@desarrollaria.com>

Thanks,
y2k
y2k@desarrollaria.com

^ permalink raw reply

* RE: [RFC,BlueZ] monitor: Fix RAS CS step mode parsing issues
From: bluez.test.bot @ 2026-05-08 20:00 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz
In-Reply-To: <20260508191728.428868-1-luiz.dentz@gmail.com>

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

This is an automated email and please do not reply to this email.

Dear Submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.

----- Output -----

error: patch failed: monitor/att.c:4425
error: monitor/att.c: patch does not apply
hint: Use 'git am --show-current-patch' to see the failed patch

Please resolve the issue and submit the patches again.


---
Regards,
Linux Bluetooth


^ permalink raw reply

* [bluez/bluez]
From: BluezTestBot @ 2026-05-08 20:00 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1091417
  Home:   https://github.com/bluez/bluez

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez] 7cd27f: monitor: Parsing of cs step mode data in RAS Notif...
From: prathibhamadugonde @ 2026-05-08 20:00 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/master
  Home:   https://github.com/bluez/bluez
  Commit: 7cd27f4f66aa88194fbc1565bc13f24405acacd8
      https://github.com/bluez/bluez/commit/7cd27f4f66aa88194fbc1565bc13f24405acacd8
  Author: Prathibha Madugonde <prathibha.madugonde@oss.qualcomm.com>
  Date:   2026-05-08 (Fri, 08 May 2026)

  Changed paths:
    M monitor/att.c

  Log Message:
  -----------
  monitor: Parsing of cs step mode data in RAS Notifications

Sample Decoding Example:
            Subevent #0:
              Start ACL Connection Event: 406
              Frequency Compensation: -16384 (0.01 ppm)
              Ranging Done Status: Partial results, more to follow (0x1)
              Subevent Done Status: All results complete (0x0)
              Ranging Abort Reason: No abort (0x0)
              Subevent Abort Reason: No abort (0x0)
              Reference Power Level: -14 dBm
              Number of Steps Reported: 58
                Step 0
                  Mode Type: 0
                  Aborted: No
                  Packet Quality: 0x00
                    CS Access Address check is successful
                    Bit errors: 0
                  Packet RSSI: -52
                  Packet Antenna: 1
                Step 1
                  Mode Type: 0
                  Aborted: No
                  Packet Quality: 0x00
                    CS Access Address check is successful
                    Bit errors: 0
                  Packet RSSI: -48
                  Packet Antenna: 1
                Step 2
                  Mode Type: 1
                  Aborted: No
                  Packet Quality: 0x00
                    CS Access Address check is successful
                    Bit errors: 0
                  Packet NADM: Unknown NADM (0xff)
                  Packet RSSI: -60
                  ToA_ToD: 0xffffff45
                  Packet Antenna: 1
                Step 3
                  Mode Type: 1
                  Aborted: No
                  Packet Quality: 0x00
                    CS Access Address check is successful
                    Bit errors: 0
                  Packet NADM: Unknown NADM (0xff)
                  Packet RSSI: -54
                  ToA_ToD: 0xffffff53
                  Packet Antenna: 1



To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* Re: [PATCH BlueZ v3] monitor: Parsing of cs step mode data in RAS Notifications
From: patchwork-bot+bluetooth @ 2026-05-08 19:20 UTC (permalink / raw)
  To: Prathibha Madugonde
  Cc: linux-bluetooth, luiz.dentz, quic_mohamull, quic_hbandi,
	quic_anubhavg
In-Reply-To: <20260508053819.3424918-1-prathm@qti.qualcomm.com>

Hello:

This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Fri,  8 May 2026 11:08:19 +0530 you wrote:
> From: Prathibha Madugonde <prathibha.madugonde@oss.qualcomm.com>
> 
> Sample Decoding Example:
>             Subevent #0:
>               Start ACL Connection Event: 406
>               Frequency Compensation: -16384 (0.01 ppm)
>               Ranging Done Status: Partial results, more to follow (0x1)
>               Subevent Done Status: All results complete (0x0)
>               Ranging Abort Reason: No abort (0x0)
>               Subevent Abort Reason: No abort (0x0)
>               Reference Power Level: -14 dBm
>               Number of Steps Reported: 58
>                 Step 0
>                   Mode Type: 0
>                   Aborted: No
>                   Packet Quality: 0x00
>                     CS Access Address check is successful
>                     Bit errors: 0
>                   Packet RSSI: -52
>                   Packet Antenna: 1
>                 Step 1
>                   Mode Type: 0
>                   Aborted: No
>                   Packet Quality: 0x00
>                     CS Access Address check is successful
>                     Bit errors: 0
>                   Packet RSSI: -48
>                   Packet Antenna: 1
>                 Step 2
>                   Mode Type: 1
>                   Aborted: No
>                   Packet Quality: 0x00
>                     CS Access Address check is successful
>                     Bit errors: 0
>                   Packet NADM: Unknown NADM (0xff)
>                   Packet RSSI: -60
>                   ToA_ToD: 0xffffff45
>                   Packet Antenna: 1
>                 Step 3
>                   Mode Type: 1
>                   Aborted: No
>                   Packet Quality: 0x00
>                     CS Access Address check is successful
>                     Bit errors: 0
>                   Packet NADM: Unknown NADM (0xff)
>                   Packet RSSI: -54
>                   ToA_ToD: 0xffffff53
>                   Packet Antenna: 1
> 
> [...]

Here is the summary with links:
  - [BlueZ,v3] monitor: Parsing of cs step mode data in RAS Notifications
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=7cd27f4f66aa

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH] Bluetooth: btmtk: accept too short WMT FUNC_CTRL events
From: Mikhail Gavrilov @ 2026-05-08 19:19 UTC (permalink / raw)
  To: Pauli Virtanen; +Cc: Luiz Augusto von Dentz, linux-bluetooth
In-Reply-To: <d9fe37aa17175290bc406ccad8ed4cf533dfd8b8.camel@iki.fi>

On Sat, May 9, 2026 at 12:09 AM Pauli Virtanen <pav@iki.fi> wrote:
>
> Hi Luiz,
>
> pe, 2026-04-24 kello 15:38 -0400, Luiz Augusto von Dentz kirjoitti:
> > Hi Pauli, Tristan,
> >
> > On Fri, Apr 24, 2026 at 3:25 PM Pauli Virtanen <pav@iki.fi> wrote:
> > >
> > > MT7925 (USB ID 0e8d:e025) on fw version 20260106153314 sends WMT
> > > FUNC_CTRL events that are missing the status field.
> > >
> > > Prior to commit 006b9943b982 ("Bluetooth: btmtk: validate WMT event SKB
> > > length before struct access") the status was read from out-of-bounds of
> > > SKB data, which usually would result to success with
> > > BTMTK_WMT_ON_UNDONE, although I don't know the intent here.  The bounds
> > > check added in that commit returns with error instead, producing
> > > "Bluetooth: hci0: Failed to send wmt func ctrl (-22)" and makes the
> > > device unusable.
> > >
> > > Fix the regression by interpreting too short packet as status
> > > BTMTK_WMT_ON_UNDONE, which makes the device work normally again.
> > >
> > > Fixes: 006b9943b982 ("Bluetooth: btmtk: validate WMT event SKB length before struct access")
> > > Signed-off-by: Pauli Virtanen <pav@iki.fi>
> > > ---
> > >
> > > Notes:
> > >     AFAICS the commit is not yet pulled and is only in bluetooth-next, so
> > >     maybe this should be just fixup?
> >
> > Yeah, I'll most likely fix it in place and add your Signed-off-by.
>
> Looks like this got pulled to net without this fix, so it's broken now
>
> >
> > >  drivers/bluetooth/btmtk.c | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
> > > index ab34f1dd42bc..68a32d11e5ec 100644
> > > --- a/drivers/bluetooth/btmtk.c
> > > +++ b/drivers/bluetooth/btmtk.c
> > > @@ -719,8 +719,8 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
> > >         case BTMTK_WMT_FUNC_CTRL:
> > >                 if (!skb_pull_data(data->evt_skb,
> > >                                    sizeof(wmt_evt_funcc->status))) {
> > > -                       err = -EINVAL;
> > > -                       goto err_free_skb;
> > > +                       status = BTMTK_WMT_ON_UNDONE;
> > > +                       break;
> >
> > This probably means the original change was never tested on real
> > hardware. We likely need input from the MediaTek team on how to handle
> > these events, as I don't think a public spec exists.
> >
> > >                 }
> > >
> > >                 wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
> > > --
> > > 2.53.0
> > >
> >
>
> --
> Pauli Virtanen

Hi Pauli, Luiz,

I sent a functionally equivalent fix [1] earlier today before
finding your April 24 submission -- apologies for the noise.

Confirming the same regression on MediaTek MT7922 (USB ID
0489:e0e2, firmware build 20260224103448): "Failed to send wmt
func ctrl (-22)" right after HW/SW Version, BT setup aborts.
Reverting bd75e1003d3e on top of v7.1-rc2 restores Bluetooth;
your fix has the same effect on my hardware.

So this is not chip-specific: MT7922 (Wi-Fi 6E generation) and
MT7925 (Wi-Fi 7 generation) firmware both send 7-byte FUNC_CTRL
events without the trailing __be16 status, suggesting a property
of the MediaTek WMT firmware family rather than an individual
quirk.

Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> # MT7922 (0489:e0e2)

[1] https://lore.kernel.org/linux-bluetooth/20260508173121.27526-1-mikhail.v.gavrilov@gmail.com/

-- 
Thanks,
Mikhail

^ permalink raw reply

* [RFC PATCH BlueZ] monitor: Fix RAS CS step mode parsing issues
From: Luiz Augusto von Dentz @ 2026-05-08 19:17 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Fix double space typo in print_ranging_steps signature.

Fix ToA_ToD sign extension using proper cast via (uint32_t)(int16_t)
instead of unconditionally OR-ing with 0xFFFF0000 which corrupts
positive values.

Refactor print_step_mode_3 to reuse print_step_mode_1 and
print_step_mode_2 eliminating ~90 lines of duplicated code.

Initialize first_segment to false so the error path via goto done
does not incorrectly print remaining data when the segmentation
header was never parsed.

Improve Mode 0 step data length heuristic with better alignment
check and clearer documentation of the limitation.

Assisted-by: OpenCode:claude-opus-4.6
---
 monitor/att.c | 122 ++++++++------------------------------------------
 1 file changed, 18 insertions(+), 104 deletions(-)

diff --git a/monitor/att.c b/monitor/att.c
index 278ac5675fd4..7506dc528e85 100644
--- a/monitor/att.c
+++ b/monitor/att.c
@@ -4425,7 +4425,7 @@ static void print_step_mode_1(const struct l2cap_frame *frame, uint8_t len)
 		return;
 	}
 
-	print_field("          ToA_ToD: 0x%08x", toa_tod | 0xFFFF0000);
+	print_field("          ToA_ToD: 0x%08x", (uint32_t)(int16_t)toa_tod);
 
 	if (!l2cap_frame_get_u8((void *)frame, &antenna)) {
 		print_text(COLOR_ERROR, "          Packet Antenna: invalid");
@@ -4501,13 +4501,7 @@ static void print_step_mode_2(const struct l2cap_frame *frame, uint8_t len,
 static void print_step_mode_3(const struct l2cap_frame *frame, uint8_t len,
 				uint8_t num_antenna_paths)
 {
-	uint8_t quality, nadm, rssi, antenna;
-	uint16_t toa_tod;
-	uint8_t ant_perm_idx;
-	uint8_t i;
-	uint32_t pct;
-	uint16_t i_sample, q_sample;
-	uint8_t tone_quality;
+	uint8_t mode2_len;
 
 	/* Mode 3 = Mode 1 (6 bytes) + Mode 2 (variable) */
 	if (len < 6) {
@@ -4515,101 +4509,18 @@ static void print_step_mode_3(const struct l2cap_frame *frame, uint8_t len,
 		return;
 	}
 
-	/* Parse Mode 1 data first */
-	if (!l2cap_frame_get_u8((void *)frame, &quality)) {
-		print_text(COLOR_ERROR, "          Packet Quality: invalid");
-		return;
-	}
+	/* Parse Mode 1 portion */
+	print_step_mode_1(frame, 6);
 
-	print_field("          Packet Quality: 0x%02x", quality);
-	print_field("            %s", packet_quality_str(quality));
-	print_field("            Bit errors: %u", (quality >> 2) & 0x3F);
-
-	if (!l2cap_frame_get_u8((void *)frame, &nadm)) {
-		print_text(COLOR_ERROR, "          Packet NADM: invalid size");
-		return;
-	}
-
-	if (nadm == 0xFF)
-		print_field("          Packet NADM: Unknown NADM (0xff)");
-	else
-		print_field("          Packet NADM: %u", nadm);
-
-	if (!l2cap_frame_get_u8((void *)frame, &rssi)) {
-		print_text(COLOR_ERROR, "          Packet RSSI: invalid size");
-		return;
-	}
-
-	print_field("          Packet RSSI: %d", (int8_t)rssi);
-
-	if (!l2cap_frame_get_le16((void *)frame, &toa_tod)) {
-		print_text(COLOR_ERROR, "          ToA_ToD: invalid size");
-		return;
-	}
-
-	print_field("          ToA_ToD: 0x%08x", toa_tod | 0xFFFF0000);
-
-	if (!l2cap_frame_get_u8((void *)frame, &antenna)) {
-		print_text(COLOR_ERROR, "          Packet Antenna: invalid");
-		return;
-	}
-
-	print_field("          Packet Antenna: %u", antenna);
-
-	/* Now parse Mode 2 data */
 	if (frame->size < 1)
 		return;
 
-	if (!l2cap_frame_get_u8((void *)frame, &ant_perm_idx)) {
-		print_text(COLOR_ERROR, "          Antenna Permutation Index: "
-							"invalid size");
-		return;
-	}
-
-	print_field("          Antenna Permutation Index: %u", ant_perm_idx);
-
-	/* Use the antenna paths count from ranging header */
-	for (i = 0; i < (num_antenna_paths + 1); i++) {
-		if (frame->size < 4) {
-			print_text(COLOR_ERROR,
-				"            Insufficient data for path %u",
-				i);
-			return;
-		}
-
-		if (!l2cap_frame_get_le24((void *)frame, &pct)) {
-			print_text(COLOR_ERROR, "            PCT: invalid");
-			return;
-		}
-
-		/* Extract 12-bit I and Q samples from 24-bit PCT */
-		i_sample = pct & 0x0FFF;
-		q_sample = (pct >> 12) & 0x0FFF;
-
-		print_field("          Path %u", i);
-		print_field("            PCT: 0x%06x", pct);
-		print_field("              I: 0x%03x", i_sample);
-		print_field("              Q: 0x%03x", q_sample);
-
-		if (!l2cap_frame_get_u8((void *)frame, &tone_quality)) {
-			print_text(COLOR_ERROR,
-				"            Tone quality indicator: "
-				"invalid size");
-			return;
-		}
-
-		print_field("            Tone quality indicator: 0x%02x",
-				tone_quality);
-		print_field("              %s (0x%02x)",
-				tone_quality_str(tone_quality),
-				tone_quality & 0x03);
-		print_field("              %s (0x%02x)",
-				tone_extension_str(tone_quality),
-				(tone_quality >> 4) & 0x03);
-	}
+	/* Parse Mode 2 portion */
+	mode2_len = len - 6;
+	print_step_mode_2(frame, mode2_len, num_antenna_paths);
 }
 
-static void  print_ranging_steps(const struct l2cap_frame *frame,
+static void print_ranging_steps(const struct l2cap_frame *frame,
 				uint8_t num_steps, uint8_t num_antenna_paths)
 {
 	uint8_t step_idx;
@@ -4649,15 +4560,18 @@ static void  print_ranging_steps(const struct l2cap_frame *frame,
 		 */
 		switch (mode_type) {
 		case 0:
-			/* Mode 0: Default to 3 bytes (reflector)
-			 * Only use 5 bytes if we're the last step AND have
-			 * exactly 5 bytes remaining
+			/* Mode 0: 3 bytes without Measured Freq Offset, or
+			 * 5 bytes with it. The presence depends on the CS
+			 * role (initiator includes it, reflector does not).
+			 * Without role info, try 5 bytes if remaining data
+			 * aligns exactly, otherwise default to 3 bytes.
 			 */
-			if (step_idx == num_steps - 1 && frame->size == 5) {
-				/* Initiator - last step with exactly 5 bytes */
+			if (frame->size >= 5 &&
+					frame->size % 5 == 0 &&
+					frame->size / 5 ==
+					(size_t)(num_steps - step_idx)) {
 				step_data_len = 5;
 			} else if (frame->size >= 3) {
-				/* Reflector - default case */
 				step_data_len = 3;
 			} else {
 				print_text(COLOR_ERROR,
@@ -4742,7 +4656,7 @@ static void  print_ranging_steps(const struct l2cap_frame *frame,
 static void ras_ranging_data_read(const struct l2cap_frame *frame)
 {
 	uint8_t seg_header;
-	bool first_segment = true;
+	bool first_segment = false;
 
 	if (!l2cap_frame_get_u8((void *)frame, &seg_header)) {
 		print_text(COLOR_ERROR, "  Segmentation Header: invalid size");
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH] Bluetooth: btmtk: accept too short WMT FUNC_CTRL events
From: Pauli Virtanen @ 2026-05-08 19:09 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth, Mikhail Gavrilov
In-Reply-To: <CABBYNZ+jM+2BQ4Fek87OCKbyvuxjsyeCG0qpGRkAO4LA=pj4xw@mail.gmail.com>

Hi Luiz,

pe, 2026-04-24 kello 15:38 -0400, Luiz Augusto von Dentz kirjoitti:
> Hi Pauli, Tristan,
> 
> On Fri, Apr 24, 2026 at 3:25 PM Pauli Virtanen <pav@iki.fi> wrote:
> > 
> > MT7925 (USB ID 0e8d:e025) on fw version 20260106153314 sends WMT
> > FUNC_CTRL events that are missing the status field.
> > 
> > Prior to commit 006b9943b982 ("Bluetooth: btmtk: validate WMT event SKB
> > length before struct access") the status was read from out-of-bounds of
> > SKB data, which usually would result to success with
> > BTMTK_WMT_ON_UNDONE, although I don't know the intent here.  The bounds
> > check added in that commit returns with error instead, producing
> > "Bluetooth: hci0: Failed to send wmt func ctrl (-22)" and makes the
> > device unusable.
> > 
> > Fix the regression by interpreting too short packet as status
> > BTMTK_WMT_ON_UNDONE, which makes the device work normally again.
> > 
> > Fixes: 006b9943b982 ("Bluetooth: btmtk: validate WMT event SKB length before struct access")
> > Signed-off-by: Pauli Virtanen <pav@iki.fi>
> > ---
> > 
> > Notes:
> >     AFAICS the commit is not yet pulled and is only in bluetooth-next, so
> >     maybe this should be just fixup?
> 
> Yeah, I'll most likely fix it in place and add your Signed-off-by.

Looks like this got pulled to net without this fix, so it's broken now

> 
> >  drivers/bluetooth/btmtk.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
> > index ab34f1dd42bc..68a32d11e5ec 100644
> > --- a/drivers/bluetooth/btmtk.c
> > +++ b/drivers/bluetooth/btmtk.c
> > @@ -719,8 +719,8 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
> >         case BTMTK_WMT_FUNC_CTRL:
> >                 if (!skb_pull_data(data->evt_skb,
> >                                    sizeof(wmt_evt_funcc->status))) {
> > -                       err = -EINVAL;
> > -                       goto err_free_skb;
> > +                       status = BTMTK_WMT_ON_UNDONE;
> > +                       break;
> 
> This probably means the original change was never tested on real
> hardware. We likely need input from the MediaTek team on how to handle
> these events, as I don't think a public spec exists.
> 
> >                 }
> > 
> >                 wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
> > --
> > 2.53.0
> > 
> 

-- 
Pauli Virtanen

^ permalink raw reply

* Re: [PATCH v4] Bluetooth: serialize accept_q access
From: patchwork-bot+bluetooth @ 2026-05-08 19:00 UTC (permalink / raw)
  To: Ren Wei
  Cc: linux-bluetooth, netdev, marcel, luiz.dentz, davem, edumazet,
	kuba, pabeni, horms, jannh, yuantan098, yifanwucs, tomapufckgml,
	bird, wangjiexun2025
In-Reply-To: <20260506114338.2873496-1-n05ec@lzu.edu.cn>

Hello:

This patch was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Wed,  6 May 2026 19:43:30 +0800 you wrote:
> From: Jiexun Wang <wangjiexun2025@gmail.com>
> 
> bt_sock_poll() walks the accept queue without synchronization, while
> child teardown can unlink the same socket and drop its last reference.
> The unsynchronized accept queue walk has existed since the initial
> Bluetooth import.
> 
> [...]

Here is the summary with links:
  - [v4] Bluetooth: serialize accept_q access
    https://git.kernel.org/bluetooth/bluetooth-next/c/303bd23ee2e9

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* RE: Bluetooth: btmtk: handle FUNC_CTRL events without status field
From: bluez.test.bot @ 2026-05-08 18:47 UTC (permalink / raw)
  To: linux-bluetooth, mikhail.v.gavrilov
In-Reply-To: <20260508173121.27526-1-mikhail.v.gavrilov@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 882 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=1091757

---Test result---

Test Summary:
CheckPatch                    PASS      0.77 seconds
GitLint                       PASS      0.35 seconds
SubjectPrefix                 PASS      0.13 seconds
BuildKernel                   PASS      24.70 seconds
CheckAllWarning               PASS      27.71 seconds
CheckSparse                   PASS      26.44 seconds
BuildKernel32                 PASS      24.94 seconds
TestRunnerSetup               PASS      529.49 seconds
IncrementalBuild              PASS      26.83 seconds



https://github.com/bluez/bluetooth-next/pull/157

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [PATCH] Bluetooth: btmtk: handle FUNC_CTRL events without status field
From: Mikhail Gavrilov @ 2026-05-08 17:31 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Johan Hedberg, Tristan Madani, linux-bluetooth, linux-kernel,
	stable, Mikhail Gavrilov

A WMT FUNC_CTRL response shorter than struct btmtk_hci_wmt_evt_funcc
(9 bytes; WMT header plus a 2-byte big-endian status) makes
btmtk_usb_hci_wmt_sync() fail with -EINVAL.  This regresses Bluetooth
initialization on MediaTek MT7922 (e.g. USB id 0489:e0e2; reproduced
with firmware 0x008a008a, build 20260224103448): the FUNC_CTRL response
from the controller is 7 bytes long and the second skb_pull_data() in
the FUNC_CTRL case returns NULL, aborting setup:

  Bluetooth: hci0: HW/SW Version: 0x008a008a, Build Time: 20260224103448
  Bluetooth: hci0: Failed to send wmt func ctrl (-22)

Reverting the offending commit on top of v7.1-rc2 restores Bluetooth
on the affected hardware.

The pre-existing code dereferenced wmt_evt_funcc->status out of the
SKB tailroom in this case -- the original out-of-bounds read that the
offending commit correctly closes.  The byte pair read OOB almost
never matched 0x404 (ON_DONE) or 0x420 (ON_PROGRESS), so the else
branch ran and the caller observed BTMTK_WMT_ON_UNDONE.  That value
lets btmtk_usb_setup() proceed: for func_query it means "not yet
enabled, issue enable", and for the enable command it means "treat
as not done", both of which keep setup advancing rather than aborting
it.

Preserve that effective behaviour explicitly: when the status field
is absent, set status to BTMTK_WMT_ON_UNDONE instead of failing.
The OOB read remains closed, since skb_pull_data() still validates
the length before any further access.

Fixes: 634a4408c061 ("Bluetooth: btmtk: validate WMT event SKB length before struct access")
Cc: stable@vger.kernel.org
Cc: Tristan Madani <tristan@talencesecurity.com>
Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> # MT7922 (0489:e0e2)
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
---
 drivers/bluetooth/btmtk.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index f70c1b0f8990..fb4875760164 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -719,8 +719,10 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
 	case BTMTK_WMT_FUNC_CTRL:
 		if (!skb_pull_data(data->evt_skb,
 				   sizeof(wmt_evt_funcc->status))) {
-			err = -EINVAL;
-			goto err_free_skb;
+			bt_dev_dbg(hdev,
+				   "FUNC_CTRL event without status, assuming UNDONE");
+			status = BTMTK_WMT_ON_UNDONE;
+			break;
 		}
 
 		wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
-- 
2.54.0


^ permalink raw reply related


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