# DF-2831 — dssize()/diskpsize consume dp->d_slice without ds_token; DSO_RAWPSIZE fallback then substitutes whole-disk size for partitions

* Verified 2026-09-01, DragonFly 6.5-DEVELOPMENT x86_64 guest (QEMU/KVM),
  stock INVARIANTS kernel #0 Thu Jul 2 06:02:54 UTC 2026, then instrumented
  and fixed kernels built in-guest with `make nativekernel`.
* File: sys/kern/subr_diskslice.c (dssize :836-871), consumer wired from
  sys/kern/subr_disk.c diskpsize :1259-1276 (+ DSO_RAWPSIZE fallback
  :1270-1274), racing disk_probe replacement :367-368/:494 via
  disk_msg_core under ds_token.
* Bucket: memcorrupt. Severity: Medium. Confidence: certain.

## TL;DR verdict

REPRODUCED on the stock guest: racing swapon (d_psize -> dssize) against
root-forced reprobes (DIOCSYNCSLICEINFO arg=1) makes the kernel install a
**wrong swap geometry silently**: 125-277 of every 2000 swapon cycles
returned the whole-disk size (16384 blocks) for partition vn0s1a whose real
label says 4096 blocks — verified against a same-instant DIOCGDINFO64 probe
showing the in-core label was CORRECT (so the value did not come from the
label). With kprintf instrumentation between the racy reads (build #1) the
same race produced a **fatal trap 12 page fault in dssize+0x15c
(`movq 0x40(%rax),%rax`, fault addr 0x40)** — the ENTER/WALK traces show
dssize walking an older generation of `struct diskslices`
(...6a00 vs current ...7c00) whose label/ops pointers were freed — the
guest died at the ddb prompt. The token fix (diskpsize takes ds_token
around dssize + dssize revalidates slice bounds) removes the UAF walk and,
together with suppressing the DSO_RAWPSIZE whole-disk substitution for
partition devices, drives the wrong-geometry anomalies to 0/2000 and 0/2000
with clean ENXIO failures instead (fix kernel #3).

## Evidence

* run.log / fix_run.log — stock vs patched counters
* panic.txt — full serial console trace: DF2831 ENTER/WALK pointer
  generations, fatal trap 12, `Stopped at dssize+0x15c`
* fixinst trace (in VERDICT.md) — 219x "blocks=-1 nolabel" matched 1:1 with
  219x "RAWPSIZE fallback -> raw whole-disk size" = provenance of the
  wrong value on the token-fixed kernel (label loss is the DF-2742
  diskstrategy family; the fallback misdesign turns it into silent
  wrong geometry)
* fix.diff — ds_token in diskpsize + dssize/dsopen bounds revalidation +
  RAWPSIZE fallback restricted to whole-disk/whole-slice devices

## Reproduce

see build.sh / run.sh. Root on the guest; ~90 s per 2000-iteration run.
