# DF-4852 — dm_target_striped chunk-size validation bypass (signed int overflow)

## What

`dm_target_stripe_init()` (sys/dev/disk/dm/striped/dm_target_striped.c:98-99)
validates the chunk size with `int` arithmetic:

```c
chunksize = atoi64(argv[1]);              /* int */
if (chunksize < 1 || chunksize * DEV_BSIZE > MAXPHYS)   /* int * int */
        return EINVAL;
```

`chunksize * DEV_BSIZE` overflows for chunksize >= 2^22 (4194304*512 == 2^31,
wraps to INT_MIN) and for every larger value whose product wraps negative;
`INT_MIN > MAXPHYS` is false, so the guard passes. Chunk sizes up to
INT_MAX blocks (2^31-1 = 1 TiB of "chunk") are accepted — the intended cap
is MAXPHYS/DEV_BSIZE = 256 blocks (128 KB). Verified live: the kernel
accepted 4194304 and 2147483647 and rejected the non-overflow control
1048576 with EINVAL.

Impact: integrity/validation only (no kernel memory unsafety — the strategy
and dump math stay in bounds for any chunksize < 2^31, verified in the
finding). The loaded stripe geometry is not the geometry the check exists
to enforce; data placement silently collapses onto stripe device 0 for any
realistic device size. Requires privilege to load a table
(/dev/mapper/control is 0640 root:operator).

## Reproduce

Guest (as root), modules preloaded:

```sh
kldload dm                 # if not loaded
kldload dm_target_striped
cd /tmp/df4852 && cc -O -Wall -o dm_chunk dm_chunk.c -lprop
./dm_chunk
```

Expected (see run.log):

```
[case A] chunk=4194304     reload rv=0 (accepted)  EXPECTED: ACCEPT
[case B] chunk=1048576     reload rv=22 (Invalid argument)  EXPECTED: EINVAL
[case C] chunk=2147483647  reload rv=0 (accepted)  EXPECTED: ACCEPT
[case D] chunk=128         reload rv=0 (accepted)  EXPECTED: ACCEPT
[*] inactive table params: "2 4194304 <legs> ..."
[*] CONFIRMED: kernel accepted+stored chunk size 4194304 blocks ...
[PASS] 0 unexpected case results
```

plus kernel dmesg lines `dm: Stripe 2 devices chunk size 4194304KB` /
`2147483647KB` vs `dm: Error unsupported chunk size 524288KB` for the
control.

## Files

- `dm_chunk.c`   proplib dm-ioctl PoC (create/reload/table/remove_all)
- `build.sh`     guest build
- `run.sh`       guest run (kldloads modules first)
- `build.log` `run.log` `run.2.log` `dmesg_run.log` `env.txt`
- `fix.diff`     64-bit cast before the multiply
- `VERDICT.md`   full narrative
