amdsettags panic("Implement me!") reached when a target rejects a tagged command (MESSAGE REJECT handling)
Summary
amdhandlemsgreject calls amdsettags whenever MESSAGE REJECT arrives with an active SRB holding CAM_TAG_ACTION_VALID and no SDTR pending; amdsettags is panic('Implement me!'). Tag queuing default-enabled from EEPROM. A tag-intolerant or hostile target panics the kernel; xpt_alloc_ccb also leaks. Branch selection verified on the guest. Implement-the-function fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4043 Β· 12 files| File | Type | Description | Size | |
|---|---|---|---|---|
| amd_walks.c | β | 10.2 KB | view raw | |
| build.sh | β | 65 B | view raw | |
| run.sh | β | 89 B | view raw | |
| build.log | β | 184 B | view raw | |
| run.log | β | 2.0 KB | view raw | |
| env.txt | β | 832 B | view raw | |
| fix.diff | β | 353 B | view raw | |
| fix_build.log | β | 1.2 KB | view raw | |
| README.md | β | 1.1 KB | β raw | |
| VERDICT.md | β | 2.7 KB | β raw | |
| manifest.json | β | 877 B | view raw | |
| verdict.json | β | 3.5 KB | view raw |
DF-4043 β amdsettags panic("Implement me!") reached when a target rejects a tagged command (MESSAGE REJECT handling)
File: sys/dev/disk/amd/amd.c
Severity: Medium | Class: CWE-670 Always-Incorrect Control Flow Implementation (unimplemented function panic)
Status: hardware-gated β source-certain; runtime reproduction impossible on the audit guest
(no AMD53C974 HBA β see env.txt). Verdict: inconclusive, confidence certain.
Build & run (on the DragonFly guest)
./build.sh # compiles the demonstrator (verbatim-copy of the driver walks) ./run.sh # reproduces the exact branch selection / fault
Expected: the DF-4043 section of run.log shows the panic-branch selection / fault.
Full guest details in env.txt.
Fix validation
fix.diff applied (with all DF-4036..DF-4044 patches together) to a clean guest /usr/src copy;
make nativekernel KERNCONF=X86_64_GENERIC completed with 0 errors under -Werror
(see fix_build.log β amd.o recompiled into the GENERIC kernel).
Sources restored to pristine afterwards (md5-verified).
DF-4043 VERDICT β amdsettags panic("Implement me!") reached when a target rejects a tagged command (MESSAGE REJECT handling)
Bottom line
Source-certain kernel panic: amdhandlemsgreject (amd.c:1452-1525) calls amdsettags(amd, cur_target, FALSE) at amd.c:1485 whenever a MESSAGE REJECT arrives while the active SRB has CAM_TAG_ACTION_VALID and no SDTR is pending (msgout_len==0 on the SEL_W_ATN2 tagged path β amdstart amd.c:942-954 only writes the tag bytes to the FIFO). amdsettags is a stub: panic("Implement me!") (amd.c:846). A target that reports tag support (or one that simply rejects the tag byte) panics the kernel; the xpt_alloc_ccb at :1483 also leaks. Tag queuing is enabled by default (EEPROM defaults set TAG_QUEUING for all targets, amd.c:2238; AMD_USR_TAGENB at amd.c:2337-2338). Verified by replicating the handlemsgreject branch ladder with msgout_len==0 + active tagged SRB: the tag branch is selected (run.log DF-4043). Requires hostile/broken SCSI target -> runtime inconclusive on this guest (no HBA), source certain.
Exploit chain
tagged I/O to a target that rejects the SIMPLE Q TAG message -> MSG IN MESSAGE REJECT -> amdhandlemsgreject -> amdsentmsg(SDTR)=FALSE (msgout empty) -> tag branch :1475-1485 -> amdsettags -> panic amd.c:846
Why not reproduced on the guest
The audit guest has no AMD53c974-compatible SCSI HBA (env.txt); amd(4) is compiled into the
GENERIC kernel (X86_64_GENERIC:88 device amd) but never attaches, so the hostile-target message
flows cannot be exercised at runtime. The exact walks were compiled from the driver source
(verbatim amdsentmsg copy / exact branch ladder / exact store) and driven with the real driver
states (run.log); the fix is compile-validated (fix_build.log).
Negative results recorded alongside (pass-2 depth)
Kills proven in run.log: msgin_buf[6] per-byte walk max index 4 (bounded); SRB_array[msgin_buf[1]] 0..255 fits SRB_array[256] exactly; msgout shift bcopy fits msgout_buf[6]; amdtimeout/callout family is #if 0 dead code (no timeout-vs-intr race); EEPROM word walks fit eepromBuf[128] exactly; XPT_RESET_BUS ACBFlag race can only strand CCBs (hang, logged, not filed).
Fix
Implement amdsettags: toggle AMD_CUR_TAGENB in tinfo[target].disc_tag with a target bound. Applied and compile-validated on the guest (fix_build.log); sys/ tree never modified by the audit.
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
fixedfixed (compile-validated): all nine patches applied together to the clean guest /usr/src copy (polaris10_smumgr.c md5 6f39bb32..->19a2b278.., amd.c f577a330..->54ce1518..), make -j4 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with 0 compile errors under -Werror; amd.o recompiled into the GENERIC kernel. Runtime re-test impossible on this guest (device absent). Sources restored to pristine and md5-verified after validation.
findings/poc/DF-4043/fix.diff; findings/poc/DF-4043/fix_build.log (build banner + compile lines + 0 errors)
Confirmed kernel references
Detail
Exploit chain
tagged I/O to a target that rejects the SIMPLE Q TAG message -> MSG IN MESSAGE REJECT -> amdhandlemsgreject -> amdsentmsg(SDTR)=FALSE (msgout empty) -> tag branch :1475-1485 -> amdsettags -> panic amd.c:846
Evidence (decisive lines)
run.log section DF-4043; VERDICT.md; fix_build.log; env.txt
PoC changes
Pass-2 reviewer authored demonstrator with a verbatim copy of the driver's amdsentmsg walk / handlemsgreject branch ladder / parsemsg DISCONNECT arm so branch selection is the kernel's; fix.diff generated against the pristine file and compile-validated via full nativekernel rebuild on the guest (shared build with DF-4036..DF-4044, fix_build.log).
Verified recommended fix
Implement amdsettags: toggle AMD_CUR_TAGENB in tinfo[target].disc_tag with a target bound
Verdict
Source-certain kernel panic: amdhandlemsgreject (amd.c:1452-1525) calls amdsettags(amd, cur_target, FALSE) at amd.c:1485 whenever a MESSAGE REJECT arrives while the active SRB has CAM_TAG_ACTION_VALID and no SDTR is pending (msgout_len==0 on the SEL_W_ATN2 tagged path β amdstart amd.c:942-954 only writes the tag bytes to the FIFO). amdsettags is a stub: panic("Implement me!") (amd.c:846). A target that reports tag support (or one that simply rejects the tag byte) panics the kernel; the xpt_alloc_ccb at :1483 also leaks. Tag queuing is enabled by default (EEPROM defaults set TAG_QUEUING for all targets, amd.c:2238; AMD_USR_TAGENB at amd.c:2337-2338). Verified by replicating the handlemsgreject branch ladder with msgout_len==0 + active tagged SRB: the tag branch is selected (run.log DF-4043). Requires hostile/broken SCSI target -> runtime inconclusive on this guest (no HBA), source certain.
No comments yet.