β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-2725

cluster_rbuild() under-counts component pages vs the pbuf's embedded xio_pages[]/KVA window β€” latent OOB pointer write + PTE install past MAXPHYS window for non-page-tiling VFS geometry

Field Value
ID DF-2725
Status new
Severity Low
CVSS 3.1 CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:H
CWE CWE-787 / CWE-131
File sys/kern/vfs_cluster.c
Lines 954-959 (check), 1049-1066 (append), 1094-1100
Area kern
Confidence likely
Discovered 2026-08-30
Pass 2 (GLM 5.3 second pass)
Bucket memcorrupt
Reported pending
Known CVE none
CVE match novel

Summary

cluster_rbuild() admits a new component whenever (npages*PAGE_SIZE)+round_page(blksize) <= maxiosize and performs no capacity check at all for the first component β€” but each component actually contributes tbp->b_xio.xio_npages pages, which can exceed round_page(blksize)/PAGE_SIZE by 1 whenever a component buffer starts mid-page and crosses a page boundary. cluster_wbuild() gets this right by summing actual page counts. With non-page-tiling geometry the loop can accumulate more than maxiosize/PAGE_SIZE pages into bp->b_xio.xio_pages β€” the embedded array is exactly XIO_INTERNAL_PAGES=btoc(MAXPHYS) with kvasize=MAXPHYS β€” producing (a) OOB writes of vm_page_t pointers past the embedded array in struct buf and (b) pmap_qenter_noinval() installing PTEs past the reserved MAXPHYS KVA window. The b_bufsize>b_kvasize panic does NOT catch this (b_bufsize aggregates bytes, not pages). LATENT in-tree: every in-tree caller produces page-tiling buffers (ffs/ext2 fragment offsets are fsize-multiples and fsize|PAGE; msdosfs power-of-2 blsize at cluster-aligned offsets; tmpfs/fuse PAGE_SIZE; hammer 16K; hammer2 uniform 64K; GETBLK_SZMATCH pins component size==blksize). Reachable by any out-of-tree/third-party VFS (or future in-tree one) whose block geometry is not page-tiling β€” then a plain sequential read loop drives it.

Mirror cluster_wbuild's exact accounting before appending each component's pages (test `bp->b_xio.xio_npages + tbp->b_xio.xio_npages

maxiosize / PAGE_SIZE` after the getblk, as :1609-1610 does) and cap the first component too.

Timeline

  • 2026-08-30 Discovered during pass-2 audit of vfs_cluster.c (GLM 5.3).

Discussion (0)

No comments yet.