ng7 twin of DF-0512: finish_accept copies an unbounded sa (sa_len up to 255) into ng_ksocket_accept.addr declared as a fixed struct sockaddr
Summary
The accept response is allocated with OFFSETOF(...,addr)+sa->sa_len so the bcopy is in-bounds of the allocation, but the declared type of addr is a fixed struct sockaddr; any consumer that type-puns the response with sizeof(addr) or a sockaddr-specific family gets a truncated/confused sockaddr (PF_LOCAL up to 255 bytes). Pass 1 filed this for v1 (DF-0512) but its ng7 twin was never filed. Latent type confusion for ABI consumers of NGM_KSOCKET_ACCEPT responses with long sockaddrs. Fix: declare addr as sockaddr_storage. [VERIFIED pass2: reproduced - ACCEPT arglen 32 vs declared 16-byte sockaddr type-confusion condition on harness kernel; in-bounds copy, ABI hazard as filed]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3504 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 323 B | β raw | |
| VERDICT.md | β | 1.7 KB | β raw | |
| env.txt | β | 329 B | view raw | |
| fix.diff | β | 488 B | view raw | |
| manifest.json | β | 681 B | view raw | |
| run.log | β | 262 B | view raw | |
| verdict.json | β | 2.0 KB | view raw |
DF-3504 - ng7 ksocket ACCEPT sockaddr type confusion
Harness kernel. gcc -O -o kaccept kaccept.c; ./kaccept. arglen=32 vs declared 16-byte struct sockaddr - condition reproduced.
Kernel: DragonFly dfbsd 6.5-DEVELOPMENT #0: Sun Oct 25 20:46:48 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_NG7 x86_64 (harness kernel)
DF-3504 - VERDICT
status: reproduced | reproduced: 1 | impact: none | confidence: certain
Condition reproduced on the harness kernel: kaccept.c creates an ng7 ksocket listener (hook inet6/stream/6), binds [::]:7799, LISTENs, requests NGM_KSOCKET_ACCEPT (which arms response_addr), then connects from a normal IPv6 socket; the ACCEPT response received on the control socket reports cmd=3 arglen=32 = offsetof(struct ng_ksocket_accept, addr)=4 + sa_len=28 (sockaddr_in6) - exactly twice the 16-byte declared struct sockaddr addr (ng_ksocket.h:78-81). finish_accept bcopies the full sa_len into that fixed-typed field (ng_ksocket.c:1250-1252); the copy is in-bounds of the kmalloc'd response (allocated with OFFSETOF+sa_len), so this is the filed ABI/type-confusion hazard rather than memory corruption: any consumer type-punning the response with sizeof(struct sockaddr) (or copying sizeof(addr)) silently truncates 12+ bytes of address. Latent consumer-facing defect; no in-tree victim identified (ngctl's parse uses the generic sockaddr type).
Kernel references
- sys/netgraph7/ksocket/ng_ksocket.c:1250
- sys/netgraph7/ksocket/ng_ksocket.c:1252
- sys/netgraph7/ksocket/ng_ksocket.h:80
Evidence
run.log (ACCEPT resp cmd=3 arglen=32 vs sizeof(sockaddr)=16 + CONFIRMED line), kaccept.c
Recommended fix
declare addr as struct sockaddr_storage (ABI bump) or document arglen-based consumption.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testableConfirmed kernel references
Detail
Evidence (decisive lines)
run.log (ACCEPT resp cmd=3 arglen=32 vs sizeof(sockaddr)=16 + CONFIRMED line), kaccept.c
PoC changes
kaccept.c written fresh; note the listen flow requires an explicit NGM_KSOCKET_ACCEPT request to arm response_addr
Verified recommended fix
declare addr as struct sockaddr_storage (ABI bump) or document arglen-based consumption.
Verdict
Condition reproduced on the harness kernel: kaccept.c creates an ng7 ksocket listener (hook inet6/stream/6), binds [::]:7799, LISTENs, requests NGM_KSOCKET_ACCEPT (which arms response_addr), then connects from a normal IPv6 socket; the ACCEPT response received on the control socket reports cmd=3 arglen=32 = offsetof(struct ng_ksocket_accept, addr)=4 + sa_len=28 (sockaddr_in6) - exactly twice the 16-byte declared struct sockaddr addr (ng_ksocket.h:78-81). finish_accept bcopies the full sa_len into that fixed-typed field (ng_ksocket.c:1250-1252); the copy is in-bounds of the kmalloc'd response (allocated with OFFSETOF+sa_len), so this is the filed ABI/type-confusion hazard rather than memory corruption: any consumer type-punning the response with sizeof(struct sockaddr) (or copying sizeof(addr)) silently truncates 12+ bytes of address. Latent consumer-facing defect; no in-tree victim identified (ngctl's parse uses the generic sockaddr type).
No comments yet.