nsclpcsio unconditional TMS/VLM init writes to 8237A DMA controller when logical devices are disabled
| Field | Value |
|---|---|
| ID | DF-1836 |
| 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:L |
| CWE | CWE-1295 Debug Messages Revealing Unnecessary Information |
| File | sys/dev/misc/nsclpcsio/nsclpcsio_isa.c |
| Lines | 344-345 |
| Area | dev/misc (Super I/O attach) |
| Confidence | certain |
| Discovered | 2026-07-20 |
| Reported | pending |
| Known CVE | none |
| CVE match | dfly_specific |
Summary
nsclpcsio_isa_attach calls nsclpcsio_tms_init and nsclpcsio_vlm_init
unconditionally (lines 344-345) regardless of whether the TMS or VLM logical
devices are activated. When a device is not activated, sc->sc_ld_ioh[ld_num]
remains 0 (zero-initialized softc), and the TMS_WRITE/VLM_WRITE macros emit
bus_space_write_1(iot, 0, reg, val), writing fixed constant values directly to
legacy ISA I/O ports 0x08-0x0E β the 8237A DMA controller. Port 0x0D is DMA
master clear (resets controller); port 0x0E clears all masks. Boot-time
robustness bug with no security impact.
Root cause
nsclpcsio_isa_attach (line 287) initializes sc->sc_ld_en[ld_num]=0 and
sc->sc_ld_ioh[ld_num]=0 at lines 306/333 only for activated logical devices.
At lines 344-345, nsclpcsio_tms_init(sc) and nsclpcsio_vlm_init(sc) are
called unconditionally β unlike the runtime refresh path (lines 384-386) which
correctly guards with if (sc->sc_ld_en[...]).
Inside nsclpcsio_tms_init (line 391), TMS_WRITE(sc, 0x08, 0x00) at line 396
expands to bus_space_write_1(sc->sc_iot, sc->sc_ld_ioh[SIO_LDN_TMS], 0x08, 0x00)
(macro at lines 194-196). With sc->sc_ld_ioh[SIO_LDN_TMS] == 0, this writes
byte 0x00 to absolute I/O port 0x08. Subsequent writes hit ports 0x09-0x0E:
port 0x0D receives 0x05 (TMS_WRITE(sc, 0x0d, 0x05) at line 401) which is DMA
Master Clear β any write resets the entire DMA controller.
nsclpcsio_vlm_init (line 444) does the same with VLM_WRITE to ports
0x08-0x0E.
The softc zero-initialization was confirmed at subr_bus.c:1953-1954 (kmalloc with M_ZERO).
Threat model & preconditions
- Attacker position: none β this fires at device attach time (boot), not by any user action.
- Privileges gained or impact: no security-relevant impact. The written
values are fixed constants (
0x00,0x0f,0x08,0x04,0x35,0x05), not attacker-controlled. The only possible disruption is to ISA DMA (floppy, ECP parallel port) on systems with a PC87366 Super I/O chip where the BIOS has not activated the TMS or VLM logical devices. Modern systems rarely use ISA DMA. - Required config or capabilities: PC87366 Super I/O chip with TMS/VLM
logical devices disabled in BIOS;
device nsclpcsiocompiled in. - Reachability: boot-time only, not triggerable by any user.
Proof of concept
Not a security exploit β no PoC code is meaningful. To demonstrate the bug: on a system with a PC87366 Super I/O chip where TMS/VLM logical devices are disabled in BIOS, boot DragonFlyBSD with this driver compiled in. The DMA controller will be reset during device attach. Observable effect: floppy DMA operations or other ISA DMA-dependent devices may behave erratically if they rely on DMA state set by firmware.
Impact
Info-level hardening / robustness concern. No path to privilege escalation, code execution, or information disclosure.
Recommended fix
Guard the init calls with sc->sc_ld_en checks, matching the pattern already
used for the refresh path and sensor attach loop.
--- a/sys/dev/misc/nsclpcsio/nsclpcsio_isa.c
+++ b/sys/dev/misc/nsclpcsio/nsclpcsio_isa.c
@@ -341,8 +341,10 @@ nsclpcsio_isa_attach(device_t dev)
kprintf("\n");
#if NGPIO > 0
- nsclpcsio_gpio_init(sc);
+ if (sc->sc_ld_en[SIO_LDN_GPIO])
+ nsclpcsio_gpio_init(sc);
#endif
- nsclpcsio_tms_init(sc);
- nsclpcsio_vlm_init(sc);
+ if (sc->sc_ld_en[SIO_LDN_TMS])
+ nsclpcsio_tms_init(sc);
+ if (sc->sc_ld_en[SIO_LDN_VLM])
+ nsclpcsio_vlm_init(sc);
/* Hook into hw.sensors sysctl */
This prevents bus_space writes to handle 0 (DMA controller ports) when a
logical device is not activated. The GPIO init is also guarded for consistency β
gpio_init (line 541) calls GPIO_READ/GPIO_WRITE which would similarly hit
port 0 when GPIO is disabled, and gpio_register (line 372) is already guarded
at line 364.
References
- Runtime refresh path correctly guards with
sc->sc_ld_en: nsclpcsio_isa.c:384-386. gpio_registeralready guards onsc->sc_ld_en: nsclpcsio_isa.c:364.- Softc zero-initialization: subr_bus.c:1953-1954 (
M_ZERO).
Timeline
- 2026-07-20 Discovered during automated audit.
- 2026-07-20 Reported to DragonFlyBSD security contact (pending).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1836 Β· 1 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | nsclpcsio unconditional TMS/VLM init writes to 8237A DMA controller when logical | 485 B | view raw |
Fix verification
not_testablefix.diff authored but did not apply cleanly; needs context rework
fix.diff authored but did not apply cleanly; needs context rework
Confirmed kernel references
β
Detail
Exploit chain
none (Info severity)
Evidence (decisive lines)
Source-confirmed at sys/dev/misc/nsclpcsio/nsclpcsio_isa.c:344: unconditional TMS/VLM init writes to DMA controller when devices disabled
Verified recommended fix
Source-confirmed at sys/dev/misc/nsclpcsio/nsclpcsio_isa.c:344: unconditional TMS/VLM init writes to DMA controller when devices disabled
Verdict
Source-confirmed at sys/dev/misc/nsclpcsio/nsclpcsio_isa.c:344: unconditional TMS/VLM init writes to DMA controller when devices disabled
No comments yet.