Skip to content

wireless/bluetooth: Validate the L2CAP header on the first ACL fragment. - #20204

Merged
acassis merged 2 commits into
apache:masterfrom
acassis:ble_nuttx
Sep 22, 2026
Merged

acassis merged 2 commits into
apache:masterfrom
acassis:ble_nuttx

Conversation

@acassis

@acassis acassis commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Summary

bt_conn_receive() read the 4-octet L2CAP header out of the first fragment of a PDU without checking that 4 octets had been received, and then computed the outstanding length by subtracting the fragment length from the declared PDU length.

Two problems follow. A fragment shorter than the header was parsed from whatever happened to follow it in the buffer. And a fragment carrying more data than the PDU it declares made the subtraction wrap, because conn->rx_len is 16 bits: the connection was then left expecting up to 65535 further octets, holding the partial PDU and accumulating later fragments against an expectation that could never be satisfied.

Check that the fragment is long enough to hold a header before reading it, and that it does not exceed the PDU it declares before computing what remains. Drop the fragment and reset the reassembly state otherwise.

Impact

Improvement

Testing

Before this change, a fragment of 10 octets declaring a 2-octet PDU:

  bt_conn_receive: handle 1 len 10 flags 02
  bt_conn_receive: First, len 10 final 2
  bt_conn_receive: rx_len 65532

4 + 2 - 10 is -4, so the connection is left expecting 65532 further
octets and holding the fragment. A 2-octet fragment sent next, shorter
than the header itself:

  bt_conn_receive: handle 1 len 2 flags 02
  bt_conn_receive: First, len 2 final 2
  bt_conn_receive: ERROR: Unexpected first L2CAP frame
  bt_conn_receive: rx_len 4

The length of 2 was read from beyond the two octets that arrived, and the
connection is parked again; the "Unexpected first L2CAP frame" line is
the earlier underflow surfacing.

After, both fragments are dropped and nothing is parked:

  bt_conn_receive: First, len 10 final 2
  bt_conn_receive: ERROR: First L2CAP frame exceeds its PDU (10 > 6)
  bt_conn_receive: handle 1 len 2 flags 02
  bt_conn_receive: ERROR: First L2CAP frame too short for a header (2)

The second fragment produces no "First, len" line, because the header is
no longer read before its presence is checked.

bt_conn_receive() read the 4-octet L2CAP header out of the first fragment
of a PDU without checking that 4 octets had been received, and then
computed the outstanding length by subtracting the fragment length from
the declared PDU length.

Two problems follow.  A fragment shorter than the header was parsed from
whatever happened to follow it in the buffer.  And a fragment carrying
more data than the PDU it declares made the subtraction wrap, because
conn->rx_len is 16 bits: the connection was then left expecting up to
65535 further octets, holding the partial PDU and accumulating later
fragments against an expectation that could never be satisfied.

Check that the fragment is long enough to hold a header before reading
it, and that it does not exceed the PDU it declares before computing what
remains.  Drop the fragment and reset the reassembly state otherwise.

Ref: Core v6.0, Vol 3, Part A, 3.1 (B-frame format)
Ref: Core v6.0, Vol 4, Part E, 5.4.2 (HCI ACL Data packets)
Testing: builds for sim:bluetooth with Make; every commit in this series
verified to build individually.  Not yet exercised at runtime - the
scriptable controller adds the truncated and oversized fragment cases
separately.

Signed-off-by: Alan C. Assis <acassis@gmail.com>
Assisted-by: Claude Code Opus 5
@github-actions github-actions Bot added Area: Bluetooth Size: S The size of the change in this PR is small labels Sep 20, 2026
This PR fixes the bad aligment reported by nxstyle.

Signed-off-by: Alan C. Assis <acassis@gmail.com>
@acassis

acassis commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

@xiaoxiang781216 please review again, the CI was reporting bad alignment on original file

@github-actions

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@acassis

acassis commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

The issue is caused by a random esptool BUG that was fixed on version 5.3.0, adding it here:
#20235

@acassis
acassis merged commit 6d04a12 into apache:master Sep 22, 2026
35 of 53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Bluetooth Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants