# DF-0883 — Unvalidated logical block size `lb_size` → divide-by-zero panic

## Summary

In `udf_mountfs()` (`sys/vfs/udf/udf_vfsops.c:306`), the Logical Volume
Descriptor's `lb_size` field — a `uint32_t` read verbatim from the on-disk
image — is assigned to `udfmp->bsize` with no validation. When `lb_size=0`,
`udf_find_partmaps()` at line 667 divides `packet_len / bsize` →
**integer divide fault (#DE) → kernel panic** at mount time.

A crafted UDF image with `lb_size=0` and a Type 2 Sparable partition map
triggers a deterministic single-shot panic.

## Reproduce

```sh
# On the host (python3 available): craft the image
cd findings/poc/DF-0883
./build.sh                    # produces evil.udf (lb_size=0, packet_len=2048)

# On the DragonFlyBSD guest (root):
scp evil.udf run.sh dfbsd:/root/poc/
ssh dfbsd 'cd /root/poc && mkdir -p /mnt/udf && sh run.sh'
```

### Expected behavior

- **Unpatched kernel/udf.ko (`#0`):** mount panics — `Fatal trap 18: integer
  divide fault ... Stopped at udf_mount.part.2+0x814: idivl`
- **Fixed udf.ko:** mount returns `EINVAL` cleanly (`udf: invalid logical
  block size 0`), guest stays up

## Files

| File | Description |
|------|-------------|
| `craft_evil_udf.py` | Python UDF image crafter (lb_size=0, packet_len=2048) |
| `evil.udf` | Crafted image (614400 bytes) |
| `build.sh` | Runs crafter (or uses pre-built image) |
| `run.sh` | vnconfig + mount commands |
| `fix.diff` | git-apply-able fix: validate lb_size as power-of-2 in [512,65536] |
| `VERDICT.md` | Full analysis: mechanism, evidence, fix validation |
| `run.log` | Unpatched kernel panic output |
| `fix_run.log` | Patched module clean output |
| `fix_build.log` | Module build log |
| `panic.txt` | Panic signature from serial console |
| `env.txt` | Guest environment |
| `manifest.json` | Machine-readable catalog |
