<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/net/bluetooth/l2cap_core.c, branch linux-7.1.y</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=linux-7.1.y</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=linux-7.1.y'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-06-03T15:21:24+00:00</updated>
<entry>
<title>Bluetooth: L2CAP: reject BR/EDR signaling packets over MTUsig</title>
<updated>2026-06-03T15:21:24+00:00</updated>
<author>
<name>Michael Bommarito</name>
<email>michael.bommarito@gmail.com</email>
</author>
<published>2026-05-21T14:45:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=dd214733544427587a95f66dbf3adff072568990'/>
<id>urn:sha1:dd214733544427587a95f66dbf3adff072568990</id>
<content type='text'>
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 &lt;luiz.dentz@gmail.com&gt;
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 &lt;michael.bommarito@gmail.com&gt;
Signed-off-by: Luiz Augusto von Dentz &lt;luiz.von.dentz@intel.com&gt;
</content>
</entry>
<entry>
<title>Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp</title>
<updated>2026-05-28T12:52:20+00:00</updated>
<author>
<name>Luiz Augusto von Dentz</name>
<email>luiz.von.dentz@intel.com</email>
</author>
<published>2026-05-11T16:09:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=41c2713b204e6cb6a94587bc6bf6935107df5479'/>
<id>urn:sha1:41c2713b204e6cb6a94587bc6bf6935107df5479</id>
<content type='text'>
If dcid is received for an already-assigned destination CID the spec
requires that both channels to be discarded, but calling l2cap_chan_del
may invalidate the tmp cursor created by list_for_each_entry_safe and
in fact it is the wrong procedure as the chan-&gt;dcid may be assigned
previously it really needs to be disconnected.

Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so
instead schedule l2cap_chan_timeout with delay 0 to close the channel
asynchronously.

Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
Signed-off-by: Luiz Augusto von Dentz &lt;luiz.von.dentz@intel.com&gt;
</content>
</entry>
<entry>
<title>Bluetooth: l2cap: clear chan-&gt;ident on ECRED reconfiguration success</title>
<updated>2026-05-28T12:52:13+00:00</updated>
<author>
<name>Zhenghang Xiao</name>
<email>kipreyyy@gmail.com</email>
</author>
<published>2026-05-26T10:51:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=00e1950716c6ed67d74777b2db286b0fa23b4be9'/>
<id>urn:sha1:00e1950716c6ed67d74777b2db286b0fa23b4be9</id>
<content type='text'>
l2cap_ecred_reconf_rsp() returns early on success without clearing
chan-&gt;ident. Every other L2CAP response handler (l2cap_ecred_conn_rsp,
l2cap_le_connect_rsp, l2cap_config_rsp) clears chan-&gt;ident after a
successful transaction to prevent the channel from matching subsequent
responses with the recycled ident value.

A remote attacker that completed a reconfiguration as the peer can
replay a failure response with the stale ident, causing the kernel to
match and destroy the already-established channel via
l2cap_chan_del(chan, ECONNRESET).

Clear chan-&gt;ident for all matching channels on success, and harden the
failure path by using l2cap_chan_hold_unless_zero() consistent with
other L2CAP handlers (l2cap_le_command_rej, __l2cap_get_chan_by_ident).

Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
Signed-off-by: Zhenghang Xiao &lt;kipreyyy@gmail.com&gt;
Signed-off-by: Luiz Augusto von Dentz &lt;luiz.von.dentz@intel.com&gt;
</content>
</entry>
<entry>
<title>Bluetooth: L2CAP: fix chan ref leak in l2cap_chan_timeout() on !conn</title>
<updated>2026-05-27T20:44:01+00:00</updated>
<author>
<name>Siwei Zhang</name>
<email>oss@fourdim.xyz</email>
</author>
<published>2026-05-21T02:30:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=9dbd84990394c51f5cee1e8871bb5ff8af5ed939'/>
<id>urn:sha1:9dbd84990394c51f5cee1e8871bb5ff8af5ed939</id>
<content type='text'>
__set_chan_timer() takes a l2cap_chan reference via l2cap_chan_hold()
before scheduling the delayed work.  The normal path in
l2cap_chan_timeout() drops this reference with l2cap_chan_put() at the
end, but the early return when chan-&gt;conn is NULL skips the put,
leaking the reference.

