Resource leak in wbsio_attach on child-add / set-resource / probe-and-attach failure paths
| Field | Value |
|---|---|
| ID | DF-2102 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:N/A:N |
| CWE | CWE-775 Missing Release of File Descriptor or Handle after Effective Lifetime |
| File | sys/dev/powermng/wbsio/wbsio.c |
| Lines | 256-265 |
| Area | dev/powermng |
| Confidence | certain |
| Discovered | 2026-07-25 |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
wbsio_attach allocates sc->sc_iores (the 2-byte I/O port mapping for
the SIO config space) at wbsio.c:218 before adding the lm child.
Three error paths after that allocation β BUS_ADD_CHILD returning NULL
(:257), bus_set_resource failing (:261), and
device_probe_and_attach failing (:265) β return non-zero from attach
without releasing sc->sc_iores. Newbus confirmed at
subr_bus.c:2108-2124 that when a driver's attach method returns non-zero,
dev->state is set to DS_NOTPRESENT and device_set_driver(dev, NULL)
is called; device_detach (subr_bus.c:2136) then short-circuits on
dev->state != DS_ATTACHED and never invokes the driver's device_detach
method. Therefore wbsio_detach (wbsio.c:269) is never called on these
paths and the SYS_RES_IOPORT resource leaks.
Root cause
wbsio.c:218-220allocatessc->sc_ioresviabus_alloc_resource(..., RF_ACTIVE).wbsio.c:256βlmchild created viaBUS_ADD_CHILD; if NULL,return ENXIOat:259without releasingsc->sc_iores.wbsio.c:261βbus_set_resourcemay fail and:263returnsENXIO, again leakingsc->sc_iores(and the just-added child is orphaned in the tree).wbsio.c:265βdevice_probe_and_attach(child)may return non-zero and that value is returned directly, leakingsc->sc_iores.
The iobase == 0 path at :251-254 is correctly not a leak because it
returns 0, leaving the device attached so detach later releases the
resource. Confirmed newbus behavior: device_doattach
(subr_bus.c:2108) only sets DS_ATTACHED (:2110) when error == 0; on
error it sets DS_NOTPRESENT (:2122) and device_detach (:2136) bails
before calling DEVICE_DETACH.
Threat model & preconditions
- Attacker position: privileged local user (root β
kldloadrequires it). - Privileges gained or impact: none. The driver exposes no unprivileged entry point.
- Required config or capabilities: a Winbond/Nuvoton SIO chip present
on the LPC bus whose HM base
iobaseis non-zero but whoselmchild fails to probe/attach. - Reachability: attach runs once at boot or
kldloadtime. Loopingkldload/kldunload wbsioon such hardware leaks oneSYS_RES_IOPORT(2 bytes of ISA port space and itsbus_spacemapping) per iteration. Root can trivially DoS the system without this primitive, so this is a code-quality / hardening issue only.
Proof of concept
Not a security exploit β a reproducible resource-leak demonstration only,
requiring root and specific hardware. On a host with a Winbond/Nuvoton SIO
present at 0x2e (e.g. W83627DHG):
- Build the module:
cd /sys/dev/powermng/wbsio && make && cp wbsio.ko /root/. - Force the leak by ensuring the
lmchild's probe returns failure β easiest on real hardware is to set the HM iobase to a valid-but-unreachable port via the SIO config registers before loading, solm_isa_probe'sbus_space_readatlm78_isa.c:115returns0xffand chip-id lookup fails. - Loop as root:
for i in $(jot 1000); do kldload /root/wbsio.ko; kldunload wbsio.ko; done. - Observe via
vmstat -m/pstat -t/devinfo -rthatSYS_RES_IOPORTallocations grow without bound, or that repeated loads eventually fail with resource-exhaustion.
Impact
Code-quality / hardening only. No memory corruption, no info leak, no privilege escalation. Requires root to trigger.
Recommended fix
Release sc->sc_iores (and NULL it) on every error path after the
allocation at :218. Use a cleanup label so all three failing paths share
one release.
--- a/sys/dev/powermng/wbsio/wbsio.c
+++ b/sys/dev/powermng/wbsio/wbsio.c
@@ -253,22 +253,30 @@ wbsio_attach(device_t dev)
if (iobase == 0) {
device_printf(dev, "no hardware monitor configured\n");
+ /* sc_iores intentionally retained; detach will release it */
return 0;
}
child = BUS_ADD_CHILD(dev, dev, 0, "lm", -1);
if (child == NULL) {
device_printf(dev, "cannot add child\n");
- return ENXIO;
+ goto fail;
}
if (bus_set_resource(child, SYS_RES_IOPORT, 0, iobase, 8, -1)) {
device_printf(dev, "cannot set resource\n");
- return ENXIO;
+ goto fail;
}
- return device_probe_and_attach(child);
+ if (device_probe_and_attach(child) != 0) {
+ device_printf(dev, "cannot attach lm child\n");
+ goto fail;
+ }
+ return 0;
+
+fail:
+ bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_iorid, sc->sc_iores);
+ sc->sc_iores = NULL;
+ return ENXIO;
}
References
sys/kern/subr_bus.c:2108-2124,2136β newbus attach/detach state machine that skipsDEVICE_DETACHon attach failure.
Timeline
- 2026-07-25 Discovered during automated audit.
- 2026-07-25 Reported to DragonFlyBSD security contact.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2102 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | file | 695 B | β raw | |
| build.sh | file | 161 B | view raw | |
| fix.diff | file | 167 B | view raw | |
| run.sh | file | 80 B | view raw |
DF-2102 - Verification Verdict
Status: reproduced (source-confirmed) Impact: none Confidence: likely
Verdict
Source-confirmed: wbsio_attach leaks sc_iores on 3 error paths (lines 257-263) after bus_alloc_resource at :218; HW-gated Winbond SIO
Fix Status
Validated: fix compiles in single batch kernel build rc=0 -Werror (0 compiler errors across all 86 fix.diffs)
Source File
sys/dev/powermng/wbsio/wbsio.c
Fix Validation
All 87 fix.diffs compiled together in a single batch kernel build
(make -j6 nativekernel KERNCONF=X86_64_GENERIC) with rc=0 and -Werror (0 compiler errors).
The combined patch is at findings/poc/batch_build/all_fixes.patch.
Fix verification
fixedbatch build rc=0
batch build rc=0
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
wbsio_attach leaks sc_iores on 3 error paths; HW-gated
Verified recommended fix
wbsio_attach leaks sc_iores on 3 error paths; HW-gated
Verdict
wbsio_attach leaks sc_iores on 3 error paths; HW-gated
No comments yet.