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

KKASSERT is the only bounds check before bcopy/hammer_datacrc in hammer_indirect_callback (defense-in-depth gap on non-INVARIANTS kernels)

Field Value
ID DF-3034
Status new
Severity Info
CVSS 3.1 CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:N/A:N
CWE CWE-617 (assert-as-bounds-check)
File sys/vfs/hammer/hammer_io.c
Lines 1658-1677
Area vfs/hammer
Confidence likely
Discovered 2026-09-02
Pass 2 (GLM 5.3 second pass)
Bucket base:vfs
Reported pending
Known CVE none
CVE match novel

Summary

hammer_indirect_callback() validates that the device-side buffer covers the request only via KKASSERT(bp->b_bufsize >= obp->b_bufsize) β€” compiled out on production kernels β€” and then bcopy()s obp->b_bufsize bytes out of bp->b_data; the preceding CRC check has the same unguarded assumption. The code's own comment admits fragility ('due to big-block recycling and other factors there is some fragility there'), and HAMMER genuinely mixes 16K and 64K buffer sizes in the large-data zone, so a future regression in buffer sizing turns this into an OOB kernel heap read copied into a user-readable file buffer. Currently not exploitable: getblk guarantees an exact size match (disposes of mismatched buffers and retries), both breadcb and cluster_readcb acquire the callback's buffer at exactly obp->b_bufsize, and the path requires hammer_double_buffer=1 (non-default). Filed as Info hardening: the memory-safety property is incidental (relies on distant getblk internals) and any buffer-size regression immediately becomes an OOB read (kernel heap β†’ user file page) on production kernels. Fix: convert the assert into an explicit runtime check + short-circuit the CRC condition (row diff). Same assert-as-bounds-check class as DF-3003 (:931), kept separate because the guarded operations differ.

Timeline

  • 2026-09-02 Discovered during pass-2 audit of hammer_io.c (GLM 5.3).

Discussion (0)

No comments yet.