Add the missing l2cap_chan_put() before the early return.

Fixes: adf0398cee86 ("Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout")
Cc: stable@vger.kernel.org
Signed-off-by: Siwei Zhang &lt;oss@fourdim.xyz&gt;
Signed-off-by: Luiz Augusto von Dentz &lt;luiz.von.dentz@intel.com&gt;
</content>
</entry>
<entry>
<title>Bluetooth: L2CAP: ecred_reconfigure: send packed pdu, not stack pointer</title>
<updated>2026-05-14T13:57:45+00:00</updated>
<author>
<name>Michael Bommarito</name>
<email>michael.bommarito@gmail.com</email>
</author>
<published>2026-05-11T12:26:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=3374ef8cf99368a40f7efd51a2a375a4c5dc6f0d'/>
<id>urn:sha1:3374ef8cf99368a40f7efd51a2a375a4c5dc6f0d</id>
<content type='text'>
Commit 1c08108f3014 ("Bluetooth: L2CAP: Avoid -Wflex-array-member-not-at-end
warnings") converted the on-stack request PDU in l2cap_ecred_reconfigure()
from an explicit packed struct to DEFINE_RAW_FLEX(), but did not adjust the
size and source-pointer arguments to l2cap_send_cmd():

  -    struct {
  -            struct l2cap_ecred_reconf_req req;
  -            __le16 scid;
  -    } pdu;
  +    DEFINE_RAW_FLEX(struct l2cap_ecred_reconf_req, pdu, scid, 1);
       ...
       l2cap_send_cmd(conn, chan-&gt;ident, L2CAP_ECRED_RECONF_REQ,
                      sizeof(pdu), &amp;pdu);

After the conversion, DEFINE_RAW_FLEX() expands to declare an anonymous
union pdu_u plus a local pointer "pdu" pointing at it. Therefore:

  - sizeof(pdu) is now sizeof(struct l2cap_ecred_reconf_req *) = 8 on
    64-bit (4 on 32-bit), not the 6 bytes of (mtu, mps, scid[1]).
  - &amp;pdu is the address of the local pointer's stack storage, not the
    address of the request payload.

l2cap_send_cmd() forwards (data, count) to l2cap_build_cmd(), which calls
skb_put_data(skb, data, count). The L2CAP_ECRED_RECONFIGURE_REQ packet
body therefore contains 8 bytes copied from the kernel stack starting at
&amp;pdu -- the 8 bytes overlap the pdu pointer's value, leaking a kernel
stack address to the paired Bluetooth peer. The intended (mtu, mps, scid)
fields are not transmitted at all, so the peer rejects the request as
malformed and the L2CAP_ECRED_RECONFIGURE feature itself has been broken
for the local-side initiator since the introducing commit landed.

The sibling site l2cap_ecred_conn_req() in the same commit was converted
correctly (sizeof(*pdu) + len, pdu); only this site was missed.

Restore the original semantics: pass the full flex-struct size via
struct_size(pdu, scid, 1) and the pdu pointer (the struct address) as
the source.

Validated on a stock 7.0-based host kernel via the real call path:
setsockopt(SOL_BLUETOOTH, BT_RCVMTU, ...) on a BT_CONNECTED
L2CAP_MODE_EXT_FLOWCTL socket emits an L2CAP_ECRED_RECONFIGURE_REQ
whose body is 8 bytes (the on-stack pdu local's value) rather than
the expected 6. Three captures from fresh socket / fresh hciemu peer
on the same host -- low bytes vary per call, high 0xffff confirms a
kernel virtual address (KASLR-randomised stack slot, not a fixed
string):

  RECONF_REQ body (ident=0x02 len=8): 42 fb 54 af 0e ca ff ff
  RECONF_REQ body (ident=0x02 len=8): 52 3d 2e af 0e ca ff ff
  RECONF_REQ body (ident=0x02 len=8): b2 fc 5b af 0e ca ff ff

After this patch the body is 6 bytes carrying the expected
little-endian (mtu, mps, scid).

Cc: stable@vger.kernel.org
Fixes: 1c08108f3014 ("Bluetooth: L2CAP: Avoid -Wflex-array-member-not-at-end warnings")
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito &lt;michael.bommarito@gmail.com&gt;
Signed-off-by: Luiz Augusto von Dentz &lt;luiz.von.dentz@intel.com&gt;
</content>
</entry>
<entry>
<title>Bluetooth: l2cap: defer conn param update to avoid conn-&gt;lock/hdev-&gt;lock inversion</title>
<updated>2026-05-06T20:20:51+00:00</updated>
<author>
<name>Mikhail Gavrilov</name>
<email>mikhail.v.gavrilov@gmail.com</email>
</author>
<published>2026-04-14T21:52:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=91b5a598b5285da794b72619f31777b62dd336f8'/>
<id>urn:sha1:91b5a598b5285da794b72619f31777b62dd336f8</id>
<content type='text'>
When a BLE peripheral sends an L2CAP Connection Parameter Update Request
the processing path is:

  process_pending_rx()          [takes conn-&gt;lock]
    l2cap_le_sig_channel()
      l2cap_conn_param_update_req()
        hci_le_conn_update()    [takes hdev-&gt;lock]

Meanwhile other code paths take the locks in the opposite order:

  l2cap_chan_connect()          [takes hdev-&gt;lock]
    ...
      mutex_lock(&amp;conn-&gt;lock)

  l2cap_conn_ready()            [hdev-&gt;lock via hci_cb_list_lock]
    ...
      mutex_lock(&amp;conn-&gt;lock)

This is a classic AB/BA deadlock which lockdep reports as a circular
locking dependency when connecting a BLE MIDI keyboard (Carry-On FC-49).

Fix this by making hci_le_conn_update() defer the HCI command through
hci_cmd_sync_queue() so it no longer needs to take hdev-&gt;lock in the
caller context.  The sync callback uses __hci_cmd_sync_status_sk() to
wait for the HCI_EV_LE_CONN_UPDATE_COMPLETE event, then updates the
stored connection parameters (hci_conn_params) and notifies userspace
(mgmt_new_conn_param) only after the controller has confirmed the update.

A reference on hci_conn is held via hci_conn_get()/hci_conn_put() for
the lifetime of the queued work to prevent use-after-free, and
hci_conn_valid() is checked before proceeding in case the connection was
removed while the work was pending.  The hci_dev_lock is held across
hci_conn_valid() and all conn field accesses to prevent a concurrent
disconnect from invalidating the connection mid-use.

Fixes: f044eb0524a0 ("Bluetooth: Store latency and supervision timeout in connection params")
Signed-off-by: Mikhail Gavrilov &lt;mikhail.v.gavrilov@gmail.com&gt;
Reviewed-by: Paul Menzel &lt;pmenzel@molgen.mpg.de&gt;
Signed-off-by: Luiz Augusto von Dentz &lt;luiz.von.dentz@intel.com&gt;
</content>
</entry>
<entry>
<title>Bluetooth: l2cap: fix MPS check in l2cap_ecred_reconf_req</title>
<updated>2026-05-06T20:20:38+00:00</updated>
<author>
<name>Dudu Lu</name>
<email>phx0fer@gmail.com</email>
</author>
<published>2026-04-15T10:43:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=4f42363c814f28fe3f59847c35acf1ed033bedd4'/>
<id>urn:sha1:4f42363c814f28fe3f59847c35acf1ed033bedd4</id>
<content type='text'>
The L2CAP specification states that if more than one channel is being
reconfigured, the MPS shall not be decreased. The current check has
two issues:

1) The comparison uses &gt;= (greater-than-or-equal), which incorrectly
   rejects reconfiguration requests where the MPS stays the same.
   Since the spec says MPS "shall be greater than or equal to the
   current MPS", only a strict decrease (remote_mps &gt; mps) should be
   rejected. Keeping the same MPS is valid.

2) The multi-channel guard uses `&amp;&amp; i` (loop index) to approximate
   "more than one channel", but this incorrectly allows MPS decrease
   for the first channel (i==0) even when multiple channels are being
   reconfigured. Replace with `&amp;&amp; num_scid &gt; 1` which correctly
   checks whether the request covers more than one channel.

