disklabel64 read-path trust: crafted-media partition fields yield OOB absolute-media-offset I/O β cross-slice access, mod-2^64 wraparound slice escape, and ds_reserved EROFS label-area write bypass (concrete impact upgrade of DF-0134)
| Field | Value |
|---|---|
| ID | DF-2910 |
| Status | new |
| Severity | Medium |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H |
| CWE | CWE-20 / CWE-1284 |
| File | sys/kern/subr_disklabel64.c |
| Lines | 183-193 (consumer: subr_diskslice.c:206-212, 280-281) |
| Area | kern/disk |
| Confidence | certain |
| Discovered | 2026-09-02 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | base:kern |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
l64_readdisklabel accepts any CRC-valid on-media disklabel64 with completely uncontained p_boffset/p_bsize/d_bbase/d_total_size (only magic, d_npartitionsβ€16 and CRC are checked; whole struct copied in-core). The kernel auto-parses such labels at media attach for BSD-typed MBR slices and creates partition devices for them. dscheck then routes partition I/O via l64_getpartbounds computing nbio->bio_offset = (sp->ds_offset + slicerel_secno) * dss_secsize with NO containment check against sp->ds_size and mod-2^64 wrap β unlike the WHOLE_DISK/WHOLE_SLICE branches which use ds_size. Demonstrated on the guest (vn, 3/3 deterministic): (a) cross-slice read β /dev/vn0s1a of a 1MiB slice with p_boffset=2MiB returned slice s2's marker at abs LBA 6144; (b) backwards wraparound β p_boffset=2^64-983040 made the kernel report media_offset=65536 and /dev/vn0s1b read abs LBA 128, BEFORE the slice start; (c) universal window β one partition with p_boffset=p_bsize=2^64-512 yields a 2^55-1-sector window whose user-relative seeks map to arbitrary absolute offsets; (d) EROFS bypass β a write to slice-rel sector 1 via the whole-slice device is correctly rejected EROFS, but the same byte via the crafted partition succeeded and clobbered the on-disk label magic at abs LBA 2049 ('PWNED-PARTITION-WRITE' read back raw). No panic, guest stable β DF-0134's old 'offset overflow panic' speculation disproven; the real impact is clean, kernel-mediated OOB read/write at attacker-chosen absolute media offsets. Not kernel-memory corruption; no unprivileged local trigger (partition nodes root:operator 0640; install path separately bounded per DF-0135). Attacker crafts media; root/automount attaches β cross-slice data theft and targeted corruption (MBR, foreign labels, other OS partitions) on that disk.
Proof of contest
VERIFIED (findings/poc/DF-2910/): makeimg.py builds the crafted 16MiB image; all four primitives observed 3/3 on stock kernel #0 (cross-slice marker, wraparound LBA-128 marker, universal window, EROFS bypass write at abs LBA 2049). Fix validated on rebuilt kernel #1: crafted label rejected ('cannot find label (disklabel64 corrupted, partition)'), valid contained label still installs with working I/O and intact EROFS. userβroot: N/A β disk-data redirection, not kernel memory corruption; escalation ceiling is corruption of other slices' data (e.g. another OS partition's setuid binaries) on media root attaches.
Recommended fix
Structural validation in l64_readdisklabel (total/boot area and every partition sector-aligned, no-wrap, contained within sp->ds_size Γ secsize) β validated fix.diff in findings/poc/DF-2910/.
Timeline
- 2026-09-02 Discovered during pass-2 audit of subr_disklabel64.c (GLM 5.3); all four primitives reproduced + fix validated same run.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2910 Β· 20 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 3.6 KB | β raw | |
| VERDICT.md | β | 5.2 KB | β raw | |
| makeimg.py | β | 5.5 KB | view raw | |
| df2910.img | β | 16.0 MB | β download | |
| valid.img | β | 16.0 MB | β download | |
| probe.c | β | 722 B | view raw | |
| wprobe.c | β | 740 B | view raw | |
| dump.c | β | 950 B | view raw | |
| pinfo.c | β | 599 B | view raw | |
| run.sh | β | 1.5 KB | view raw | |
| run.log | β | 1.9 KB | view raw | |
| run.2.log | β | 1.9 KB | view raw | |
| run.3.log | β | 1.9 KB | view raw | |
| run.fixed.log | β | 552 B | view raw | |
| run.fixed2.log | β | 582 B | view raw | |
| build.log | β | 4.6 KB | view raw | |
| env.txt | β | 266 B | view raw | |
| fix.diff | β | 2.5 KB | view raw | |
| verdict.json | β | 5.5 KB | view raw | |
| manifest.json | β | 1.4 KB | view raw |
DF-2910 β disklabel64 read-path trust β arbitrary absolute-media-offset I/O via partition devices of crafted media
Impact upgrade of DF-0134 (which established the missing structural validation; this pack concretely demonstrates and fixes the resulting I/O redirection primitives).
What was proven (baseline, stock INVARIANTS kernel #0, 3/3 deterministic runs)
Attacker-controlled media (image file / USB disk) containing a CRC-valid disklabel64
with uncontained partition fields is auto-parsed by the kernel at attach time
(disk_probe β disk_probe_slice, sys/kern/subr_disk.c:491). l64_readdisklabel
(sys/kern/subr_disklabel64.c:145-201) checks only magic / d_npartitions<=16 / CRC β
never bounds. Partition devices are then created, and dscheck
(sys/kern/subr_diskslice.c:206-212,280-281) routes their I/O using
(sp->ds_offset + slicerel_secno) * dss_secsize β mod-2^64 arithmetic with no
containment check against the slice:
- Cross-slice read/write β
p_boffsetbeyond the slice end:/dev/vn0s1a(partition of the 1 MiB slice s1) reads/writes slice s2's data at absolute LBA 6144. β slice isolation broken; a mounted attacker slice can read/modify other slices of the same disk (e.g. an OS partition, the running system's raw data). - Wraparound slice escape (backwards) β
p_boffset = 2^64-983040:(2048 + 2^55-1920)*512 mod 2^64 = 65536β/dev/vn0s1breads absolute LBA 128, before the slice start (kernel itself reportsmedia_offset=65536via DIOCGPART). - Universal window β one partition
p_boffset = p_bsize = 2^64-512yields a 2^55-sector window (media_offset=LBA 2047, media_blocks=2^55-1); the user's own partition-relative seek selects the absolute target. - EROFS label-area protection bypass β writing slice-rel sector 1 via the
whole-slice device is correctly rejected
EROFS(ds_reserved=8), but the same byte written through the crafted partition (slicerel_secno β 2^55β not< ds_reserved) succeeds:write(/dev/vn0s1c, sec=2) = 512and the on-disk label magic at absolute LBA 2049 is overwritten ("PWNED-PARTITION-WRITE" on raw read-back).
No panic; guest stays up; primitives are fully controlled read/write at attacker-chosen absolute media offsets. Ceiling: with root attaching/opening attacker media (automount, vnconfig, USB), all slice/label protections on that disk are void β cross-slice data theft and targeted corruption (MBR, foreign labels, other OS's data). It is disk-data redirection, not kernel-memory corruption.
Build / run (in guest, as root)
# host: generate the crafted image (python3, no deps) python3 makeimg.py df2910.img # guest: attach; kernel auto-probes the crafted label vnconfig -c vn0 /root/df2910.img sh run.sh # full sequence: dump label, 3 read primitives, EROFS control+bypass
Expected (vulnerable kernel): SLICE2-SECRET-MARKER via vn0s1a,
SECTOR128-SECRET-MARKER via vn0s1b, EROFS via vn0s1 control, write=512 ok via
vn0s1c and PWNED-PARTITION-WRITE at raw LBA 2049.
Expected (patched kernel): vn0s1: cannot find label (disklabel64 corrupted,
partition) in the message buffer; only /dev/vn0s1 exists; every primitive absent;
valid labels (valid.img) still install with working partition I/O and EROFS intact.
Fix
fix.diff adds structural validation to l64_readdisklabel (label total/boot-area and
every partition bounded within sp->ds_size * secsize, sector-aligned, wrap-safe
sums). Validated in-guest: baseline reproduces, patched kernel rejects the crafted
label and accepts valid ones (run.fixed.log, run.fixed2.log).
DF-2910 VERDICT β reproduced / OOB I/O (disk-data redirection, slice escape, EROFS bypass)
Classification
- status: reproduced (3/3 deterministic baseline runs; no panic; guest stable)
- impact: dos-level ceiling is not the point β this is out-of-bounds I/O: kernel-mediated read/write at attacker-chosen absolute media offsets through partition devices created from attacker-crafted media. Not kernel-memory corruption; disk-data boundary break.
- confidence: certain β every step traced to source and demonstrated empirically.
Root cause chain (path:line)
sys/kern/subr_disk.c:491β every BSD-type MBR slice is label-probed at attach (disk_probe_slice), zero user interaction beyond media presence.sys/kern/subr_disklabel64.c:183-187βl64_readdisklabelvalidates onlyd_magic,d_npartitions<=16, CRC.p_boffset/p_bsize/d_bbase/d_total_sizeare never checked against the media/slice (this is the DF-0134 gap).sys/kern/subr_disk.c:228-269β partition devices are created for every partition with nonzerop_fstype, regardless of geometry.sys/kern/subr_diskslice.c:206-212βdschecktakesstart/blocksstraight froml64_getpartbounds(subr_disklabel64.c:64-82) with no clamp tosp->ds_size(contrast the WHOLE_DISK/WHOLE_SLICE branches at :189/:197 which useds_size).sys/kern/subr_diskslice.c:280-281βnbio->bio_offset = (off_t)(sp->ds_offset + slicerel_secno) * ssp->dss_secsizeβ mod-2^64 arithmetic: hugep_boffsetwraps the product to any small absolute offset; the EROFS reserved check at :227 (slicerel_secno < sp->ds_reserved) never fires because the wrappedslicerel_secnois astronomically large.
What was demonstrated (baseline, kernel #0 stock INVARIANTS)
- Cross-slice read:
/dev/vn0s1a(partition of 1 MiB slice s1,p_boffset=2 MiB) returnedSLICE2-SECRET-MARKERliving in slice s2 (abs LBA 6144) β run.log Β§1. - Wraparound backwards read:
p_boffset=0xffffffffff10000β kernel-reportedmedia_offset=65536(DIOCGPART) β/dev/vn0s1breturned the marker at abs LBA 128, before the slice start β run.log Β§2. - Universal window:
p_boffset=p_bsize=0xfffffffffffffe00βmedia_blocks=2^55-1(16 EiB) partition whose user-relative seeks map to arbitrary absolute offsets β run.log Β§3/pinfo. - EROFS bypass write: control write via
/dev/vn0s1at slice-rel sec 1 βEROFS(errno 30); identical byte via/dev/vn0s1cat sec 2 βwrite()=512 ok, raw read-back at abs LBA 2049 showsPWNED-PARTITION-WRITEβ the on-disk label magic clobbered through a partition device. run.log Β§4-6. - Stable across runs (run.log, run.2.log, run.3.log); guest alive; no panic.
Threat model
Unprivileged attacker supplies the media (USB stick, disk image, cloud volume); root (or
an automount daemon) attaches it and the kernel auto-parses the label. Partition devices
appear root:operator 0640. Root opening/mounting the crafted slice gives the attacker
cross-slice read/write of the same physical disk β including the MBR, foreign labels,
and other OS partitions β plus voiding of the label-area EROFS protection. On the PoC
guest the trigger is vnconfig (root). Severity Medium: powerful primitive, but requires
privileged attach/open of attacker media (no unprivileged local trigger found; the
DIOCSDINFO/WDINFO64 install path is separately bounds-checked in l64_setdisklabel
modulo DF-0135).
PoC changes vs. seed
Seed sketch did not exist (finding filed from this run). Generator initially computed the
wrap p_boffset as target - ds_offset*512 per-partition; corrected after guest
ground-truth (DIOCGPART media_offset) showed the general form: backwards reach comes
from (ds_offset + p_boffset/512)*512 mod 2^64 β best expressed as one partition with
p_boffset = p_bsize = 2^64-512 plus a user seek. CRC32 is zlib-compatible
(sys/libkern/crc32.c table = 0xEDB88320 reflected).
Fix validation (mandatory β memory-boundary class)
fix.diff: structural validation inl64_readdisklabel(total/boot-area contained; each partition sector-aligned,p_boffset<=slicebsize,p_bsize<=slicebsize,p_boffset+p_bsize<=slicebsizeβ terms bounded first so the sum cannot wrap).- Baseline reproduced on kernel #0; guest
vm.sh reset with-src, patch applied to /usr/src,make -j6 nativekernel && make installkernel, reboot β kernel #1. - Patched result: kernel log
vn0s1: cannot find label (disklabel64 corrupted, partition); no vn0s1a/b/c devices; all primitives absent (run.fixed.log, run.fixed2.log); label magic at LBA 2049 intact. - No false positives: a fully-contained label (
valid.img) is accepted on the patched kernel;vn1s1acreated with correct in-slicemedia_offset, read/write round-trip works, EROFS reserved protection enforced (EROFSon whole-slice write at sec 1). - Note: on the patched kernel an unlabeled slice has
ds_reserved=0, so whole-slice writes into the (absent) label area succeed β pre-existing behavior for label-less slices, not a regression of this fix.
fix_status: fixed β baseline reproduced / patched behavior gone / valid labels unaffected.
Fix verification
fixedvm.sh reset with-src; fix.diff applied to guest /usr/src; make -j6 nativekernel + make installkernel; reboot into kernel #1. Crafted label now rejected ('vn0s1: cannot find label (disklabel64 corrupted, partition)'), no vn0s1a/b/c devices, label magic intact, all OOB primitives absent. Valid contained label (valid.img) still accepted with correct in-slice media_offset, working read/write, and EROFS reserved protection enforced.
['findings/poc/DF-2910/run.fixed.log', 'findings/poc/DF-2910/run.fixed2.log', 'findings/poc/DF-2910/build.log', 'findings/poc/DF-2910/fix.diff']
Confirmed kernel references
Detail
Exploit chain
1) attacker crafts media: MBR slice type 0xA5 containing disklabel64 with CRC-valid but uncontained partitions; 2) root attaches (vnconfig -c / USB automount) -> kernel auto-probes (subr_disk.c:491) and creates partition devices; 3) read/write via e.g. /dev/vn0s1a (p_boffset beyond slice) hits other slices' data; 4) p_boffset near 2^64 wraps dscheck's offset arithmetic to arbitrary small absolute offsets incl. before the slice start; 5) p_boffset=p_bsize=2^64-512 gives a universal window (media_blocks=2^55-1) where user seeks choose the absolute target; 6) wraparound makes slicerel_secno huge so the ds_reserved EROFS check never fires -> write to the label/MBR area through a partition device.
Evidence (decisive lines)
['findings/poc/DF-2910/run.log Β§1: SLICE2-SECRET-MARKER read via /dev/vn0s1a (cross-slice)', 'findings/poc/DF-2910/run.log Β§2: SECTOR128-SECRET-MARKER read via /dev/vn0s1b (wrap to pre-slice LBA 128; DIOCGPART media_offset=65536)', 'findings/poc/DF-2910/run.log Β§4-6: control write EROFS errno=30 vs bypass write()=512 ok via /dev/vn0s1c; raw LBA 2049 shows PWNED-PARTITION-WRITE', "findings/poc/DF-2910/run.fixed.log: patched kernel logs 'vn0s1: cannot find label (disklabel64 corrupted, partition)'; DIOCGDINFO64 -> EINVAL; no vn0s1a/b/c", 'findings/poc/DF-2910/run.fixed2.log + VERDICT.md: valid.img label still accepted on patched kernel, partition I/O round-trips, EROFS enforced', 'findings/poc/DF-2910/makeimg.py: image generator with exact struct packing and zlib CRC32']
PoC changes
No seed existed; written fresh. Initial generator expressed the wrap as per-target p_boffset=target-ds_offset*512; guest ground truth (DIOCGPART) showed the general primitive is one partition with p_boffset=p_bsize=2^64-512 plus user-relative seeks; corrected accordingly. dd error lines must not be truncated (tail swallowed EROFS errors) - wprobe.c uses write(2) and prints errno.
Verified recommended fix
Validate on-media disklabel64 structure in l64_readdisklabel: label total/boot area and every partition sector-aligned and contained within sp->ds_size*secsize with wrap-safe sums (see fix.diff).
Verdict
l64_readdisklabel (sys/kern/subr_disklabel64.c:183-187) accepts any CRC-valid on-media disklabel64 with uncontained p_boffset/p_bsize; dscheck (sys/kern/subr_diskslice.c:280-281) then routes partition I/O at (ds_offset+slicerel)*secsize with mod-2^64 wrap and no slice containment. Demonstrated on the stock guest via vn: cross-slice read of another slice's data, backwards wraparound read to pre-slice absolute LBA 128 (kernel-reported media_offset=65536), a single 2^55-sector universal-window partition, and a write through a partition device that clobbers the on-disk label magic while the identical whole-slice write is EROFS-rejected. Impact is disk-data redirection (slice isolation + label-area EROFS protection voided for crafted media), not kernel memory corruption; trigger requires root to attach/open attacker media (vnconfig/automount), so Medium. Concrete impact upgrade of DF-0134. Fix validated: structural bounds in the read path reject the crafted label (kernel #1) while valid labels still install and EROFS protection still works.
No comments yet.