AlmAck opened a new pull request, #20003:
URL: https://github.com/apache/nuttx/pull/20003

   ## Summary
   
   `bt_conn_send()` caps the first fragment correctly:
   
   ```c
   len = remaining;
   if (len > g_btdev.le_mtu)
     {
       len = g_btdev.le_mtu;
     }
   ```
   
   The continuation loop a few lines below uses `<` instead of `>`, so a
   continuation fragment shorter than the controller MTU has its length
   *raised* to the MTU rather than left alone.
   
   The following `memcpy(bt_buf_extend(buf, len), ptr, len)` then copies
   `le_mtu` bytes out of a source buffer that holds fewer, reading past the
   end of the original buffer, and the ACL header advertises a length the
   payload does not have.
   
   ## Impact
   
   Affects every fragmented L2CAP transmission. The final fragment of a
   multi-fragment PDU is by definition shorter than the MTU, so it is hit
   on essentially every fragmented send: a heap overread on the transmit
   path plus a malformed ACL fragment on the air.
   
   Single-fragment PDUs are unaffected, which is why this survives light
   traffic and shows up under sustained transfers.
   
   
   ## Testing
   
   What was done downstream: found while debugging fragmented ATT writes on
   nrf5340-dk (cpuapp running the host stack, cpunet running the SoftDevice
   Controller) with `CONFIG_BLUETOOTH_MAX_MTU=247`. No clean before/after
   capture of this fix in isolation was kept — it was fixed alongside other
   Bluetooth work, so quoting a log here would misattribute it.
   
   Suggested reproduction to capture:
   
   1. Any board with a BLE controller and `CONFIG_BLUETOOTH_MAX_MTU` set
      above the controller's `le_mtu`, so L2CAP PDUs fragment.
   2. Send a PDU whose length is not a multiple of `le_mtu` — the last
      fragment is then shorter than the MTU and takes the broken path.
   3. Before the patch, instrument or capture the outgoing ACL fragments:
      the final fragment's header advertises `le_mtu` bytes and the payload
      is copied from past the end of the source buffer.
   4. After the patch, the final fragment carries `remaining` bytes.
   
   A sniffer capture or a `wlinfo` dump of `hdr->len` versus `remaining`
   for each fragment is the clearest evidence.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to