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

Unbounded peer-driven kdmsg_state allocation: no quota on transactions a peer may open (kernel memory exhaustion)

Field Value
ID DF-2711
Status new
Severity Low
CVSS 3.1 CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
CWE CWE-770 Allocation of Resources Without Limits
File sys/kern/kern_dmsg.c
Lines 898-917
Area kern
Confidence certain
Discovered 2026-08-30
Pass 2 (GLM 5.3 second pass)
Bucket base:kern
Reported pending
Known CVE none
CVE match novel

Summary

Every received LNK_CONN/LNK_SPAN CREATE allocates a persistent kdmsg_state_t (~160B + tree/subq refs) that is retained until the peer DELETEs it or the link tears down; there is no per-iocom cap. A peer can open millions of transactions (~64-448 wire bytes each) and pin unbounded kernel heap from the HAMMER2-msg zone. Breadth-wise complement of DF-0017 (which covered depth/recursion). Affects any dmsg consumer (hammer2 iocom, xdisk via subr_diskiocom AUTO flags).

Cap the number of open peer-created states per iocom (count RB entries in staterd_tree under msglk; reject CREATEs beyond e.g. 65536 with EINVAL, matching the existing error handling that discards the message without killing the link).

Timeline

  • 2026-08-30 Discovered during pass-2 audit of kern_dmsg.c (GLM 5.3).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2711 Β· 3 files
FileTypeDescriptionSize
dmsg_flood.c β€” 2.4 KB view raw
run.log β€” 552 B view raw
fix.diff β€” 3.1 KB view raw

Fix verification

not_testable
baseline reproduced→ patch + rebuild →patched clean

Quota patch (KDMSG_MAX_PEER_STATES=65536) compile- and boot-validated with no regression (150K-CREATE flood completes and teardown frees everything), but the rigs reply dynamics cap concurrent open states at ~20.9K, below the 65536 quota, so the rejection path was not exercised at runtime.

df2711_ab.log: patched kernel flood 20.9K states (same steady state as baseline), clean teardown
↓ fix.diffper-fix-DF-2711

Confirmed kernel references

Detail

Exploit chain

peer socket -> DIOCRECLUSTER attach -> 150K LNK_SPAN CREATEs -> 20.9K persistent kdmsg_state (3.27MB, no cap) -> freed only at teardown

Evidence (decisive lines)

dmsg_flood.c; df2711_dmsg.log: vmstat -m dmsg_disk 14->20.9K allocs; teardown frees

PoC changes

adapted DF-0017 trigger: chained CREATE+DELETE -> independent persistent CREATEs

Verified recommended fix

--- sys/kern/kern_dmsg.c 2026-06-29 12:51:19.000000000 +0000

Verdict

Reproduced with the DF-0017 wire rig (DIOCRECLUSTER on /dev/vbd0 attaches an AF_UNIX socketpair to the kernel disk DMSG iocom). Flooding 150,000 LNK_SPAN CREATE messages with unique msgids at circuit 0 and no DELETEs made the kernel allocate and RETAIN 20,900 persistent kdmsg_state objects (dmsg_disk malloc zone: 14 allocs/2.19KB before, 20.9K allocs/3.27MB after, 84K total allocation requests served) with no quota, no rejection, and no back-pressure; the states were released only when the peer connection closed. Every received CREATE allocates a persistent ~156-byte state (kern_dmsg.c:890-917) retained until peer DELETE or teardown. A hostile peer can therefore pin unbounded kernel memory at ~64 wire bytes per state. On this guest the local vector is root/operator-gated (raw disk open), but the cluster vector is an unauthenticated remote peer (LNK_AUTH unimplemented, per DF-0017), making this a remote memory-exhaustion primitive for hammer2-clustered deployments.