β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-5743

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-5743 Β· 2 files
FileTypeDescriptionSize
README.md file 1.4 KB ↓ raw
verdict.json file 1.8 KB view raw
README.md file
↓ download 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_testable
baseline no→ patch + rebuild →patched clean

hardening-only finding; no fix validation applicable

per-fix-DF-5743

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.