netbt uses IFF_LINK0 (0x1000) as an mbuf direction tag, colliding with the core mbuf flag M_LASTFRAG β spurious flag propagation and spoofable SCM_HCI_DIRECTION metadata
Summary
IFF_LINK0 == 0x1000 == M_LASTFRAG and is preserved by m_copym via M_COPYFLAGS: every RX packet carries a spurious M_LASTFRAG into the socket layer and any legitimately frag-flagged mbuf would be misreported as incoming. No in-tree consumer can see netbt mbufs today - hardening landmine. private-bit fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-5743 Β· 2 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | file | 1.4 KB | β raw | |
| verdict.json | file | 1.8 KB | view raw |
DF-5743 β netbt uses IFF_LINK0 (0x1000) as an mbuf "direction" tag,
colliding with the core mbuf flag M_LASTFRAG
Production code:
- sys/netbt/hci_socket.c:991 m->m_flags & IFF_LINK0 (direction cmsg)
- sys/netbt/hci_unit.c:347,363,380 m->m_flags |= IFF_LINK0 (RX mark)
- sys/netbt/hci.h M_GETCTX/M_SETCTX comment block (the NetBSD
import's M_LINK0 == IFF_LINK0 aliasing was carried over)
IFF_LINK0 == 0x1000 (sys/net/if.h:104) is numerically identical to
M_LASTFRAG == 0x1000 (sys/sys/mbuf.h:256), and M_LASTFRAG is part of
M_COPYFLAGS (mbuf.h:282) so it survives m_copym β every RX packet
marked "incoming" by netbt carries a spurious M_LASTFRAG into the
socket layer, and any mbuf that legitimately carries M_LASTFRAG
(set by ip_output.c:882, ieee80211_output.c:1861, and consulted by the
bge/bnx/ti/wpi drivers) would be misreported as "incoming" by
hci_mtap's SCM_HCI_DIRECTION control message.
No reachable harmful consumer exists inside netbt or the socket layer today (the ethernet/wifi consumers never see netbt mbufs), so this is filed as Low / hardening: the collision is a landmine (flag semantics silently overloaded) and the direction metadata is spoofable by any packet whose mbuf has bit 0x1000 set for other reasons. Fix: define a netbt-private direction bit (e.g. M_ flag properly registered or a pkthdr aux flag) instead of borrowing IFF_LINK0.
No PoC (Low/hardening per audit contract β skipped; status untested).
Fix verification
not_testablehardening-only finding; no fix validation applicable
Confirmed kernel references
Detail
Evidence (decisive lines)
static: sys/netbt/hci_socket.c:991, sys/netbt/hci_unit.c:347, sys/net/if.h:104, sys/sys/mbuf.h:256, sys/sys/mbuf.h:282, consumers enumerated via grep (no netbt-path consumer)
PoC changes
not built - Low/hardening finding, verification skipped per audit contract
Verified recommended fix
stop borrowing IFF_LINK0 for mbufs: add a netbt-private direction indicator (separate m_flag bit coordinated with sys/sys/mbuf.h maintainers, or a pkthdr aux field).
Verdict
Low/hardening: hci_socket.c:991 and hci_unit.c:347/363/380 use IFF_LINK0 (0x1000) as an mbuf direction tag; it collides with the core mbuf flag M_LASTFRAG (mbuf.h:256), which is copied by m_copym (M_COPYFLAGS, mbuf.h:282). Every RX packet gets a spurious M_LASTFRAG; every frag-flagged mbuf entering hci_mtap is misreported as incoming in the SCM_HCI_DIRECTION cmsg. No in-tree consumer of M_LASTFRAG touches netbt mbufs (bge/bnx/ti/wpi/ip_output/ieee80211 only), so no demonstrable impact today - filed as hardening with a spoofable-metadata note.
No comments yet.