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

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 into lpOutBuffer.
  • Required config or capabilities: device hptmv loaded.
  • Reachability: sysctl hptmv.status write with a crafted lpInBuffer spanning a valid page then an unmapped page, so copyin faults partway.

Proof of concept

  1. mmap a single page at a known address with PROT_READ.
  2. Compute HPT_IOCTL_PARAM so that nInBufferSize spans past the mapped page into an unmapped page; copyin will fault partway and return EFAULT (ignored).
  3. Choose dwIoControlCode that accepts nInBufferSize > 0 and writes to lpOutBuffer.
  4. Read out_buf after 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.

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1852 Β· 4 files
FileTypeDescriptionSize
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
VERDICT.md verdict source-confirmation analysis
↓ download 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

fixed
baseline reproduced→ patch + rebuild →patched clean

fix.diff compiled in batch kernel build rc=0 -Werror

fix.diff compiled in batch kernel build rc=0 -Werror
↓ fix.diffcombined build rc=0

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)