DF-3525 / run.log
DF-3525 run.log — gated repro on DF-3524-FIXED kernel #1 (stock ng_l2cap module)
NOTE: on the STOCK kernel this entry is unreachable because DF-3524
(ng_uncallout/ETIMEDOUT wedge) prevents any L2CAP con from ever reaching
CON_OPEN (llpi.c:648 state check drops all ACL data). Fixing DF-3524
(kern_timeout.c, kernel #1) un-gates it; the reassembly defect itself is
present in the stock module.
[1] # ./l2cap_con lie
LP_CON_IND -> ok
HCI_NODE_UP -> ok (pkt_size=65535, num_pkts=8)
L2CAP SET_DEBUG(9) -> ok
LP_CON_CFM (pos) -> ok (connection accepted -> CON_OPEN)
ECHO_RSP -> 13 real bytes received
outgoing ACL header length field = 65527
real payload bytes in mbuf chain = 9
LIE PROPAGATED: ACL header claims 65527 bytes, 9 exist -> 65518 phantom
bytes (driver TX OOB read on real HW)
exit=0
(13 received bytes = 5-byte packed ACL hdr + 4-byte L2CAP hdr +
4-byte cmd hdr; phantom = 65527 - 8 = 65519 exactly as constructed.)
[2] kernel side (dmesg):
ng_l2cap_lp_receive: got ACL data packet, con_handle=291, PB=0x2, length=8
ng_l2cap_lp_receive: staring new L2CAP packet, con_handle=291, length=65523
ng_l2cap_lp_receive: got ACL data packet, con_handle=291, PB=0x1, length=65519
ng_l2cap_lp_send: attaching ACL packet, con_handle=291, PB=0x2, length=65527
ng_l2cap_lp_deliver: sending ACL packet, con_handle=291, len=65532
-> the ZERO-byte FRAGMENT claiming 65519 bytes was accepted
(llpi.c:702 `rx_pkt->m_pkthdr.len += length` never checks `length`
against the bytes actually present), the completed "packet"
passed ng_l2cap_receive's consistency check by construction
(hdr->length == pkthdr.len - 4), and the echo response carried
the lie into the outgoing ACL header (lp_send :548).
[3] CONTROL (truthful single-fragment echo, same session type):
ECHO_RSP -> received 17 bytes; ACL length field == actual.
[4] FIX VALIDATED (module-level, ng_l2cap_llpi.c claim check:
`if (length > m->m_pkthdr.len) { error = EMSGSIZE; goto drop; }`
right after length = le16toh(acl_hdr->length)):
./l2cap_con lie -> ECHO_RSP NOT RECEIVED (lie suppressed)
./l2cap_con con -> ECHO_RSP received 17 bytes, exit=0
(truthful traffic unaffected)
kernel log for con: got ACL ... length=12 == actual.