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).
Recommended fix
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)
PoC verification
Evidence pack
findings/poc/DF-2711 Β· 3 files| File | Type | Description | Size | |
|---|---|---|---|---|
| dmsg_flood.c | β | 2.4 KB | view raw | |
| run.log | β | 552 B | view raw | |
| fix.diff | β | 3.1 KB | view raw |
Fix verification
not_testableQuota 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
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.
No comments yet.