# DF-4149 — zero-length iovec ⇒ unkillable read loop in cuse_client_read/write

## What (reproduced)

`cuse_client_read()` (`cuse.c:1687-1741`) and `cuse_client_write()`
(`cuse.c:1778-1832`) walk the uio directly:

```c
while (uio->uio_resid != 0) {
        len = uio->uio_iov->iov_len;      /* can be 0 (empty first iov) */
        ... send CUSE_CMD_READ, wait for server ...
        else if (error == len)            /* 0 == 0 */
                error = uiomove(NULL, 0, uio);   /* no progress */
```

`uiomove()` with count 0 never advances `uio_iov` past the empty iov, so
the loop re-sends a 0-length READ/WRITE command forever.  `readv(fd,
[{NULL,0},{buf,8}], 2)` from any user able to open the cuse device node
triggers it (DFly's `iovec_copyin` does not drop empty iovs).

Worse, after the first signal `cuse_client_receive_command_locked`
(`cuse.c:622-635`) switches from `cv_wait_sig` to the uninterruptible
`cv_wait`, and each loop iteration blocks again waiting for the next
server round-trip, so **SIGKILL is never delivered** for as long as the
server keeps replying: the reader is an unkillable process.

Reproduced (run.log): client (uid 65534) survives `kill -9`; it is only
released when the server disappears (`is_closing`).  If the stuck client
holds an inherited/duplicated `/dev/cuse` fd (trivially arranged — observed
accidentally during DF-4147 harness work), `is_closing` is never set and
the process is **permanently unkillable (D-state) until reboot**, pinning
the cuse client (~12 KB) and server objects forever.

## Fix

`fix.diff`: skip leading zero-length iovs exactly like `uiomove()` does,
in both readers.

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