HAMMER1 mirror ioctls: mirror->size unchecked in mirror_read and mirror->count unchecked in both paths β wrap-around bypasses the ubuf bounds guards (hardening)
Summary
hammer_ioc_mirror_read never validates mirror->size (contrast the write path's 'size < 0 || size > 0x70000000' at :348) and neither path validates caller-supplied mirror->count on entry. The guards 'count + HAMMER_HEAD_DOALIGN(bytes) > size' (:156/:214/:260) and 'count + mrec.head.rec_size > size' (:424, uint32 arithmetic) wrap for count near INT_MAX or negative, letting copyin/copyout run at ubuf+-2GB. None beyond the caller poking its own address space: every access stays behind copyin/copyout fault isolation and both ubuf and count come from the same SYSCAP_NOVFS_IOCTL-gated caller. Defense-in-depth only; source-proven (untested). Fix: validate size/count at entry to both mirror ioctls.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3151 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 520 B | β raw | |
| VERDICT.md | β | 1.7 KB | β raw | |
| verdict.json | β | 1.8 KB | view raw | |
| manifest.json | β | 393 B | view raw |
DF-3151 β mirror_read/mirror_write entry validation gaps (Info, hardening)
hammer_ioc_mirror_read never validates mirror->size (the write path does at
hammer_mirror.c:348) and neither path validates the caller-supplied
mirror->count; the 32-bit bounds arithmetic at hammer_mirror.c:156/214/260/424
can wrap. All consequences stay behind copyin/copyout user-address fault
isolation (same gated caller owns ubuf), so this is hardening, not a kernel
memory-safety bug. See VERDICT.md. No PoC (status: untested).
DF-3151 β HAMMER1 hammer_ioc_mirror_read never validates mirror->size / mirror->count
Source-analysis finding (Info / hardening); no guest run performed.
- hammer_ioc_mirror_read (hammer_mirror.c:72-319) validates only the key range
(:91-96). Unlike the write path (:348
size < 0 || size > 0x70000000) the READ path never checksmirror->size, and NEITHER path validatesmirror->counton entry. - All copyout sizing is guarded by `mirror->count + HAMMER_HEAD_DOALIGN(bytes)
mirror->size
(:156, :214, :260) in 32-bit signed/unsigned arithmetic. With a caller-suppliedcountnear INT_MAX (or negative), the sum wraps and the guard passes, so the kernel will copyout atubuf + count` (~+-2GB). - The WRITE path has the same shape at :424 (
mirror->count + mrec.head.rec_sizein uint32 arithmetic can wrap for negative count). - NOT a kernel memory-safety bug: every access is copyin/copyout through the
standard user-address fault isolation, and both
ubufandcountcome from the same (gated, SYSCAP_NOVFS_IOCTL) caller. Impact is limited to the caller poking its own address space plus protocol confusion. - Fix (hardening): validate
mirror->sizein mirror_read exactly as the write path does, and rejectmirror->count < 0 || mirror->count > mirror->sizeat entry to both functions.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
(No fix.diff for this item: documented recommendation only - see Fix above.)
Fix verification
not_testableConfirmed kernel references
Detail
Evidence (decisive lines)
['VERDICT.md: full line-annotated analysis']
PoC changes
n/a (no PoC; source-analysis finding)
Verified recommended fix
Validate mirror->size in hammer_ioc_mirror_read (same check as hammer_mirror.c:348) and reject out-of-range mirror->count at entry to both mirror ioctls.
Verdict
Info/hardening, source-proven only. hammer_ioc_mirror_read never validates mirror->size (contrast the write path's explicit check at hammer_mirror.c:348) and neither mirror path validates the caller-supplied mirror->count on entry. The bounds guards at mirror.c:156/214/260 (read) and :424 (write) are computed in 32-bit arithmetic and can wrap for count near INT_MAX or negative, letting the kernel copyin/copyout at ubuf+count (~+-2GB). Not a kernel memory-safety bug: all accesses stay behind copyin/copyout user-address fault isolation and both ubuf and count come from the same SYSCAP_NOVFS_IOCTL-gated caller - impact is confined to the caller's own address space plus protocol confusion. No guest run performed (nothing to demonstrate beyond the caller poking its own memory).
No comments yet.