Unconditional panic() on device-fed completion status bytes: q_status != QS_DONE (fires on legitimate QS_DONE|QS_DISC1) and unhandled host_stat codes (including codes the driver itself enumerates)
Summary
The walk panics unless the raw LRAM q_status byte is exactly QS_DONE or carries QS_ABORTED - the driver's own ABI defines QS_DISC1/DISC2 bits, so a legitimate 0x82 completion or any corrupt byte panics. adv_done's default arm panics on host_stat codes outside the handled set, including two codes the switch enumerates only in order to panic. Guest model: 14/30 tabulated values panic incl. legitimate ABI bits. Log-and-complete-with-error fix (DF-4042/4308 family).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4351 Β· 9 files| File | Type | Description | Size | |
|---|---|---|---|---|
| df4351.c | β | 5.5 KB | view raw | |
| build.sh | β | 86 B | view raw | |
| run.sh | β | 89 B | view raw | |
| build.log | β | 496 B | view raw | |
| run.log | β | 2.6 KB | view raw | |
| env.txt | β | 966 B | view raw | |
| fix.diff | β | 1.2 KB | view raw | |
| VERDICT.md | β | 2.7 KB | β raw | |
| README.md | β | 1.1 KB | β raw |
DF-4351 β panic() on device-fed completion status bytes (DF-4042/DF-4308 family, narrow twin)
Build / Run (guest model)
cc -O2 -Wall -o df4351 df4351.c ./df4351
Expected: 14 of 30 tabulated device-fed values lead to kernel panic,
including q_status = QS_DONE|QS_DISC1 (0x82) β a legitimate ABI
combination (QS_DISC1/QS_DISC2 are defined queue-state bits,
advlib.h:565-566) β and host_stat codes the driver itself enumerates
(QHSTA_D_LRAM_CMP_ERROR 0x81, QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1).
Root cause
- advansys.c:1092-1094 β panic unless the raw LRAM q_status byte is exactly QS_DONE or has QS_ABORTED set (copied unmasked by adv_copy_lram_doneq, advlib.c:816-818).
- advansys.c:1235-1237 β adv_done default arm panics on host_stat codes outside the handled set, including codes the switch itself lists only to panic on.
Hostile/corrupt SCSI peripheral or buggy firmware β instant kernel panic from an ordinary completion. Same family as DF-4042 (amd.c) and DF-4308 (adwcam.c), both accepted at Low for this threat model.
Fix
fix.diff (git apply --check clean): log + complete with error instead
of panicking at both sites.
DF-4351 VERDICT
Status: untested (kernel path) β code defect certain; guest model replays the exact panic predicates.
Root cause (line-accurate)
Two unconditional panic() sites gated only on adapter-written LRAM bytes:
-
sys/dev/disk/advansys/advansys.c:1092-1094
if ((scsiq.q_status != QS_DONE) && (scsiq.q_status & QS_ABORTED) == 0) panic("adv_qdone: completed scsiq with unknown status");q_status is copied verbatim from LRAM by adv_copy_lram_doneq (advlib.c:816-818, no masking). The driver's own queue-state ABI (advlib.h:562-569) defines QS_DISC1 (0x02)/QS_DISC2 (0x04); a completion byte of QS_DONE|QS_DISC1 (0x82) β a state the firmware can legitimately write for a reconnected command β is an instant panic. Any corrupt LRAM byte without QS_ABORTED likewise. -
advansys.c:1227-1237 β adv_done's inner switch routes QHSTA_D_QDONE_SG_LIST_CORRUPTED (0x21), QHSTA_D_ASC_DVC_ERROR_CODE_SET (0x22), QHSTA_D_HOST_ABORT_FAILED (0x23), QHSTA_D_EXE_SCSI_Q_FAILED (0x24), QHSTA_D_ASPI_NO_BUF_POOL (0x26), QHSTA_M_BAD_TAG_CODE (0x46), and β although the driver's ABI enumerates them β QHSTA_D_LRAM_CMP_ERROR (0x81) and QHSTA_M_MICRO_CODE_ERROR_HALT (0xA1) into
panic("%s: Unhandled Host status error %x"), plus every undefined value.
Consequence: an ordinary I/O completion carrying any of these device-written bytes takes the whole system down. Family precedent: DF-4042 (amd.c, MESSAGE REJECT panic) and DF-4308 (adwcam.c, four unhandled host_status codes) β both accepted, Low severity for the hostile-peripheral threat model.
Verification
- Kernel path untestable on the guest (no AdvanSys HBA; env.txt).
- Guest model
df4351.c(cc 8.3; build.log/run.log) tabulates the two predicates verbatim over the device-fed value domains: 14/30 values panic, including the two "legitimate ABI bits" rows (0x82/0x84) and the two enumerated-but-panicking host codes (0x81/0xA1).
Fix validation
Kernel-level validation impossible on this guest. fix.diff (git apply
--check clean) replaces both panics: site 1 logs and falls through to
normal completion-with-error handling (adv_done's default: arm at
:1248-1253 already maps unknown done_stat to CAM_REQ_CMP_ERR, so no
control-flow hazard); site 2 reports via xpt_print_path and sets
CAM_REQ_CMP_ERR, matching the handling of QHSTA_M_AUTO_REQ_SENSE_FAIL.
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_testableKernel fix validation impossible on this guest (no AdvanSys HBA). fix.diff is git-apply-clean against sys/; control-flow analysis: site 1 falls through to the existing unknown-done_stat handling (:1248-1253 -> CAM_REQ_CMP_ERR), site 2 mirrors the QHSTA_M_AUTO_REQ_SENSE_FAIL arm; neither path leaves the ccb uncompleted.
fix.diff; adv_done default-arm trace in VERDICT.md (:1248-1253)
Confirmed kernel references
Detail
Exploit chain
hostile/corrupt SCSI peripheral or compromised AdvanSys firmware writes any completion with q_status not in {QS_DONE, *|QS_ABORTED} or host_stat in the panic set -> adv_intr -> adv_run_doneq/adv_done -> panic() -> kernel DoS. No unprivileged-user or remote path.
Evidence (decisive lines)
run.log ('PANIC-ON-DEVICE-STATUS CONFIRMED (model)', 14/30 table incl. 0x82/0x84/0x81/0xA1 rows); VERDICT.md; env.txt; fix.diff (git apply --check clean)
PoC changes
No seed PoC. Authored df4351.c: tabulates the two panic predicates (transcribed verbatim) over the q_status byte domain and the host_stat code table from advlib.h:640-667.
Verified recommended fix
Replace both device-fed panics with log + CAM_REQ_CMP_ERR completion (see fix.diff).
Verdict
Source-certain, hardware-gated (DF-4042/DF-4308 family, narrow twin). advansys.c:1092-1094 panics unless the raw LRAM completion-status byte is exactly QS_DONE or carries QS_ABORTED - the byte is copied unmasked from the adapter (advlib.c:816-818), and the driver's own ABI defines QS_DISC1/QS_DISC2 queue-state bits, so a legitimate 0x82 (QS_DONE|QS_DISC1) or any corrupt value panics the kernel from an ordinary completion. advansys.c:1235-1237 panics on host_stat codes the switch does not handle, including codes it enumerates only to panic on (0x81 QHSTA_D_LRAM_CMP_ERROR, 0xA1 QHSTA_M_MICRO_CODE_ERROR_HALT). Hostile SCSI peripheral / buggy firmware -> instant kernel DoS; family precedent DF-4042 and DF-4308 (both Low). Kernel path untestable on the guest (no AdvanSys HBA). Guest model (cc 8.3) replays both predicates verbatim: 14/30 tabulated device-fed values panic, incl. the legitimate-bit and enumerated-code rows.
No comments yet.