mn_attach error-path asymmetry: discarded BAR resource handles (unreleasable), leaking ENXIO returns, failures reported as attach success, dangling sc->node after node destruction, and no device_detach
Summary
Both memory-BAR handles live only in a local variable (only the virtual/physical values are stored) so they can never be released; each early ENXIO leaks everything allocated before it. Failures are returned as SUCCESS (bus-master-test failure, ng_make_node failure). The ng_name_node failure path destroys the node while sc->node keeps the dangling pointer in the still-live softc with interrupts registered - and still returns success. No device_detach exists at all. Deterministic source demonstration (0 release/0 detach occurrences). Bookkeeping + fail-correctly + NULL-the-pointer fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4343 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 3.8 KB | β raw | |
| VERDICT.md | β | 2.3 KB | β raw | |
| run.sh | β | 181 B | view raw | |
| run.log | β | 258 B | view raw | |
| env_guest.txt | β | 569 B | view raw | |
| fix.diff | β | 2.9 KB | view raw | |
| verdict.json | β | 2.8 KB | view raw | |
| manifest.json | β | 678 B | view raw |
DF-4343 β mn_attach error-path asymmetry: unreleasable/leaked BARs, success-returned failures, dangling sc->node, no detach
- File:
sys/dev/netif/mn/if_mn.c - Lines: 1301-1317 (BAR allocs;
struct resource *reslocal-only), 1324-1335 (leaking ENXIO returns), 1353-1355 (mn_reset failure returns success), 1386-1389 (ng_make_node_common failure returns success), 1392-1396 (name-failure frees node, softc keeps dangling pointer, returns success), 1402-1411 (no device_detach) - Severity: Low (privileged attach-time/hardware-error paths; resource-exhaustion and dangling-pointer hygiene, no direct unprivileged trigger)
- CVSS:
CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:L/A:L - CWE: CWE-772 (protected resource not freed) / CWE-404 (improper shutdown) / CWE-252 (unchecked return)
- Confidence: certain (plain code reading)
Summary
mn_attach violates attach error-path symmetry in five distinct ways:
-
BAR
struct resource *handles are discarded. Both memory BAR allocations use a localres(if_mn.c:1302,:1311); onlyrman_get_virtual()/rman_get_start()are saved into the softc (:1307-1308,:1316-1317). The resource handles themselves are never stored, so they can never bebus_release_resource'd β on the success path they are held forever, and on every error return below they leak. -
Each early ENXIO leaks everything allocated before it: second-BAR failure leaks BAR0 (
:1311-1315); IRQ-alloc failure leaks both BARs (:1324-1327);bus_setup_intrfailure leaks both BARs plus the IRQ (:1332-1335). Failed attaches can be repeated (rescan, slot churn) and accumulate leaked bus resources. -
Failure returned as success. When the controller fails the PCI bus-master test,
mn_resetreturns 0 and attach doesif (!u) return (0);(:1353-1355) β the device reports attach SUCCESS while non-functional, with the interrupt live and no netgraph node. Likewiseng_make_node_commonfailure prints andreturn (0)(:1386-1389). -
Name-failure path frees the node but leaves
sc->nodedangling (:1392-1396):ng_rmnode+ng_unrefdrop the creation reference (node refs β 0 β kfree) β notengmn_shutdownis a no-op returning EINVAL (if_mn.c:280-285) song_cutlinksnever runs β and the softc (still referenced bydevice_set_softc, interrupts live) keeps pointing at freed memory forever. Returns success (0) on top. -
No
device_detachmethod at all (:1402-1411): IRQ teardown, resource release, softc free and netgraph node removal are impossible; hot-unplug or module unload leaks the softc, both BARs, the IRQ and the node.
Threat
Attacker relevance is indirect: repeated failed attaches (card mis-seated /
bus-master-disabled slot / IRQ exhaustion) leak kernel bus resources
(CWE-772), and the dangling sc->node (item 4) is a latent UAF pointer that
future code paths touching sc->node would dereference. Requires the mn
hardware and privileged (re)scan operations β hence Low.
Exploit / PoC
No runnable PoC beyond source inspection is possible on the audit guest
(no card, driver not built β see run.log / env_guest.txt). Deterministic
source-level demonstration: grep -n "bus_release_resource" if_mn.c β no
matches; grep -n "device_detach" if_mn.c β no matches; the five code
sites cited above.
Recommended fix
Retain both BAR handles in the softc and release them (plus the IRQ) on
every error path; return ENXIO on mn_reset/ng_make_node_common
failure; on name failure set sc->node = NULL after destroying the node and
return ENXIO; add a device_detach implementing the inverse of attach.
See fix.diff for the minimal resource/return-value half (full detach
requires lifecycle work out of scope for a minimal patch).
DF-4343 VERDICT
Status: inconclusive on this guest (defect is static/plain-code) reproduced: 0 Β· impact on this guest: none Β· confidence: certain
All five defects are verifiable by direct source reading and greps; nothing depends on runtime hardware behavior:
reslocals atif_mn.c:1302/:1311are never stored instruct softc(fieldsm0v/m0p/m1v/m1phold only virtual/physical values,if_mn.c:1307-1308,:1316-1317);grep -n bus_release_resource sys/dev/netif/mn/if_mn.cβ no matches (resources unreleasable by construction).- Early returns at
:1314,:1326,:1334discard previously allocated resources. :1353-1355if (!u) return (0);β mn_reset failure reported as attach success.:1386-1389ng_make_node_commonfailure βreturn (0).:1392-1396name failure:ng_rmnode+ng_unreffree the node (refs 1β0 via the no-opngmn_shutdownatif_mn.c:280-285, which never callsng_cutlinks), leavingsc->nodedangling in the still-live softc, thenreturn (0).:1402-1411device_methods contains nodevice_detach.
Guest verification attempt (see run.log): no 0x110a PCI device, driver not
built (optional mn netgraph), kldload if_mn ENOENT β attach paths cannot
be exercised at runtime on this guest; classification inconclusive for the
reproduction while the defect itself is certain from source.
Fix: fix.diff (git apply --check clean): retain both BAR handles in the
softc (mem0, mem1), release them + the IRQ on every error path, return
ENXIO on mn_reset / ng_make_node_common / ng_name_node failures, NULL the
node pointer after destroying it. A full device_detach is additionally
recommended upstream but is intentionally out of the minimal patch.
Files
README.md, VERDICT.md, run.sh, run.log, env_guest.txt, fix.diff, verdict.json, manifest.json (no runtime trigger exists for this class; source-level citations are the demonstration).
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_testableNo baseline possible on this guest (hardware absent). fix.diff is line-accurate (git apply --check clean) and restores error-path symmetry for every cited site except the still-recommended full device_detach.
findings/poc/DF-4343/fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
README.md (five cited sites); VERDICT.md; run.log (guest greps: 0 releases / 0 detach; hardware absent); fix.diff (git apply --check OK)
PoC changes
no runtime trigger exists for this class; source citations + guest greps are the demonstration
Verified recommended fix
Retain both BAR resource handles in softc, release them + IRQ on every error path, return ENXIO on mn_reset/node-creation/name failures and NULL sc->node after destroying it; add device_detach (fix.diff carries the minimal half)
Verdict
Static, deterministic defect class (attach error-path symmetry); runtime paths unreachable on the audit guest (no Munich32X PCI device, driver 'optional mn netgraph' not built, kldload ENOENT). Verified from source: both BAR struct resource handles are stored only in the local 'res' and discarded (if_mn.c:1302,1311) so they can never be released; the ENXIO returns at 1314, 1326, 1334 leak every previously allocated resource; mn_reset failure and ng_make_node_common failure return 0 = attach success (1353-1355, 1386-1389); the ng_name_node failure path frees the node (ng_rmnode+ng_unref, refs 1->0 because ngmn_shutdown is a no-op returning EINVAL) while sc->node keeps the dangling pointer and attach still reports success (1392-1396); there is no device_detach at all (1402-1411). Guest-side grep confirmation in run.log: 0 bus_release_resource, 0 device_detach in the file.
No comments yet.