Fixes: 7accb1c4321a ("Bluetooth: L2CAP: Fix invalid response to L2CAP_ECRED_RECONF_REQ")
Signed-off-by: Dudu Lu &lt;phx0fer@gmail.com&gt;
Signed-off-by: Luiz Augusto von Dentz &lt;luiz.von.dentz@intel.com&gt;
</content>
</entry>
<entry>
<title>Bluetooth: l2cap: Add missing chan lock in l2cap_ecred_reconf_rsp</title>
<updated>2026-04-13T13:19:42+00:00</updated>
<author>
<name>Dudu Lu</name>
<email>phx0fer@gmail.com</email>
</author>
<published>2026-04-05T15:47:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=42776497cdbc9a665b384a6dcb85f0d4bd927eab'/>
<id>urn:sha1:42776497cdbc9a665b384a6dcb85f0d4bd927eab</id>
<content type='text'>
l2cap_ecred_reconf_rsp() calls l2cap_chan_del() without holding
l2cap_chan_lock(). Every other l2cap_chan_del() caller in the file
acquires the lock first. A remote BLE device can send a crafted
L2CAP ECRED reconfiguration response to corrupt the channel list
while another thread is iterating it.

Add l2cap_chan_hold() and l2cap_chan_lock() before l2cap_chan_del(),
and l2cap_chan_unlock() and l2cap_chan_put() after, matching the
pattern used in l2cap_ecred_conn_rsp() and l2cap_conn_del().

Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
Signed-off-by: Dudu Lu &lt;phx0fer@gmail.com&gt;
Signed-off-by: Luiz Augusto von Dentz &lt;luiz.von.dentz@intel.com&gt;
</content>
</entry>
<entry>
<title>Bluetooth: L2CAP: Fix printing wrong information if SDU length exceeds MTU</title>
<updated>2026-04-13T13:17:52+00:00</updated>
<author>
<name>Luiz Augusto von Dentz</name>
<email>luiz.von.dentz@intel.com</email>
</author>
<published>2026-03-16T18:34:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=15bf35a660eb82a49f8397fc3d3acada8dae13db'/>
<id>urn:sha1:15bf35a660eb82a49f8397fc3d3acada8dae13db</id>
<content type='text'>
The code was printing skb-&gt;len and sdu_len in the places where it should
be sdu_len and chan-&gt;imtu respectively to match the if conditions.

