summaryrefslogtreecommitdiff
path: root/include/net/bluetooth
AgeCommit message (Collapse)Author
7 daysMerge branch 'bluetooth' into bluetooth-nextLuiz Augusto von Dentz
7 daysBluetooth: Add missing newline to bt_dev_{err,warn}_ratelimited()Hitalo Souza
bt_dev_err_ratelimited() and bt_dev_warn_ratelimited() pass the format string to bt_err_ratelimited()/bt_warn_ratelimited() without appending a newline, unlike bt_dev_err() and bt_dev_warn(), which go through BT_ERR()/BT_WARN() and add one. Only 2 of the 22 in-tree callers (both in virtio_bt) put the newline in their own format string. A printk record without a trailing newline is stored with prb_commit() instead of prb_final_commit(), and readers of the log buffer (/dev/kmsg, syslog) do not see it until it is finalized, which only happens when the next record is reserved. These messages therefore stay invisible until some unrelated message is printed, and journald, which timestamps a record when it reads it, logs them with the time of that later message. This was observed with a MediaTek MT7921 controller (USB 04ca:3802): when an eSCO link is closed, the host still receives a few SCO packets for the handle after Disconnection Complete, so hci_scodata_packet() logs "SCO packet for unknown connection handle". Comparing the record's kernel timestamp (_SOURCE_MONOTONIC_TIMESTAMP) with the time journald received it, over one capture: emitted logged delay 15:36:52.896 15:37:00.214 7.3 s 15:37:03.410 15:39:05.574 122.2 s 15:39:05.574 15:39:12.506 6.9 s 15:39:19.791 15:40:54.109 94.3 s 15:41:22.021 15:41:24.647 2.6 s Each message showed up together with the next kernel message; the 94 s one looked as if it had been logged in the middle of a later, healthy eSCO connection. bt_dev_err_ratelimited() lost its newline in commit 657cc646475b ("Bluetooth: Remove usage of BT_ERR_RATELIMITED macro"), which replaced BT_ERR_RATELIMITED(), the variant that appended "\n", with a direct call to bt_err_ratelimited(). bt_dev_warn_ratelimited() never had one. Append the newline in both macros, as BT_ERR() and BT_WARN() do, and drop it from the two virtio_bt format strings so that their messages do not gain an empty line. Fixes: 36278a5d4d35 ("Bluetooth: Adding a bt_dev_warn_ratelimited macro.") Fixes: 657cc646475b ("Bluetooth: Remove usage of BT_ERR_RATELIMITED macro") Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Hitalo Souza <enghitalo@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
8 daysMerge branch 'bluetooth' into bluetooth-nextLuiz Augusto von Dentz
8 daysBluetooth: MGMT: Fix advertising instances with Global AdvertisingLuiz Augusto von Dentz
Global Advertising, enabled with MGMT_OP_SET_ADVERTISING, uses instance 0 and with extended advertising it has its own advertising set, but instances were still being treated as if they shared the same set: - Add Advertising and Add Extended Advertising Data would return success without ever enabling the instance. - Removing the last instance would disable all advertising sets, stopping Global Advertising while leaving its setting enabled. - Disabling Global Advertising would disable all sets, including active instances. Fix this by only overriding instances that share the advertising set of Global Advertising, and by tracking HCI_LE_ADV_0 rather than HCI_LE_ADV to determine the state of Global Advertising. Fixes: 0d92808024b4 ("Bluetooth: HCI: Fix tracking of advertisement set/instance 0x00") Assisted-by: OpenCode:claude-opus-5.5 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
8 daysBluetooth: make hdev->adv_instance_timeout a booleanPauli Virtanen
Mesh uses millisecond time units for advertisements instead of seconds as normally. These values go to hdev->adv_instance_timeout, which then has mixed units. hdev->adv_instance_timeout is however only used as a true/false flag. Make hdev->adv_instance_timeout boolean flag, to avoid possible future problems with its mixed-units values. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
13 daysBluetooth: MGMT: Add management security level changed eventFrédéric Danis
Add an event on device security level or encryption type change to let user space know which level is currently in use. Reset security level to 0 on disconnection so further connections will correctly report security level changes. This will be used for BlueZ qualification automation. Assisted-by: GPT:GPT-5.3-Codex Assisted-by: Copilot:claude-sonnet-5 Signed-off-by: Frédéric Danis <frederic.danis@collabora.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-29Merge branch 'bluetooth' into bluetooth-nextLuiz Augusto von Dentz
2026-09-29Bluetooth: RFCOMM: connect the session socket without rfcomm_mutexMikhail Gavrilov
An RFCOMM connect() issued while a BR/EDR link is being authenticated makes lockdep report a circular dependency, and the reported cycle is a real AB/BA between rfcomm_mutex and hdev->lock. rfcomm_security_cfm() is called from the HCI event path, which already holds hdev->lock: hci_rx_work() hci_event_packet() hci_cc_read_enc_key_size() [hdev->lock] hci_encrypt_cfm() [hci_cb_list_lock] rfcomm_security_cfm() [rfcomm_mutex] while an RFCOMM connect() from userspace takes the same two locks the other way round: rfcomm_sock_connect() rfcomm_dlc_open() [rfcomm_mutex] __rfcomm_dlc_open() rfcomm_session_create() kernel_connect() l2cap_sock_connect() l2cap_chan_connect() [hdev->lock] WARNING: possible circular locking dependency detected kworker/u131:1/1128 is trying to acquire lock: rfcomm_mutex, at: rfcomm_security_cfm+0x31/0x3e0 [rfcomm] but task is already holding lock: hci_cb_list_lock, at: hci_cc_read_enc_key_size+0x1d2/0xcc0 Chain exists of: rfcomm_mutex --> &hdev->lock --> hci_cb_list_lock hci_auth_complete_evt() and hci_encrypt_change_evt() reach the callback the same way. Both orders have to be seen in the same boot, which is why a BR/EDR connection alone is not enough to show it: a session set up by the remote side is created by rfcomm_accept_connection() in krfcommd, which calls kernel_accept() and never takes hdev->lock under rfcomm_mutex. Connecting a device that authenticates and encrypts the link and then calling connect() on an RFCOMM socket towards any address - the connect does not have to succeed, the order is recorded before the page timeout - reports it every time. Only the session socket has to be connected with the lock held, and it does not: nothing else can see the socket before it is put on the session list. So connect it first and take rfcomm_mutex afterwards, which removes the rfcomm_mutex -> hdev->lock order for good, rather than keeping the HCI event path out of rfcomm_mutex. rfcomm_session_create() becomes rfcomm_session_connect(), which returns the connected socket without touching the session list, and rfcomm_dlc_open() adds the session once it holds the lock again. If another opener added a session for the same pair while this socket was connecting, that session is used and this socket is dropped. __rfcomm_dlc_open() now takes the session it should use, and its state check runs after the lock is re-acquired, so a DLC that was opened or closed in the meantime is still handled. Over an existing ACL link the connection can complete before the session reaches the list, and the wakeup from the socket callback is then lost, so krfcommd is woken once the session is visible. Connecting without the lock opens a window in which the socket can be closed. The DLC is not on a session yet, so rfcomm_dlc_close() finds nothing to do and returns without touching it, and rfcomm_dlc_open() would then attach a DLC whose owner is gone. rfcomm_dlc_close() now marks such a DLC with RFCOMM_CLOSED, and rfcomm_dlc_open() checks the mark once it holds rfcomm_mutex again and drops the socket instead of attaching the DLC. The mark is cleared when an open starts, so a DLC that is reused is not affected. This covers both callers of rfcomm_dlc_open(), the socket and the tty layer. Fixes: 759c185d0bbd ("Bluetooth: RFCOMM: serialize security confirmation handling") Suggested-by: Pauli Virtanen <pav@iki.fi> Reported-by: Pauli Virtanen <pav@iki.fi> Closes: https://lore.kernel.org/linux-bluetooth/5e76a95e934e451e7006db28827c2d64af5a88be.camel@iki.fi/ Reported-by: syzbot+74071deb72339c215b2e@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-bluetooth/6a92fadc.08e933ee.dbf97.008f.GAE@google.com/ Reported-by: Jiaming Zhang <r772577952@gmail.com> Closes: https://lore.kernel.org/all/CANypQFabseTuRiyz2pGkc_Qj0moGDnY7KEp1qdTOqkw6gAL3hw@mail.gmail.com/ Cc: stable@vger.kernel.org Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> Tested-by: syzbot+74071deb72339c215b2e@syzkaller.appspotmail.com Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-28Merge branch 'bluetooth' into bluetooth-nextLuiz Augusto von Dentz
2026-09-28Merge branch 'bluetooth' into bluetooth-nextLuiz Augusto von Dentz
2026-09-28Bluetooth: Serialize SMP remote OOB data accessChengfeng Ye
build_pairing_cmd() looks up remote OOB data and copies its contents without holding hdev->lock, which serializes the list's writers. After SMP finds an entry, a concurrent management Remove Remote OOB Data command can unlink and free it before SMP reads its present flag or copies its random and confirmation values. Removal can also invalidate an entry while the lookup is still traversing the list. KASAN reported: BUG: KASAN: slab-use-after-free in build_pairing_cmd+0x948/0x9b0 Call Trace: build_pairing_cmd+0x948/0x9b0 smp_recv_cb+0x459f/0x8110 l2cap_recv_frame+0xf14/0x9190 l2cap_recv_acldata+0xa64/0xd40 hci_rx_work+0x4ca/0x730 Allocated by task 87: hci_add_remote_oob_data+0x11d/0x530 add_remote_oob_data+0x282/0x400 hci_sock_sendmsg+0x1033/0x1ea0 Freed by task 93: hci_remote_oob_data_clear+0x108/0x1c0 remove_remote_oob_data+0x198/0x220 hci_sock_sendmsg+0x1033/0x1ea0 Taking hdev->lock in build_pairing_cmd() would recurse for callers that already hold it and invert the device-to-L2CAP lock order on the receive path. Add a per-device remote_oob_lock instead, held across the SMP lookup and copies and by the add, remove and clear helpers. Cover initialization and in-place updates as well, so SMP cannot read partially initialized or updated OOB values. Release the mutex on allocation failure, preserving the existing error return. The new critical sections acquire no device, connection or channel locks. Writers retain their existing hdev->lock protection, which continues to serialize the other readers without changing their locking or behavior. Link: https://lore.kernel.org/r/00660cd3-7d71-13a4-f617-229e6defb701@gmail.com Fixes: 02b05bd8b0a6 ("Bluetooth: Set SMP OOB flag if OOB data is available") Cc: stable@vger.kernel.org Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-23Bluetooth: hci_core: Fix inquiry cache timestamps on 64-bit systemsLinmao Li
On 64-bit systems, outgoing BR/EDR connections always fall back to page scan repetition mode R2 with no clock offset once the system has been up for more than five minutes, even when inquiry found the peer only seconds earlier. This lengthens paging and can increase the risk of a Page Timeout. The inquiry cache stores jiffies in __u32 timestamps, but its age helpers subtract them from unsigned long jiffies. INITIAL_JIFFIES casts -300 * HZ through unsigned int, so jiffies crosses 2^32 five minutes after boot on 64-bit systems. Assigning it to __u32 then drops the upper 32 bits. In one trace, a 7.6-second-old entry (HZ=1000) was reported as 2^32 + 7620 ticks old and rejected by hci_acl_create_conn_sync(). hci_inquiry() is affected by the same truncation when checking the whole cache. 32-bit systems are unaffected because unsigned long is 32 bits wide there. Use unsigned long for both timestamps so they have the same width as jiffies on 32-bit and 64-bit systems, and update the debugfs format specifier accordingly. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Linmao Li <lilinmao@kylinos.cn> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: Add generic support for vendor packetsZijun Hu
The virtual HCI_VENDOR_PKT (0xff) has been defined but never used by the BT core. Now, there is a requirement to implement it, as follows: For Qualcomm multi-subsystem BT chips, the transport wire carries both BT-HCI and PERI-HCI packets, where PERI is a subsystem in the chip, take the upcoming QCC2072 as an example: Packet type BT-HCI indicator PERI-HCI indicator ----------------------------------------------------------------- CMD (Host -> Controller) 0x01 0x31 ACL Data (bidirectional) 0x02 0x32 EVENT (Controller -> Host) 0x04 0x34 There are also BT ACL packets with vendor-reserved handles found in existing device drivers, as shown below: +--------+--------+---------------------------+ | Vendor | Handle | Purpose | +--------+--------+---------------------------+ | QCOM | 0xEDD | Firmware coredump | | | 0xEDC | Firmware enhanced logging | +--------+--------+---------------------------+ | MTK | 0xFC6F | Firmware coredump | | | 0x05FF | Firmware debug logging 1 | | | 0x05FE | Firmware debug logging 2 | +--------+--------+---------------------------+ | NXP | 0xFFF | Firmware coredump | +--------+--------+---------------------------+ Implement HCI_VENDOR_PKT to generically support such vendor packets, which don't follow BT SIG's vendor-extension framework: - Log them in btmon as they appear on the wire. - Add hdev->recv_vendor_pkt() to handle them in hci_rx_work(). - Add hci_send_vendor_frame() to send them to the device driver. - Allow them to flow over HCI_CHANNEL_USER, nested inside HCI_VENDOR_PKT. Also solve the same issues that the commit below fixes for HCI_EV_VENDOR, which follows BT SIG's vendor-extension framework: commit 0bd606b31d40 ("Bluetooth: hci_event: Introduce handle_ev_vendor() for HCI_EV_VENDOR") Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: Move H:4 reassembly into the Bluetooth coreLuiz Augusto von Dentz
h4_recv_buf() is currently implemented in hci_h4.c which is only built as part of the hci_uart module, and only when CONFIG_BT_HCIUART_H4 is enabled. That makes the H:4 reassembly logic unusable by drivers which do not depend on hci_uart, e.g. btusb which needs it to implement Bulk Serialization Mode. Move the transport agnostic part into the Bluetooth core as h4_recv_skb(), which takes a struct hci_dev instead of a struct hci_uart, along with struct h4_recv_pkt and the H4_RECV_* helpers, and keep h4_recv_buf() as a thin wrapper for the hci_uart protocols. Since every Bluetooth driver already depends on the bluetooth module this introduces no new module dependency and no new Kconfig symbol. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: L2CAP: annotate locking for l2cap_ops callbacksPauli Virtanen
Annotate current locking context for l2cap_ops callbacks. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: L2CAP: annotate locking for l2cap_chan_del()Pauli Virtanen
Add context analysis annotations for chan->lock and chan->conn->lock involving l2cap_chan_del() usage. Add necessary annotations and related lockdep_assert_held to callers. Move struct l2cap_ops definition after struct l2cap_conn, so that the callbacks can be annotated. In l2cap_chan_close_unlocked() we consider chan->conn->lock as locked even if chan->conn == NULL, to avoid needing to define separate __l2cap_chan_close/del for this NULL case. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: L2CAP: take lock for l2cap_chan_del in l2cap_ecred_rsp_deferPauli Virtanen
l2cap_ecred_rsp_defer() calls l2cap_chan_del without holding chan->lock, which ends up calling ops->teardown() with wrong lock context. Fix by taking chan->lock in l2cap_ecred_rsp_defer(). AB-BA deadlocks between sibling l2cap_chan are avoided here via requiring l2cap_conn::lock to serialize all nested l2cap_chan locking on same nesting level. In current code, there is no nested l2cap_chan locking on same nesting level, so we can add this new requirement. Also return early from __l2cap_ecred_conn_rsp_defer() if chan did not have FLAG_DEFER_SETUP, as then no RSP shall be sent for it, to make sure SMP channels are excluded. Also hold chan reference over l2cap_chan_del(), in case chan_l reference was the last. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: L2CAP: make concurrent l2cap_set_timer() refcounting safePauli Virtanen
Since l2cap_set_timer() does not check return value of schedule_delayed_work(), two concurrent calls may result to l2cap_chan refcount leak. Change the refcounting by using mod_delayed_work() and checking its return value. Code paths aside from l2cap_chan_busy() hold chan->lock, so this has little correctness impact. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: L2CAP: add annotations for l2cap_chan list lockingPauli Virtanen
Add context analysis annotations for l2cap_conn::chan_l and chan_list locking. Add corresponding required annotations to accessors and callers. This is not complete chan_l annotation, l2cap_chan::list and l2cap_chan_del() locking is currently not fully correct, and needs separate fix + annotations. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: L2CAP: remove unused l2cap_chan_close()Pauli Virtanen
l2cap_chan_close() is now unused, and l2cap_chan_close_unlocked() should be used instead. Remove l2cap_chan_close(). Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: L2CAP: add l2cap_chan_close_unlocked() and locking helpersPauli Virtanen
l2cap_chan_close() requires holding chan->lock and chan->conn->lock if associated chan->conn exists, to guard eg. conn->chan_l. Taking the locks with right ordering requires handling a race condition. Add helper function l2cap_chan_(un)lock_conn that do the locking right. Add l2cap_chan_close_unlocked() that does not require locks to be held, as all callsites do this lock -> close -> unlock pattern. Link: https://syzkaller.appspot.com/bug?extid=0e4ebcc970728e056324 Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: L2CAP: take chan->lock for l2cap_chan_add/ready/delPauli Virtanen
chan->lock must be held for __l2cap_chan_add as eg. calls to l2cap_chan_close assume chan->conn writes are guarded by it. It must be held for l2cap_chan_del() due to l2cap_sock.c:l2cap_chan_conn, l2cap_monitor_timeout, etc. Similarly it should be held for l2cap_ops::ready (assumed in 6lowpan.c). Also teardown usually has chan->lock held, it should always have it held to have the same locking context. The lock is not correctly held by l2cap_core in several places. Add the missing locks for l2cap_chan_del/add/ready(), except in l2cap_ecred_rsp_defer() which needs separate fix as it needs lock nesting. Fixes: 6fef032af009 ("Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()") Signed-off-by: Pauli Virtanen <pav@iki.fi> Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr> Reported-by: Jaeyoung Chung <jjy600901@snu.ac.kr> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: L2CAP: add locking annotations for l2cap_chan_lock/unlockPauli Virtanen
Add minimal context analysis annotations to l2cap_chan_lock/unlock() and callers required for no warnings. Reviewed-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: hci_core: add lockdep check to hci_conn lookupsPauli Virtanen
Add lockdep check for RCU || hdev->lock in hci_conn_hash lookups that return hci_conn pointer, as dereferencing that without locks can be TOCTOU issue. It used to be several callsites did not hold appropriate locks. The check is equivalent to removing rcu_read_lock() and doing instead list_for_each_entry_rcu(c, &h->list, list, lockdep_is_held(&hdev->lock)) Although there should not be any remaining callsites without locks, don't remove the rcu_read_lock() for now, and just add the warning here. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-15Bluetooth: coredump: Quiesce dump work on unregisterWeiming Shi
hci_devcd_handle_pkt_init() arms dump_timeout and coredump producers queue dump_rx without holding an hdev reference. Unregister leaves both works live, so disconnecting during an active dump lets them access hdev after hci_release_dev() frees it. Shut down coredump processing during unregister. Close the producer gate under dump_q.lock before disabling both works, then free the active buffer and queued packets under hci_dev_lock. Serializing the gate with enqueue prevents controller-specific workers from adding packets after the final purge. Fixes: 9695ef876fd1 ("Bluetooth: Add support for hci devcoredump") Reported-by: syzbot+b170dbf55520ebf5969a@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=b170dbf55520ebf5969a Reported-by: Aby Sam Ross <abysamross@gmail.com> Link: https://lore.kernel.org/r/20260322210849.68743-1-abysamross@gmail.com Suggested-by: Aby Sam Ross <abysamross@gmail.com> Reported-by: Tristan Madani <tristan@talencesecurity.com> Link: https://lore.kernel.org/r/20260814231248.3096377-1-tristmd@gmail.com Reported-by: Xiang Mei <xmei5@asu.edu> Assisted-by: OpenAI Codex:gpt-5 Signed-off-by: Weiming Shi <bestswngs@gmail.com> Reported-by: Xiang Mei <xmei5@asu.edu> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-24Bluetooth: L2CAP: fix race l2cap_sock_cleanup_listen() vs. put_chanPauli Virtanen
For L2CAP sockets without owning sk->sk_socket, reading l2cap_pi(sk)->chan may race against concurrent l2cap_sock_kill() -> l2cap_sock_put_chan(). This excludes simultaneous proto_ops callbacks, but access in l2cap_sock_cleanup_listen() has unsafe lockless read. [Task 1] [Task 2 (hdev->workqueue)] l2cap_sock_release(parent) l2cap_disconn_cfm l2cap_sock_cleanup_listen l2cap_conn_del bt_accept_dequeue l2cap_chan_del lock_sock(sk) l2cap_sock_teardown_cb bt_accept_unlink bt_sk(sk)->parent = NULL release_sock(sk) ----------------> lock_sock(sk) parent = /* NULL */ lock_sock(sk) <--------------------- release_sock(sk) sock_set_flag(sk, SOCK_ZAPPED) l2cap_sock_close_cb l2cap_sock_kill(sk) l2cap_sock_put_chan chan = READ l2cap_pi(sk)->chan l2cap_pi(sk)->chan = NULL l2cap_chan_hold_unless_zero l2cap_put_chan(chan) kref_get_unless_zero(&chan->ref) Task 1 may observe NULL which causes null-ptr-deref. Fix the race by taking lock_sock() in l2cap_sock_kill() to synchronize with l2cap_sock_cleanup_listen(). hold_unless_zero() is not needed here, l2cap_pi(sk)->chan owns reference if it is non-NULL. Clarify code comments vs. locking. Fixes: 6fef032af009 ("Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()") Reported-by: syzbot+e6382a2f53f5fc7453ac@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=e6382a2f53f5fc7453ac Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-24Bluetooth: mgmt: fix 'hdev->discovery.uuids' NULL dereferencePavel Shpakovskiy
'uuid_count' member of struct 'discovery_state' is assigned and read without any locks, so there is a chance of situation when uuid_count != 0, but uuids is NULL and there will be NULL pointer dereference. Possible race: 'hci_update_passive_scan_sync' 'hci_discovery_filter_clear' hdev->discovery.uuid_count = 0; <----------------------preempted-----------------------------> 'start_service_discovery' // Set uuid_count to value != 0 hdev->discovery.uuid_count = uuid_count; hdev->discovery.uuids = kmemdup(...); <----------------------preempted-----------------------------> spin_lock(&hdev->discovery.lock); kfree(hdev->discovery.uuids); hdev->discovery.uuids = NULL; spin_unlock(&hdev->discovery.lock); Now uuids == NULL and uuid_count != 0. So 'mgmt_device_found' -> 'is_filter_match' -> 'eir_has_uuids' receives non consistent discovery state, where NULL dereference of uuids happens. To fix it let's add discovery.lock around every read/write of uuid_count, uuids pair of struct members. It is also important to assign uuid_count value only after success kmemdup() allocation in start_service_discovery(), otherwise uuids is NULL, because kmemdup failed, but uuid_count is already assigned to non zero value. The following panic happens: [ ] ------------[ cut here ]------------ [ ] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 [ ] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP [ ] CPU: 0 PID: 15056 Comm: kworker/u9:2 [ ] Workqueue: hci0 hci_rx_work [ ] pstate: 10400009 (nzcV daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ ] pc : eir_has_uuids+0x2d8/0x590 [ ] lr : is_filter_match+0x258/0x320 ... [ ] Call trace: [ ] eir_has_uuids+0x2d8/0x590 [ ] is_filter_match+0x258/0x320 [ ] mgmt_device_found+0x5b0/0xafc [ ] process_adv_report.part.0+0x8c8/0xf14 [ ] hci_le_adv_report_evt+0x338/0x3f0 [ ] hci_le_meta_evt+0x1f0/0x4c8 [ ] hci_event_packet+0x440/0xc9c [ ] hci_rx_work+0x44c/0xaf8 [ ] process_one_work+0x54c/0x103c [ ] worker_thread+0x6c4/0x10c4 [ ] kthread+0x274/0x2ec [ ] ret_from_fork+0x10/0x20 [ ] Code: 14000004 91004021 eb14003f 54000180 (f9400024) [ ] ---[ end trace 0000000000000000 ]--- Fixes: 2935e556850e ("Bluetooth: hci_sync: fix double free in 'hci_discovery_filter_clear()'") Signed-off-by: Pavel Shpakovskiy <pashpakovskii@salutedevices.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: hci_event: Use 255 as max event payload length in hci_ev_table[]Zijun Hu
hci_event_func() validates skb->len against ev->max_len from the entry in hci_ev_table[]. By then, the header has already been stripped by skb_pull(). So the max event payload is 255, but hci_ev_table[] still uses HCI_MAX_EVENT_SIZE (260) for it, which is imprecise. Fix by introducing HCI_MAX_EVENT_PLEN (255) and using it instead. Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: hci_event: Introduce handle_ev_vendor() for HCI_EV_VENDORZijun Hu
Introduce the hook to solve issues below: msft_vendor_evt(), the current handler for all VSEs, is unsuitable since: - many VSEs are not MSFT ones; - it always corrupts the non-MSFT VSEs by calling skb_pull_data() once the MSFT extension is enabled. Several issues are caused by many transport drivers pre-processing VSEs in their RX path, often an IRQ-disabled atomic context. Take the two typical cases below as examples: Case 1: // no btmon log, no way to reach userspace Step 1: handle and free @original_skb directly Case 2: // hurts performance and consumes GFP_ATOMIC memory Step 1: cloned_skb = skb_clone(original_skb, GFP_ATOMIC); // the VSE is handled here Step 2: handle and free @cloned_skb Step 3: hci_recv_frame(hdev, original_skb); // already handled, but re-enters the stack's event-handling path Step 4: hci_event_packet(hdev, original_skb); Fix by introducing the hook with usage: 1) the transport driver registers the hook for VSEs of interest; 2) the stack calls it in process context, handling the VSE like any other event: - if interested, handle the VSE - no need to free it - and return true; - otherwise return false. Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: hci_core: Introduce __hci_reset_dev() with a hardware error codeZijun Hu
hci_reset_dev() injects a constant hardware error code 0x00 to restart the device. But a transport driver may need a different error code. Fix by introducing __hci_reset_dev(hdev, hw_err_code), which will be used by a follow-up patch. Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: coredump: Expose header size and end marker to driversZijun Hu
To separate the coredump header and data far more easily, give a vendor driver the option to pad its header to a fixed size, by moving the header size limit and ending marker to coredump.h: - HCI_DEVCD_HDR_SIZE_MAX: the max header size - HCI_DEVCD_HDR_END_MARKER: the header-ending marker Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: add annotations for l2cap_data locking contextPauli Virtanen
Add context analysis annotations for hci_conn::l2cap_data locking. Also add necessary lockdep_assert_held() and __must_hold annotations to prove the access is safe. The access in smp_conn_security() is supposed to be guarded by the caller holding lock that blocks concurrent l2cap_conn_del() eg. hdev->lock, conn->lock or chan->lock. Mark unsafe as can't be automatically checked now. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: Add MGMT Load Connection Subrate commandLuiz Augusto von Dentz
Add MGMT_OP_LOAD_CONN_SUBRATE (0x005C) command to load per-device connection subrate parameters when the SCI feature is supported. Add MGMT_EV_CONN_SUBRATE (0x0033) event to notify userspace when connection rate changes occur via the LE Connection Rate Change HCI event. Add subrate fields (subrate_min, subrate_max, max_latency, cont_num) to struct hci_conn_params to store the loaded subrate parameters, and the corresponding le_rate_* fields to struct hci_conn to track the parameters currently in use. When a single entry is loaded for an already-connected central, or on connection completion, the LE Connection Rate Request procedure is initiated to apply the parameters. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: Add MGMT Shorter Connection Interval settingLuiz Augusto von Dentz
Add MGMT_SETTING_SCI (bit 25) to advertise support for the Shorter Connection Interval (SCI) feature. It is reported in the supported settings whenever the controller is SCI capable, and in the current settings whenever LE is enabled and the controller is SCI capable (SCI has no separate enable command, so it is a passive capability). Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: Add support for Shorter Connection Interval (SCI) featureLuiz Augusto von Dentz
Add HCI command, event and feature bit definitions for the Bluetooth 6.2 Shorter Connection Interval feature: Commands: - HCI_OP_LE_CONN_RATE (0x20a1) - Connection Rate Request - HCI_OP_LE_SET_DEF_RATE (0x20a2) - Set Default Rate Parameters - HCI_OP_LE_READ_CONN_INTERVAL (0x20a3) - Read Min Supported Connection Interval Events: - HCI_EVT_LE_CONN_RATE_CHANGE (0x37) - Connection Rate Change Feature bits: - HCI_LE_SCI - Shorter Connection Intervals - HCI_LE_SCI_HOST - Shorter Connection Intervals (Host Support) During controller init, when SCI is supported: - Set Shorter Connection Intervals (Host Support) feature via LE Set Host Feature - Read Minimum Supported Connection Interval - Set Default Rate Parameters The Connection Rate Change event handler updates the connection interval, latency and supervision timeout on the hci_conn. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: hci: Introduce hci_acl_handle() and hci_acl_dlen() helpersZijun Hu
Introduce both helpers for ACL packet since: both core and transport drivers extract the handle and data length from its header in several places. Both will be used later. Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: coredump: Introduce and apply hci_devcd_state_name()Zijun Hu
Introduce hci_devcd_state_name() to describe the devcoredump state by a string name instead of a plain number, for several reasons: 1) Applying it in coredump.c makes the devcoredump state in log messages more readable than a plain number. 2) Transport drivers may need to show the devcoredump state name too. 3) In future, the universal state name could be notified to userspace via uevent, allowing a universal application (e.g. a daemon) to be developed to save the coredump, which is otherwise discarded by the device coredump core after 5 minutes (DEVCD_TIMEOUT); see nxp_coredump_notify(). Also drop a trailing space from two bt_dev_dbg() format strings while applying it in coredump.c. Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: hci_sync: Introduce __hci_reset_sync() for device driversZijun Hu
Several vendor drivers have a requirement to send a synchronous raw HCI reset with HCI_INIT_TIMEOUT. Add a dedicated __hci_reset_sync() for them to use. Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-08-07Bluetooth: hci_sync: Remove unused hci_cmd_sync_dequeue_once()Siwei Zhang
hci_cmd_sync_dequeue_once() had a single in-tree caller, hci_cancel_connect_sync(), which now holds cmd_sync_work_lock across the in-flight create flag test and the dequeue and so open-codes the lookup and cancel under that lock. That leaves the exported hci_cmd_sync_dequeue_once() with no in-tree user, so remove it along with its declaration. Signed-off-by: Siwei Zhang <oss@fourdim.xyz> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-07-28Bluetooth: ISO: fix race of kfree vs kref_get_unless_zeroPauli Virtanen
hci_conn::iso_data is accessed and modified without lock or RCU. This leads to a race [Task hdev->workqueue] [Task 2] iso_recv iso_conn_put(conn) conn = LOAD hcon->iso_data iso_conn_free(conn) iso_conn_hold_unless_zero(conn) hcon->iso_data = NULL kfree(conn) kref_get_unless_zero(&conn->ref) /* UAF */ and also to races in iso_conn_add() vs. iso_conn_free(). Fix by adding spinlock hci_conn::proto_lock and using it to guard hci_conn::iso_data. Fixes: dc26097bdb86 ("Bluetooth: ISO: Use kref to track lifetime of iso_conn") Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-07-20Bluetooth: RFCOMM: Fix session UAF in set_termiosChengfeng Ye
rfcomm_tty_set_termios() tests dlc->session without rfcomm_mutex and later passes the pointer to rfcomm_send_rpn(). The latter dereferences both session->initiator and session->sock. Meanwhile, krfcommd can unlink the DLC and free the session while holding rfcomm_mutex. The race can proceed as follows: TTY ioctl task krfcommd -------------- -------- load dlc->session enter rfcomm_send_rpn() lock rfcomm_mutex clear dlc->session free session unlock rfcomm_mutex read session->initiator KASAN reported: BUG: KASAN: slab-use-after-free in rfcomm_send_rpn+0x297/0x2a0 Read of size 4 at addr ffff88810012a850 by task poc/92 Call Trace: rfcomm_send_rpn+0x297/0x2a0 rfcomm_tty_set_termios+0x50d/0x850 tty_set_termios+0x596/0x950 set_termios+0x46a/0x6e0 tty_mode_ioctl+0x152/0xbd0 tty_ioctl+0x915/0x1240 __x64_sys_ioctl+0x134/0x1c0 Allocated by task 92: rfcomm_session_add+0x9e/0x2e0 rfcomm_dlc_open+0x8b1/0xe00 rfcomm_dev_activate+0x85/0x1a0 rfcomm_tty_open+0x90/0x280 Freed by task 68: kfree+0x131/0x3c0 rfcomm_session_del+0x119/0x180 rfcomm_run+0x737/0x4710 Add rfcomm_dlc_send_rpn(), which holds rfcomm_mutex while it verifies that the DLC is still attached and sends the RPN frame. Have the TTY path use the helper and drop its unlocked session check. This keeps the session valid through both the frame construction and socket send. Fixes: 3a5e903c09ae ("[Bluetooth]: Implement RFCOMM remote port negotiation") Cc: stable@vger.kernel.org Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-07-13Bluetooth: mgmt: Translate HCI reason in Device Disconnected eventMikhail Gavrilov
MGMT_EV_DEVICE_DISCONNECTED carries a reason field which is defined to be one of MGMT_DEV_DISCONN_* (0x00..0x05). hci_disconn_complete_evt() converts the HCI error with hci_to_mgmt_reason(), but two other paths pass the raw HCI error straight through: hci_cs_disconnect() -> cp->reason mgmt_connect_failed() -> status The latter is reached whenever the adapter is powered off or suspended: hci_disconnect_all_sync() aborts every link with HCI_ERROR_REMOTE_POWER_OFF, hci_disconnect_sync() deliberately does not wait for HCI_EV_DISCONN_COMPLETE for that reason, so that hci_abort_conn_sync() finishes the connection off through hci_conn_failed() instead. As a result userspace sees an out of range reason: @ MGMT Event: Device Disconnected (0x000c) plen 8 BR/EDR Address: 8C:A9:6F:2C:51:46 Reason: Reserved (0x15) bluetoothd: btd_bearer_disconnected() Unknown disconnection value: 21 bluetoothd: device_disconnected() Unknown disconnection value: 21 Export hci_to_mgmt_reason() and use it in both places, so that a power off is reported as MGMT_DEV_DISCONN_REMOTE rather than as the raw HCI_ERROR_REMOTE_POWER_OFF (0x15). Fixes: d47da6bd4cfa ("Bluetooth: hci_core: Fix sending MGMT_EV_CONNECT_FAILED") Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier") Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-07-06Bluetooth: ISO: exclude RFU bits from ISO_SDU_LengthPauli Virtanen
slen contains ISO_SDU_Length (12 bits), RFU (2 bits), Packet_Status_Flags (2 bits). Exclude the RFU bits from hci_iso_data_len. Also add masks to the pack macro. Fixes: 4de0fc599eb9 ("Bluetooth: Add definitions for CIS connections") Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-07-06Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()Siwei Zhang
l2cap_sock_new_connection_cb() returned l2cap_pi(sk)->chan after release_sock(parent). Once the parent lock is dropped the newly enqueued child socket sk is reachable via the accept queue, so another task can accept and free it before the callback dereferences sk, resulting in a use-after-free. Rework the ->new_connection() op so the core, rather than the callback, owns the child channel's lifetime. The op now receives a pre-allocated new_chan and returns an errno instead of allocating and returning a channel. l2cap_new_connection() allocates the child channel and links it into the conn list via __l2cap_chan_add() before invoking the callback, so the conn-list reference keeps the channel alive once release_sock(parent) exposes the socket to other tasks. Channel configuration that was duplicated in l2cap_sock_init() and the various new_connection callbacks is consolidated into l2cap_chan_set_defaults(), which now inherits from the parent channel when one is supplied. Fixes: 8ffb929098a5 ("Bluetooth: Remove parent socket usage from l2cap_core.c") Cc: stable@kernel.org Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Siwei Zhang <oss@fourdim.xyz> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-07-06Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()Siwei Zhang
hci_abort_conn() read hci_skb_event(hdev->sent_cmd) when a connection was pending, but hdev->sent_cmd can be NULL while req_status is still HCI_REQ_PEND, leading to a NULL pointer dereference and a general protection fault from the hci_rx_work() receive path. Instead of inspecting hdev->sent_cmd, track the in-flight create connection command with a new per-connection HCI_CONN_CREATE flag and route all cancellation through hci_cancel_connect_sync(), which dispatches to a dedicated per-type cancel function. The create command is in exactly one of two states: still queued, or in flight. The cancel function holds cmd_sync_work_lock across the whole decision: the worker takes this lock to dequeue every entry, so while it is held a queued command cannot start running and an in-flight command cannot complete and let the next command become pending. This keeps the flag test and hci_cmd_sync_cancel() atomic with respect to the worker, so a queued command is simply dequeued, and an in-flight command owned by this connection is cancelled without the risk of cancelling an unrelated command that became pending in the meantime. CIS uses the same flag mechanism via HCI_CONN_CREATE_CIS but cannot be dequeued per-connection. hci_acl_create_conn_sync() and hci_le_create_conn_sync() clear HCI_CONN_CREATE after the create command completes, but the command status handler can free conn via hci_conn_del() (for example when the controller rejects the connection) while the worker is still blocked on the connection complete event. Hold a reference on conn across the create command so the flag can be cleared without a use-after-free. Fixes: a13f316e90fd ("Bluetooth: hci_conn: Consolidate code for aborting connections") Cc: stable@vger.kernel.org Suggested-by: XIAO WU <xiaowu.417@qq.com> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Siwei Zhang <oss@fourdim.xyz> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-11Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn refMarco Elver
l2cap_chan_timeout() runs asynchronously and accesses chan->conn. If the connection is torn down while the timer is running or pending, chan->conn can be freed, leading to a use-after-free when the timer worker attempts to lock conn->lock: | BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112 [inline] | BUG: KASAN: slab-use-after-free in atomic_long_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:4456 [inline] | BUG: KASAN: slab-use-after-free in __mutex_trylock_fast kernel/locking/mutex.c:161 [inline] | BUG: KASAN: slab-use-after-free in mutex_lock+0x4f/0xa0 kernel/locking/mutex.c:318 | Write of size 8 at addr ffff8881298d9550 by task kworker/2:1/83 | | CPU: 2 UID: 0 PID: 83 Comm: kworker/2:1 Not tainted 7.1.0-rc6-next-20260601-dirty #6 PREEMPT(full) | Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 | Workqueue: events l2cap_chan_timeout | Call Trace: | <TASK> | instrument_atomic_read_write include/linux/instrumented.h:112 [inline] | atomic_long_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:4456 [inline] | __mutex_trylock_fast kernel/locking/mutex.c:161 [inline] | mutex_lock+0x4f/0xa0 kernel/locking/mutex.c:318 | l2cap_chan_timeout+0x5d/0x1b0 net/bluetooth/l2cap_core.c:422 | process_one_work kernel/workqueue.c:3326 [inline] | process_scheduled_works+0x7c8/0xfb0 kernel/workqueue.c:3409 | worker_thread+0x8a9/0xcf0 kernel/workqueue.c:3490 | kthread+0x346/0x430 kernel/kthread.c:436 | ret_from_fork+0x1a3/0x470 arch/x86/kernel/process.c:158 | ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 | </TASK> | | Allocated by task 320: | l2cap_conn_add+0xa7/0x820 net/bluetooth/l2cap_core.c:7075 | l2cap_connect_cfm+0xdb/0xd70 net/bluetooth/l2cap_core.c:7452 | hci_connect_cfm include/net/bluetooth/hci_core.h:2139 [inline] | hci_remote_features_evt+0x52f/0x9f0 net/bluetooth/hci_event.c:3760 | hci_event_func net/bluetooth/hci_event.c:7796 [inline] | hci_event_packet+0x561/0xa70 net/bluetooth/hci_event.c:7847 | hci_rx_work+0x370/0x890 net/bluetooth/hci_core.c:4040 | process_one_work kernel/workqueue.c:3326 [inline] | process_scheduled_works+0x7c8/0xfb0 kernel/workqueue.c:3409 | worker_thread+0x8a9/0xcf0 kernel/workqueue.c:3490 | kthread+0x346/0x430 kernel/kthread.c:436 | ret_from_fork+0x1a3/0x470 arch/x86/kernel/process.c:158 | ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 | | Freed by task 322: | hci_disconn_cfm include/net/bluetooth/hci_core.h:2154 [inline] | hci_conn_hash_flush+0x101/0x1f0 net/bluetooth/hci_conn.c:2736 | hci_dev_close_sync+0x889/0xde0 net/bluetooth/hci_sync.c:5405 | hci_dev_do_close net/bluetooth/hci_core.c:502 [inline] | hci_unregister_dev+0x1f7/0x370 net/bluetooth/hci_core.c:2679 | vhci_release+0x12a/0x180 drivers/bluetooth/hci_vhci.c:690 | __fput+0x369/0x890 fs/file_table.c:510 | task_work_run+0x160/0x1d0 kernel/task_work.c:233 | get_signal+0xf5b/0x1120 kernel/signal.c:2810 | arch_do_signal_or_restart+0x4d/0x600 arch/x86/kernel/signal.c:337 | __exit_to_user_mode_loop kernel/entry/common.c:64 [inline] | exit_to_user_mode_loop+0x85/0x510 kernel/entry/common.c:98 | do_syscall_64+0x263/0x3d0 arch/x86/entry/syscall_64.c:100 | entry_SYSCALL_64_after_hwframe+0x77/0x7f | | The buggy address belongs to the object at ffff8881298d9400 | which belongs to the cache kmalloc-512 of size 512 | The buggy address is located 336 bytes inside of | freed 512-byte region [ffff8881298d9400, ffff8881298d9600) Fix it by having chan->conn hold a reference to l2cap_conn (via l2cap_conn_get) when the channel is added to the connection, and releasing it in the channel destructor. This ensures the l2cap_conn remains alive as long as the channel exists. A new FLAG_DEL channel flag is introduced to indicate that the channel has been deleted from its connection. l2cap_chan_del() atomically sets this flag using test_and_set_bit() instead of setting chan->conn to NULL. All asynchronous workers (l2cap_chan_timeout, l2cap_ack_timeout, l2cap_monitor_timeout, l2cap_retrans_timeout) and l2cap_chan_send() check FLAG_DEL to determine whether the channel has been torn down, rather than testing chan->conn for NULL. Fixes: 8c8e620467a7 ("Bluetooth: L2CAP: use chan timer to close channels in cleanup_listen()") Cc: <stable@vger.kernel.org> Cc: Siwei Zhang <oss@fourdim.xyz> Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Assisted-by: Gemini:gemini-3.1-pro-preview Reported-by: https://sashiko.dev/#/patchset/20260521021249.3258069-1-oss%40fourdim.xyz Signed-off-by: Marco Elver <elver@google.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-11Bluetooth: Add SPDX id lines to some source filesTim Bird
Many bluetooth source files are missing SPDX-License-Identifier lines. Add appropriate IDs to these files, and remove other license lines from the headers. Leave the warranty disclaimer in files where the license ID is GPL-2.0 but the wording of the disclaimer is slightly different from that of the GPL v2 disclaimer. It is not different enough to cause licensing conflicts, but is kept to honor the original contributors' legal intent. Signed-off-by: Tim Bird <tim.bird@sony.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-11Bluetooth: hci_sync: Add support for HCI_LE_Set_Host_Feature [v2]Luiz Augusto von Dentz
This adds support for using HCI_LE_Set_Host_Feature [v2] instead of v1 if LL Extented Features is supported and the controller supports the command. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: L2CAP: reject BR/EDR signaling packets over MTUsigMichael Bommarito
net/bluetooth/l2cap_core.c:l2cap_sig_channel() accepts BR/EDR signaling packets up to the channel MTU and dispatches each command without enforcing the signaling MTU (MTUsig). A Bluetooth BR/EDR peer within radio range can send a fixed-channel CID 0x0001 packet that is larger than MTUsig and contains many L2CAP_ECHO_REQ commands before pairing. In a real-radio stock-kernel run, one 681-byte signaling packet containing 168 zero-length ECHO_REQ commands made the target transmit 168 ECHO_RSP frames over about 220 ms. Impact: a Bluetooth BR/EDR peer within radio range, before pairing, can force 168 ECHO_RSP frames from one 681-byte fixed-channel signaling packet containing packed ECHO_REQ commands. Define Linux's BR/EDR signaling MTU as the spec minimum of 48 bytes and reject any larger signaling packet with one L2CAP_COMMAND_REJECT_RSP carrying L2CAP_REJ_MTU_EXCEEDED before any command is dispatched. The Bluetooth Core spec wording for MTUExceeded says the reject identifier shall match the first request command in the packet, and that packets containing only responses shall be silently discarded. Linux intentionally deviates from that prescription: silently discarding desynchronizes the peer because the remote stack never learns its responses were dropped, and locating the first request command requires walking command headers past MTUsig, i.e. processing bytes from a packet we have already decided is too large to process. We therefore always emit one reject and use the identifier from the first command header, a single fixed-offset byte read. The unrestricted BR/EDR signaling parser and ECHO_REQ response path both trace to the initial git import; no later introducing commit is available for a Fixes tag. Cc: stable@vger.kernel.org Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com> Link: https://lore.kernel.org/r/20260518002800.1361430-1-michael.bommarito@gmail.com Link: https://lore.kernel.org/r/20260520135034.1060859-1-michael.bommarito@gmail.com Link: https://lore.kernel.org/r/20260521000555.3712030-1-michael.bommarito@gmail.com Assisted-by: Claude:claude-opus-4-7 Assisted-by: Codex:gpt-5-5-xhigh Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-14Bluetooth: serialize accept_q accessJiexun Wang
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. Protect accept_q with a dedicated lock for queue updates and polling. Also rework bt_accept_dequeue() to take temporary child references under the queue lock before dropping it and locking the child socket. Fixes: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Jann Horn <jannh@google.com> Reported-by: Yuan Tan <yuantan098@gmail.com> Reported-by: Yifan Wu <yifanwucs@gmail.com> Reported-by: Juefei Pu <tomapufckgml@gmail.com> Reported-by: Xin Liu <bird@lzu.edu.cn> Signed-off-by: Jiexun Wang <wangjiexun2025@gmail.com> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn> Signed-off-by: Jiexun Wang <wangjiexun2025@gmail.com> Reviewed-by: Jann Horn <jannh@google.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>