mfi ioctl handlers dereference user ioctl buffers without copyin/copyout -> trap_fatal panic on unmapped args (and kernel writes through raw user pointers)
Summary
DragonFly passes the user ioctl pointer to d_ioctl handlers; mfi_ioctl/mfi_user_command dereference it directly across MFIIO_STATS, MFIIO_QUERY_DISK, MFI_CMD (reads adapter_no and bcopy's the frame), MFI_SET_AEN, and MFIIO_PASSTHRU (reads AND writes through ioc). An unmapped user address makes the kernel fault on a user VA with pcb_on_fault==NULL: 'Fatal user address access from kernel mode' -> panic. The PASSTHRU bcopy write direction additionally writes kernel data to an arbitrary (attacker-chosen, mapped) user address without copyout. The Linux shim cases copyin properly, showing the intended pattern. Single-syscall local kernel panic. Copyin/copyout-each-struct fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3873 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.4 KB | β raw | |
| VERDICT.md | β | 1.1 KB | β raw | |
| build.sh | β | 106 B | view raw | |
| env.txt | β | 283 B | view raw | |
| fix.diff | β | 1019 B | view raw | |
| mfi_ioctl_nullderef.c | β | 4.2 KB | view raw | |
| run.log | β | 264 B | view raw | |
| run.sh | β | 102 B | view raw |
DF-3873 β mfi ioctl handlers dereference user ioctl buffers without copyin -> panic on unmapped args
DragonFly passes the user ioctl data pointer to d_ioctl handlers; drivers must copyin. mfi_ioctl / mfi_user_command dereference it directly:
- mfi.c:2909-2916 (MFIIO_STATS):
ms->ms_item, bcopy to&ms->ms_qstat - mfi.c:2928-2943 (MFIIO_QUERY_DISK): reads
qd->array_id, writes qd fields - mfi.c:2950-2973 (MFI_CMD):
ioc->mfi_adapter_no,bcopy(ioc->mfi_frame.raw, ...)and every laterioc->mfi_sgl[...]/ioc->mfi_sense_*access - mfi.c:3126-3128 (MFI_SET_AEN):
aen->aen_seq_num - mfi.c:2818-2867 (MFIIO_PASSTHRU via mfi_user_command):
ioc->buf_size,copyin(ioc->buf,...),bcopy(&ioc->ioc_frame,...),bcopy(dcmd,&ioc->ioc_frame,...)β the last one also writes through the raw user pointer.
An unmapped user address makes the kernel fault on a user VA with
pcb_onfault == NULL: DragonFly trap.c:905-925 prints "Fatal user address
access from kernel mode" and calls trap_fatal() -> panic. One ioctl with a
garbage arg pointer from any user holding /dev/mfi0 open (operator group).
The Linux shim cases (MFI_LINUX_CMD_2 / MFI_LINUX_SET_AEN_2) copyin properly,
showing the intended pattern.
Build/run
cc -O2 -o mfi_ioctl_nullderef mfi_ioctl_nullderef.c # trigger 3 = this finding ./mfi_ioctl_nullderef
Guest has no MegaRAID -> hardware-gated (run.log).
DF-3873 VERDICT β inconclusive (hardware-gated), source-certain
- Verified the direct user-pointer dereferences at the cited lines and the DragonFly fault policy: sys/platform/pc64/x86_64/trap.c:905-925 β a kernel-mode fault on a user-range address with no pcb_onfault (i.e. outside copyin/copyout) is fatal ("Fatal user address access from kernel mode").
- No SMAP on the standard guest/snapshot is irrelevant: the panic comes from the unmapped VA, not from protection.
- Trigger: ioctl(fd, MFI_CMD, (void*)0x515100001000UL) etc. β single syscall.
- Guest: device absent (run.log); code-level certainty high.
- fix.diff (illustrative for MFI_CMD; same pattern for the other cases): copyin the packet first, then operate on the kernel copy.
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
not_testablecopyin/copyout the ioctl structs instead of direct dereference
fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
DF-3873/run.log (build OK, device absent) + VERDICT.md line-by-line trace
PoC changes
written fresh; shared trigger binary covers DF-3871 (T1), DF-3872 (T2), DF-3873 (T3)
Verified recommended fix
mfi_ioctl_nullderef.c
Verdict
mfi_ioctl/mfi_user_command dereference the raw user ioctl pointer without copyin (MFIIO_STATS :2909, MFIIO_QUERY_DISK :2928, MFI_CMD :2950-2973 incl. bcopy of mfi_frame.raw, MFI_SET_AEN :3126, MFIIO_PASSTHRU :2818-2867 incl. a bcopy WRITE through the user pointer). An unmapped arg faults in kernel mode with pcb_onfault==NULL: trap.c:905-925 'Fatal user address access from kernel mode' -> trap_fatal -> panic, one syscall, operator-group. Guest has no MegaRAID: hardware-gated, source-certain.
No comments yet.