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

sili_pm_softreset: error = EBUSY on unexpected device-signature change is dead-stored by the unconditional error = 0 β€” signature-change detection never propagates, probe proceeds with stale at_type

Summary

The author-intended EBUSY (XXX-marked) is dead-stored by the unconditional error=0 two lines later: after a device swap behind the PM the probe advances with the stale at_type instead of the orderly retry. Identical twin in ahci_pm.c:853-856. Probe-logic degradation only. Conditional-error fix (pack also carries the ahci hunk).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4695 Β· 11 files
FileTypeDescriptionSize
README.md β€” 1.5 KB ↓ raw
VERDICT.md β€” 2.4 KB ↓ raw
trigger_sili_pm.c β€” 3.1 KB view raw
build.sh β€” 120 B view raw
run.sh β€” 125 B view raw
build.log β€” 106 B view raw
run.log β€” 1.1 KB view raw
env.txt β€” 664 B view raw
fix.diff β€” 623 B view raw
manifest.json β€” 1.2 KB view raw
verdict.json β€” 2.2 KB view raw

DF-4695 β€” sili_pm_softreset: error = EBUSY (unexpected device-signature change) is unconditionally clobbered by error = 0

Build & run

sh build.sh          # cc -O2 -Wall -o trigger_sili_pm trigger_sili_pm.c
sh run.sh            # ./trigger_sili_pm 15

Expected output

This is a pure logic defect, mechanically provable from source β€” no runtime trigger required (the trigger is kept only to document the hardware gate).

sili_pm.c:489-497:

    if (at->at_type == ATA_PORT_T_NONE) {
        at->at_type = sili_port_signature(ap, at, sig);
    } else {
        if (sili_port_signature(ap, at, sig) != at->at_type) {
            kprintf("%s: device signature unexpectedly changed\n", …);
            error = EBUSY; /* XXX */
        }
    }
    error = 0;          /* <-- sili_pm.c:498: dead-stores the EBUSY above */
err:

The /* XXX */ shows the author intended the signature-change to propagate; error = 0; at :498 makes the assignment at :495 dead. The caller (sili_port_reset from the state machine sili.c:632 or XPT_RESET_DEV sili_cam.c:908) receives success and the probe state machine advances to ATA_PROBE_NEED_IDENT (sili_pm.c:515) with a stale at->at_type after a device swap behind the PM β€” the wrong IDENTIFY variant is then issued and the probe degrades to a logged failure instead of the intended orderly EBUSY retry. The ahci twin has the identical defect (ahci_pm.c:853-856).

On the audit QEMU guest there is no sili hardware (env.txt) β€” runtime manifestation impossible; code-certain regardless.

VERDICT.md
↓ download raw

VERDICT β€” DF-4695

Status: inconclusive (hardware-gated) Β· defect mechanically certain from source Β· impact: probe-logic degradation, no memory-safety effect

Reproduced?

Runtime manifestation requires sili PM hardware (absent on the guest, env.txt), but this finding does not need runtime proof: the defect is a mechanically provable dead store.

Proof

sili_pm.c:489-499 (verbatim):

    if (at->at_type == ATA_PORT_T_NONE) {
        at->at_type = sili_port_signature(ap, at, sig);       // :490
    } else {
        if (sili_port_signature(ap, at, sig) != at->at_type) { // :492
            kprintf("%s: device signature unexpectedly "
                "changed\n", ATANAME(ap, at));
            error = EBUSY; /* XXX */                       // :495
        }
    }
    error = 0;                                                  // :498
err:
    …
    at->at_probe = error ? ATA_PROBE_FAILED : ATA_PROBE_NEED_IDENT; // :515

error is initialized to EIO at :422; the only way it can be EBUSY at :497 is the signature-change branch at :495 β€” and :498 unconditionally overwrites it with 0. Hence error = EBUSY is dead: the signature-change condition is detectable only from the console message, never from the return value.

Consequence

When a softreset run as part of ccb error processing sees the device signature change (device swapped / glitched behind the PM), the caller β€” sili_port_reset() from the state machine (sili.c:632) or XPT_RESET_DEV (sili_cam.c:908) β€” is told success. at->at_probe advances to ATA_PROBE_NEED_IDENT (:515) with at->at_type still holding the old device type (the else-branch never updates it), so the subsequent probe issues the IDENTIFY variant for the wrong device class; the mis-probe fails and degrades to a logged probe failure instead of the intended orderly EBUSY retry. No memory corruption; wasted probe cycles and a wrong-type window during device replacement. Severity Low, confidence certain.

Family note

The ahci twin carries the identical defect β€” ahci_pm.c:853-856 (error = EBUSY; /* XXX */ … error = 0;). ahci_pm.c is outside this file's scope; flagged here for the orchestrator.

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_testable
baseline no→ patch + rebuild →patched clean

Fix validation not testable: the guest has no SiI 3124/3132 HBA and QEMU does not emulate the SiL3726 port multiplier, so neither baseline nor patched kernel can reach sili_pm_* at runtime. fix.diff is a line-accurate source-level fix (all referenced helpers declared in sili.h); code-reviewed only.

env.txt (PCI inventory, 0 sili dmesg lines); fix.diff
↓ fix.diffper-fix-DF-4695

Confirmed kernel references

Detail

Evidence (decisive lines)

VERDICT.md 'Proof' quotes sili_pm.c:489-499 verbatim showing the dead store; fix.diff also carries the ahci_pm.c twin.

PoC changes

No seed; trigger kept only to document the hardware gate.

Verified recommended fix

Only clear error when not EBUSY (sili_pm.c and ahci_pm.c twins).

Verdict

Mechanically certain from source, no runtime needed: sili_pm.c:495 sets error=EBUSY on unexpected device-signature change (author-intended, marked / XXX /), and sili_pm.c:498 unconditionally overwrites it with error=0, so the EBUSY can never reach the caller; at->at_probe then advances to NEED_IDENT (:515) with stale at_type after a device swap behind the PM. ahci twin: ahci_pm.c:853-856 (same dead store). Runtime manifestation requires PM hardware absent from the audit guest (env.txt); the trigger documents the gate.