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).
No comments yet.