# DF-4750 — VERDICT

**Status: REPRODUCED (logic bug in the TIOCCDTR handler; fix validated by
patched-module A/B).** Impact: functional only (modem-line state machine lies
to userland); no memory safety, no privilege boundary. Severity Info.

## Root cause

sys/dev/misc/nmdm/nmdm.c:561-566 in `nmdmioctl()`:

```c
case TIOCSDTR:
        ourpart->modemsignals |= TIOCM_DTR;
        break;
case TIOCCDTR:
        ourpart->modemsignals &= TIOCM_DTR;     /* line 565: missing ~ */
        break;
```

`TIOCCDTR` ("clear DTR") ANDs the signal word *with* the DTR bit instead of
with its complement. Net effect: DTR survives, and every other local modem
bit (TIOCM_LE, TIOCM_RTS, ...) is zeroed. Downstream,
`nmdm_crossover()` (nmdm.c:606-616) recomputes the peer's CTS/CAR from
RTS/DTR, so the stuck DTR also keeps the peer's carrier (TIOCM_CAR) up —
userland that drops DTR to hang up the link (classic nmdm/pty usage in
termios-compatible programs, e.g. `cu`/`tip`-style state machines) never
sees carrier drop on the peer.

## Reproduction

Unprivileged user, live guest (run.log):

```
TIOCMSET(LE|DTR|RTS)    -> TIOCMGET = 0x0007   (LE=1 DTR=1 RTS=1)
TIOCCDTR                -> TIOCMGET = 0x0002   DTR=SET (bug), RTS/LE wiped (bug)
```

The ioctl marshalling is safe (`sys_ioctl` pre-copies IOC_IN data to a kernel
buffer, sys/kern/sys_generic.c:679-697), so the direct `*(int *)ap->a_data`
writes in the handler operate on kernel scratch — the bug is purely the mask.

## Fix validation

fix.diff (`&= ~TIOCM_DTR`) applied together with the DF-4749 fix in one
rebuilt nmdm.ko on the guest (fix_build.log), module swapped, re-run
(fix_run.log):

```
TIOCMGET after TIOCCDTR = 0x0005 -> DTR=clear [correct] RTS=SET [correct]
```

Bug gone; the two findings share the same A/B module cycle.

## 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.