Link: https://lore.kernel.org/linux-bluetooth/20260315132013.75ab40c5@kernel.org/T/#m1418f9c82eeff8510c1beaa21cf53af20db96c06
Fixes: e1d9a6688986 ("Bluetooth: LE L2CAP: Disconnect if received packet's SDU exceeds IMTU")
Signed-off-by: Luiz Augusto von Dentz &lt;luiz.von.dentz@intel.com&gt;
Reviewed-by: Paul Menzel &lt;pmenzel@molgen.mpg.de&gt;
</content>
</entry>
<entry>
<title>Bluetooth: L2CAP: CoC: Disconnect if received packet size exceeds MPS</title>
<updated>2026-04-10T14:26:48+00:00</updated>
<author>
<name>Christian Eggers</name>
<email>ceggers@arri.de</email>
</author>
<published>2026-02-25T17:07:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=728a3d128325bad286b1e4f191026e8de8d12a85'/>
<id>urn:sha1:728a3d128325bad286b1e4f191026e8de8d12a85</id>
<content type='text'>
Core 6.0, Vol 3, Part A, 3.4.3:
"... If the payload size of any K-frame exceeds the receiver's MPS, the
receiver shall disconnect the channel..."

This fixes L2CAP/LE/CFC/BV-27-C (running together with 'l2test -r -P
0x0027 -V le_public -I 100').

Signed-off-by: Christian Eggers &lt;ceggers@arri.de&gt;
Signed-off-by: Luiz Augusto von Dentz &lt;luiz.von.dentz@intel.com&gt;
Tested-by: Christian Eggers &lt;ceggers@arri.de&gt;
</content>
</entry>
</feed>
