Unchecked copyin return + no M_ZERO in hptmv ioctl lets stale kernel heap leak via copyout
| Field | Value |
|---|---|
| ID | DF-1852 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N |
| CWE | CWE-252 Unchecked Return Code; CWE-909 Missing Initialization of Resource |
| File | sys/dev/raid/hptmv/hptproc.c |
| Lines | 297, 303-304 |
| Area | dev/raid (HighPoint hptmv sysctl) |
| Confidence | likely |
| Discovered | 2026-07-20 |
| Reported | pending |
| Known CVE | none |
| CVE match | dfly_specific |
Summary
kmalloc at line 297 is called without M_ZERO, so ke_area contains stale
heap data. The copyin at line 304 ignores its return code; if it fails
part-way (attacker supplies a partially-invalid lpInBuffer) the buffer remains
partially uninitialized yet is still passed as the input to
Kernel_DeviceIoControl and, on success, indirectly to copyout at line 315.
With a cooperative ioctl code this leaks stale kernel heap to userspace.
Root cause
hptproc.c:297:
ke_area = kmalloc(piop->nInBufferSize+piop->nOutBufferSize, M_DEVBUF, M_NOWAIT);
DragonFlyBSD's kmalloc does not zero memory unless M_ZERO is supplied
(kern_slaballoc.c).
hptproc.c:303-304:
if (piop->nInBufferSize)
copyin((void*)(ULONG_PTR)piop->lpInBuffer, ke_area, piop->nInBufferSize);
Return value of copyin is discarded. hptproc.c:309 then unconditionally calls
Kernel_DeviceIoControl(... ke_area, piop->nInBufferSize, ...). hptproc.c:315:
on err==0 the function copyouts from ke_area + piop->nInBufferSize.
A crafted lpInBuffer that is valid for the first N bytes then invalid will
leave ke_area[N..nInBufferSize-1] holding whatever was last in that slab (other
kernel allocations, possibly containing pointers/credentials).
Threat model & preconditions
- Attacker position: local root (sysctl write requires
SYSCAP_NOSYSCTL_WR). - Privileges gained or impact: stale kernel heap info leak. Practical impact
depends on finding an ioctl code that (a) succeeds without inspecting every
byte of
lpInBuffer, or (b) copies input-derived data intolpOutBuffer. - Required config or capabilities:
device hptmvloaded. - Reachability: sysctl
hptmv.statuswrite with a craftedlpInBufferspanning a valid page then an unmapped page, socopyinfaults partway.
Proof of concept
mmapa single page at a known address withPROT_READ.- Compute
HPT_IOCTL_PARAMso thatnInBufferSizespans past the mapped page into an unmapped page;copyinwill fault partway and returnEFAULT(ignored). - Choose
dwIoControlCodethat acceptsnInBufferSize > 0and writes tolpOutBuffer. - Read
out_bufafter the sysctl returns 0; bytes beyond what the handler actually wrote will be stale kernel heap.
Impact
Low-severity info leak of stale kernel heap. Standing alone this is a defense-in-depth hardening issue; combined with DF-1851 it also supplies an additional write gadget.
Recommended fix
Add M_ZERO to the kmalloc and abort on copyin != 0:
ke_area = kmalloc(piop->nInBufferSize+piop->nOutBufferSize, M_DEVBUF,
M_ZERO | M_NOWAIT);
...
if (piop->nInBufferSize) {
if (copyin((void*)(ULONG_PTR)piop->lpInBuffer, ke_area,
piop->nInBufferSize) != 0) {
kfree(ke_area, M_DEVBUF);
return -EINVAL;
}
}
Timeline
- 2026-07-20 Discovered during automated audit.
- 2026-07-20 Reported to DragonFlyBSD security contact (pending).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1852 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | git-apply-able fix for the cited bug | 814 B | view raw |
| VERDICT.md | verdict | source-confirmation analysis | 1.0 KB | β raw |
| build.sh | build-script | N/A (source-only) | 65 B | view raw |
| run.sh | run-script | N/A (source-only) | 89 B | view raw |
DF-1852 VERDICT
Verdict: REPRODUCED (source-confirmed)
Impact: Low (driver-level NULL deref / OOB / leak / DoS β hardware-gated)
Mechanism: hptproc.c L297 kmalloc(...,M_DEVBUF,M_NOWAIT) no M_ZERO so ke_area stale heap. L303-304 if(nInBufferSize) copyin(lpInBuffer,ke_area,nInBufferSize) return value discarded. L309 Kernel_DeviceIoControl(k
Citation: sys/dev/raid/hptmv/hptproc.c:297-304
Fix: Applied fix.diff β compiles in batch kernel build (rc=0, -Werror).
Verification method: Source-only line-by-line trace of cited path:line. Low-severity driver bug; PoC trigger requires specific hardware or root context. Confirmed the cited vulnerable pattern exists in source.
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.
Fix verification
fixedfix.diff compiled in batch kernel build rc=0 -Werror
fix.diff compiled in batch kernel build rc=0 -Werror
Confirmed kernel references
β
Detail
Exploit chain
none (Low severity)
Evidence (decisive lines)
Source-confirmed: unchecked copyin return + no M_ZERO in hptmv ioctl (hptproc.c:297-304)
Verified recommended fix
Source-confirmed: unchecked copyin return + no M_ZERO in hptmv ioctl (hptproc.c:297-304)
Verdict
Source-confirmed: unchecked copyin return + no M_ZERO in hptmv ioctl (hptproc.c:297-304)
No comments yet.