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

mfi_aen_setup dereferences log_state before the error check whose EBUSY/ENOMEM paths leave it NULL; attach caller discards the error via a comma-operator bug

Summary

The boot_seq_num assignment executes BEFORE the if (error) check; mfi_get_log_state returns EBUSY/ENOMEM without setting *log_state, so the deref reads NULL -> boot-time panic. The attach call site '(error = mfi_aen_setup(sc, 0), 0) != 0' discards the real error via the comma operator, so the broken cleanup is dead code anyway. Improbable boot-time panic; reorder + comma fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3876 Β· 6 files
FileTypeDescriptionSize
README.md β€” 919 B ↓ raw
VERDICT.md β€” 900 B ↓ raw
fix.diff β€” 618 B view raw
manifest.json β€” 578 B view raw
verdict.json β€” 1.2 KB view raw
env.txt β€” 283 B view raw

DF-3876 β€” mfi_aen_setup dereferences log_state before checking the error that leaves it NULL

mfi.c:1019-1026:

if (seq_start == 0) {
    error = mfi_get_log_state(sc, &log_state);
    sc->mfi_boot_seq_num = log_state->boot_seq_num;   /* deref FIRST */
    if (error) {
        if (log_state)
            kfree(log_state, M_MFIBUF);
        return (error);

mfi_get_log_state (mfi.c:977-1005) returns EBUSY (no free command) or ENOMEM without ever setting *log_state, leaving it NULL (mfi.c:1010); the immediate unconditional deref reads NULL -> kernel panic. Additionally the attach-time caller at mfi.c:703 is if ((error = mfi_aen_setup(sc, 0), 0) != 0) β€” the comma operator discards the real error, so the botched check at 704-706 is dead code anyway.

Hardware/timing-gated (needs the free-command pool exhausted or kmalloc failure exactly during boot/AEN re-registration); Low.

VERDICT.md
↓ download raw

DF-3876 VERDICT β€” inconclusive (hardware-gated); defect certain in source

  • Order-of-operations verified: mfi.c:1020 assigns from log_state->boot_seq_num before the if (error) at 1022; *log_state stays NULL on the EBUSY/ENOMEM paths of mfi_get_log_state (mfi.c:984-987 dequeue failure returns before the mfi_dcmd_command allocation).
  • The comma-operator bug at mfi.c:703 (, 0) swallows the error) documented.
  • Trigger needs command-pool exhaustion / allocation failure at exactly the wrong boot instant β€” real but improbable; Low.

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

reorder fix; not validatable without HW

fix.diff
↓ fix.diffper-fix-DF-3876

Confirmed kernel references

Detail

Evidence (decisive lines)

VERDICT.md

PoC changes

no runnable PoC (needs pool exhaustion at boot)

Verified recommended fix

move the boot_seq_num assignment after the error check; fix comma operator

Verdict

log_state->boot_seq_num is dereferenced before the error check whose EBUSY/ENOMEM paths leave log_state NULL (mfi.c:1020-1026 via mfi_get_log_state mfi.c:977-1005); the attach caller even discards the error via a comma-operator bug (mfi.c:703). Boot-time NULL-deref panic, improbable trigger; straightforward fix.