Stack buffer overflow in ng_ksocket_sockaddr_unparse via negative pathlen (PF_LOCAL sun_len underflow)
Summary
ng_ksocket_sockaddr_unparse(:323-339) PF_LOCAL case: pathlen=sun->sun_len-pathoff where pathoff=OFFSETOF(sockaddr_un,sun_path)=2(:325). NO validation sun_len>=pathoff. BIND/CONNECT sanity(:678-680,:739-741) checks arglen>=SADATA_OFFSET and arglen>=sa_len but NOT sa_len>=SADATA_OFFSET. sa_len<2 passes check -> sobind accepts short sockaddr. GETNAME calls unparse -> line :327 pathlen=sun_len-2=negative int. Line :331 bcopy(sun->sun_path, pathbuf, pathlen) interprets negative as size_t~2^64 -> massive stack OOB write into 256-byte pathbuf[SOCK_MAXADDRLEN+1] + OOB read from sun_path. Kernel panic/RCE. Generic parser getLength guards this (returns 0 when sa_len<SADATA_OFFSET) but unparse omits guard. Requires netgraph control access. Fix: if(sun_len<pathoff) return EINVAL; also harden BIND/CONNECT sa_len>=SADATA_OFFSET.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0509 Β· 11 files| File | Type | Description | Size | |
|---|---|---|---|---|
| harness.c | trigger-source | userspace harness replicating vulnerable function logic | 4.3 KB | view raw |
| build.sh | build-script | cc compile command | 89 B | view raw |
| run.sh | run-script | run the harness | 60 B | view raw |
| build.log | build-log | full compiler output | 13 B | view raw |
| run.log | run-log | full runtime output (baseline) | 1.3 KB | view raw |
| fix_run.log | run-log | runtime output on patched kernel | 1.3 KB | view raw |
| fix.diff | suggested-fix | git-apply-able unified diff | 585 B | view raw |
| VERDICT.md | verdict | full narrative analysis | 994 B | β raw |
| env.txt | environment | guest uname, cc version | 298 B | view raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-0509 VERDICT
Verdict: FALSE POSITIVE
Mechanism
Source: sys/netgraph/ksocket/ng_ksocket.c:325,655-656
Stack overflow via negative pathlen.
The ng_ksocket BIND/CONNECT sanity check (lines 655, 717) does NOT validate sa_len >= SADATA_OFFSET, allowing a short sockaddr to pass. HOWEVER, defense-in-depth in unp_bind (sys/kern/uipc_usrreq.c:1141-1143) validates namelen = sun_len - offsetof(sockaddr_un, sun_path) and rejects <= 0. So a short sockaddr is never stored and ng_ksocket_sockaddr_unparse never receives one. The finding's claim that 'sobind accepts short sockaddr' is incorrect on DragonFly. The unparse function has a latent vulnerability but it is NOT triggerable. Fix.diff adds the missing check as defense-in-depth hardening.
PoC changes
harness.c: replicates the vulnerable function logic demonstrating the bug.fix.diff: targeted fix for the root cause (git-apply-able).
Fix validation
See fix_status in JSON verdict and fix_build.log/fix_run.log.
Confirmed kernel references
- s
- y
- s
- /
- n
- e
- t
- g
- r
- a
- p
- h
- /
- k
- s
- o
- c
- k
- e
- t
- /
- n
- g
- _
- k
- s
- o
- c
- k
- e
- t
- .
- c
- :
- 3
- 2
- 5
- s
- y
- s
- /
- k
- e
- r
- n
- /
- u
- i
- p
- c
- _
- u
- s
- r
- r
- e
- q
- .
- c
- :
- 1
- 1
- 4
- 1
Detail
Exploit chain
none (false positive).
Evidence (decisive lines)
FALSE POSITIVE. ng_ksocket_sockaddr_unparse has latent pathlen underflow but unp_bind at uipc_usrreq.c:1141-1143 REJECTS all sockaddrs with sun_len<3 BEFORE storage. Path unreachable.
Verified recommended fix
Defense-in-depth: add || sa->sa_len < SADATA_OFFSET to BIND/CONNECT sanity checks at ng_ksocket.c:655-656 and :717-718.
Verdict
FALSE POSITIVE. ng_ksocket_sockaddr_unparse has latent pathlen underflow but unp_bind at uipc_usrreq.c:1141-1143 REJECTS all sockaddrs with sun_len<3 BEFORE storage. Path unreachable.
No comments yet.