hptmv AS_INITIALIZE_START queues the rebuild DPC with flag VERIFY - initialization never starts; ioctl spins 80s and returns success
Summary
Copy-paste bug: the INITIALIZE_START case queues hpt_rebuild_data_block with VERIFY, so rf_initializing is never set and the wait loop polls 1-tick tsleeps until the 80s timeout - then falls through to return 0: the management tool is told the array initialization (the data-hygiene wipe feature) started when nothing happened, with ET_VERIFY_STARTED in the event log. Root-gated sysctl on HighPoint hardware. Queue-INITIALIZE + timeout-returns-failure fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4541 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.4 KB | β raw | |
| VERDICT.md | β | 2.6 KB | β raw | |
| hptinit.c | β | 3.0 KB | view raw | |
| build.sh | β | 108 B | view raw | |
| run.sh | β | 166 B | view raw | |
| manifest.json | β | 684 B | view raw | |
| verdict.json | β | 2.2 KB | view raw |
DF-4541 β hptmv AS_INITIALIZE_START queues the wrong DPC flag; initialize never runs, ioctl stalls 80 s and reports success
What
hpt_set_array_state() case AS_INITIALIZE_START
(sys/dev/raid/hptmv/ioctl.c:572-591) queues the rebuild DPC with the
VERIFY flag:
580: hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY);
Compare AS_VERIFY_START (ioctl.c:540) which correctly queues VERIFY,
and HPT_IOCTL_CREATE_ARRAY with CAF_CREATE_R5_ZERO_INIT
(ioctl.c:392) which correctly queues INITIALIZE. This is a copy-paste
bug: hpt_rebuild_data_block(flags==VERIFY) only ever sets
rf_verifying (ioctl.c:729-736), never rf_initializing
(ioctl.c:720-727).
Consequence
while (!pVDevice->u.array.rf_initializing)(ioctl.c:583-589) can never become true: the calling thread polls withtsleep(..., 1)untiltimeout >= hz*80β an ~80-second stall of the sysctl-write thread per call.- After the timeout the function falls through and
return 0(ioctl.c:616) β the management tool is told the array initialization started when nothing happened. The event queue getsET_VERIFY_STARTEDinstead ofET_INITIALIZE_STARTED. - Security-relevant residue: "initialize array" is the data-hygiene feature that is supposed to write the array; a silent no-op defeats the user's wipe expectation when arrays are re-purposed.
The same silent-timeout-returns-success protocol exists in every wait
loop of this function (ioctl.c:494-500, 519-525, 543-549, 562-568,
602-608) and in Kernel_DeviceIoControl's ADD_DISK_TO_ARRAY post-
processing (ioctl.c:430-436), but only the INITIALIZE case is
guaranteed to hit it on every call.
Reachability
The hptmv ioctl channel is the writable sysctl dev.hptmv.status
(hptproc.c:614-617). Sysctl writes require root; the array must exist
on real HighPoint hardware. Not testable on the audit QEMU guest
(no HighPoint HBA β gIal_Adapter NULL, see DF-1853 for that path).
Trigger
hptinit.c <array-id> β builds the HPT_IOCTL_PARAM packet for
HPT_IOCTL_SET_ARRAY_STATE (0xFF0F) with state = AS_INITIALIZE_START
(7) and writes it to dev.hptmv.status.
Expected on vulnerable driver: returns success after ~80 s; dmesg shows
hptmv: Verifying started. rather than Initializing started.
Fix
Queue INITIALIZE, and make the wait loops report failure on timeout.
DF-4541 β VERDICT
Status: untested (no HighPoint hardware on the audit guest; path is root-only sysctl). The finding is established by code trace, not by execution.
Code trace (why this is certain without hardware)
hpt_set_array_state()AS_INITIALIZE_START: sys/dev/raid/hptmv/ioctl.c:572-591.- ioctl.c:580 β
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY);β VERIFY, not INITIALIZE. - ioctl.c:583-589 β waits on
rf_initializing, which is only set byhpt_rebuild_data_blockcaseINITIALIZE(ioctl.c:720-727); the VERIFY case setsrf_verifying(ioctl.c:729-736). Wait can never succeed β 80 s of 1-tick tsleep polling (timeout >= hz*80). - ioctl.c:616 β
return 0after the timeout: success despite no-op. - Correct comparators:
AS_VERIFY_STARTqueues VERIFY (ioctl.c:540); CREATE_ARRAYCAF_CREATE_R5_ZERO_INITqueues INITIALIZE (ioctl.c:392);AS_INITIALIZE_ABORTwaits onrf_initializing(ioctl.c:595) β i.e. the rest of the driver agrees INITIALIZE is a distinct operation.
Why not run
- The only user entry is
sysctl dev.hptmv.statuswrite (hptproc.c:614-617, CTLFLAG_RW) β root-only. - Requires a HighPoint RocketRAID controller with a functional RAID1/5
array; the QEMU guest has none (
gIal_Adapter == NULL; a sysctl write on the guest panics via the already-known DF-1853 NULL-deref before reaching this code).
Impact assessment
Logic/data-hygiene bug + per-call 80 s kernel-thread stall, root-only, hardware-bound: Low. Bucket: base:dev.
Recommended fix
--- a/sys/dev/raid/hptmv/ioctl.c
+++ b/sys/dev/raid/hptmv/ioctl.c
@@ -577,7 +577,7 @@ hpt_set_array_state(DEVICEID idArray, DWORD state)
unlock_driver();
- hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY);
+ hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, INITIALIZE);
unlock_driver();
while (!pVDevice->u.array.rf_initializing)
Additionally, the wait loops (ioctl.c:494-500, 519-525, 543-549,
562-568, 583-589, 602-608, 430-436) should return -1 (or otherwise
report failure) when they time out instead of falling through to
return 0.
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_testablenot_testable - requires HighPoint hardware
VERDICT.md contains the one-line diff; not applied (sys/ read-only; no hardware to validate on)
Confirmed kernel references
Detail
Evidence (decisive lines)
findings/poc/DF-4541/VERDICT.md (full path:line trace); hptinit.c (faithful trigger packet: HPT_IOCTL_MAGIC + SET_ARRAY_STATE 0xFF0F + AS_INITIALIZE_START 7)
PoC changes
authored from scratch; HPT_IOCTL_PARAM layout taken from hptintf.h:744-753, ioctl code HPT_CTL_CODE(15)=0xFF0F per hptintf.h:166,197
Verified recommended fix
queue INITIALIZE instead of VERIFY at ioctl.c:580 and make the wait loops return failure on timeout
Verdict
Not executed: the hptmv ioctl channel is the root-only sysctl dev.hptmv.status and requires a HighPoint SATA RAID controller with a valid array; the QEMU audit guest has no such hardware. The defect is established by code trace: AS_INITIALIZE_START queues the rebuild DPC with flag VERIFY (ioctl.c:580) so rf_initializing is never set (only hpt_rebuild_data_block case INITIALIZE sets it, ioctl.c:720-727), the ioctl thread then polls for 80 seconds (ioctl.c:583-589) and returns 0 (success, ioctl.c:616) although the array was never initialized - silent failure of the data-hygiene 'initialize array' operation plus an 80 s kernel-thread stall per call.
No comments yet.