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

hw.ral.msi_disable tunable is a no-op: pci_alloc_1intr receives ~ral_msi_disable, which is truthy for BOTH tunable values (0 β†’ ~0 == 0xFFFFFFFF, 1 β†’ ~1 == 0xFFFFFFFE)

Summary

The boolean MSI-enable flag receives the bitwise complement - truthy for both tunable values, so the knob never disables MSI. All other tree callers pass plain 0/1; the retained FreeBSD branch gates correctly (a DFly port artifact). One-token ! fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4998 Β· 3 files
FileTypeDescriptionSize
README.md β€” 1.9 KB ↓ raw
VERDICT.md β€” 2.3 KB ↓ raw
fix.diff β€” 585 B view raw

DF-4998 β€” hw.ral.msi_disable tunable is ineffective: ~ral_msi_disable is truthy for BOTH tunable values, so MSI is always enabled

Where

sys/dev/netif/ral/if_ral_pci.c:254 β€” psc->sc_irq_type = pci_alloc_1intr(dev, ~ral_msi_disable, &rid, &irq_flags);

What

pci_alloc_1intr(device_t dev, int msi_enable, int *rid, u_int *flags) (sys/bus/pci/pci.c:4348) treats its second argument as a boolean enable flag: if (msi_enable) { ... pci_alloc_msi(...) } (pci.c:4358). ral_msi_disable is a 0/1 TUNABLE_INT("hw.ral.msi_disable", ...) (line 64-65), so the bitwise complement yields:

  • ral_msi_disable == 0 β†’ ~0 == 0xFFFFFFFF (truthy) β†’ MSI enabled βœ“ (intended)
  • ral_msi_disable == 1 β†’ ~1 == 0xFFFFFFFE (still truthy) β†’ MSI enabled βœ—

i.e. hw.ral.msi_disable=1 does not disable MSI. Every other pci_alloc_1intr() caller in the tree passes a plain 0/1 enable variable (sys/dev/netif/bge/if_bge.c:2355, sys/dev/netif/re/if_re.c:758, sys/dev/netif/em/if_em.c:2488, sys/dev/drm/drm_dragonfly.c:121, …). The intent is clearly !ral_msi_disable (the operator is a ~/! typo; the operator precedence trap does not exist here since ~ binds tighter than the function call). The only working escape hatch is the per-device dev.ral.N.msi.enable=0 env hint consumed inside pci_alloc_1intr (pci.c:4357).

Impact

Functional/safety-knob regression, no direct security impact: an operator who sets the documented-by-convention hw.ral.msi_disable=1 knob (e.g. working around MSI delivery quirks on broken chipsets/APICs, or reducing the interrupt surface) silently keeps MSI. Info severity.

Reproduce (reasoning; no runtime needed β€” pure boolean logic on a live kernel path)

kldload if_ral; hw.ral.msi_disable=1 in /boot/loader.conf
# observed: dev.ral.X.%pnpinfo interrupt is still MSI (msi.enable env unset)
VERDICT.md
↓ download raw

DF-4998 β€” VERDICT

Finding: if_ral_pci.c:254 passes ~ral_msi_disable where a boolean enable flag is required, so hw.ral.msi_disable=1 fails to disable MSI.

The proof is complete at the source level and needs no hardware:

  1. sys/bus/pci/pci.c:4348 pci_alloc_1intr(device_t dev, int msi_enable, …); pci.c:4357-4369: the argument is (a) overridden only by the per-device msi.enable env hint, then (b) tested as a plain boolean: if (msi_enable) { … pci_alloc_msi(dev, &rid, 1, cpu) … }.
  2. if_ral_pci.c:64-65: ral_msi_disable is a 0/1 int tunable (hw.ral.msi_disable).
  3. if_ral_pci.c:254: pci_alloc_1intr(dev, ~ral_msi_disable, &rid, &irq_flags) β€” ~0 == -1 (truthy), ~1 == -2 (truthy): MSI is attempted for both tunable values; the knob is dead. (!ral_msi_disable was intended β€” note the FreeBSD ancestor of this code, retained in the #else branch at lines 258-265, gates on ral_msi_disable == 0 correctly.)
  4. Cross-check: all 30+ other pci_alloc_1intr() callers in the tree pass a plain int <foo>_msi_enable/use_msi 0/1 variable (bge:2355, re:758, em:2488, msk:1562, jme:3752, drm_dragonfly.c:121, …).

Upstream parity: FreeBSD if_ral_pci.c has no pci_alloc_1intr (it uses pci_alloc_msi directly with ral_msi_disable == 0), so this is a DragonFly port artifact.

Impact

Operator-knob regression only (MSI cannot be disabled system-wide for ral except via the undocumented dev.ral.N.msi.enable=0 env hint). No memory safety, no privilege, no info-disclosure consequence β€” Info severity, defense-in-depth value only (the knob exists precisely to fall back to legacy INTx on quirky platforms).

Fix

One-token correction in fix.diff (~ β†’ !), generated mechanically from the tree and verified with patch --dry-run. A kernel build is not meaningful for a boolean-logic fix and no ral hardware exists on the guest.

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

One-token correction; generated mechanically from the tree, patch --dry-run OK. No runtime validation possible (no ral hardware); the change is self-evident boolean logic.

findings/poc/DF-4998/fix.diff (patch -p1 --dry-run: OK)
↓ fix.diffper-fix-DF-4998

Confirmed kernel references

Detail

Evidence (decisive lines)

VERDICT.md (4-step source proof with cross-tree caller comparison); fix.diff (~ -> ! , patch --dry-run verified)

PoC changes

No PoC authored: runtime observation needs ral hardware (guest has none); the defect is a boolean-logic certainty.

Verified recommended fix

Pass !ral_msi_disable instead of ~ral_msi_disable to pci_alloc_1intr()

Verdict

Static certainty, no runtime security impact. pci_alloc_1intr() (sys/bus/pci/pci.c:4348) uses its second parameter as a boolean enable flag (pci.c:4358 'if (msi_enable) ... pci_alloc_msi(...)'); if_ral_pci.c:254 passes ~ral_msi_disable, and ~0 == 0xFFFFFFFF as well as ~1 == 0xFFFFFFFE are both truthy, so MSI is attempted regardless of hw.ral.msi_disable - the documented-by-convention knob is a no-op and the intended operator is '!'. The FreeBSD ancestor (kept in the #else branch, if_ral_pci.c:258-265) correctly gates on ral_msi_disable == 0, and all 30+ other pci_alloc_1intr callers in the tree pass plain 0/1 enable variables (bge:2355, re:758, em:2488, drm_dragonfly.c:121, ...), so this is a DragonFly port artifact. Untested because observing the interrupt type requires Ralink hardware; the defect is pure boolean logic on a traced path.