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

swap_pager_putpages stripe-boundary trim is off-by-one, invoking freeswapspace with npages=0

Summary

swap_pager_putpages trim check at :1713 (blk ^ (blk+n)) & ~SWB_DMMASK fires when blk+n lands exactly ON a stripe boundary even though the I/O itself does not cross. Computed trim sets j=n -> swp_pager_freeswapspace(object, blk+j, n-j=0) -> blist_free(swapblist, X, 0). blist code not designed for count=0; updates bm_bighint spuriously on fully-allocated meta nodes -> suboptimal allocation hints + minor fragmentation. No panic in practice (leaf-level shift UB unreachable). Should use blk+n-1 (last page in I/O). Fires ~1/64 per single-page putpages cluster.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-0948 Β· 1 files
FileTypeDescriptionSize
fix.diff suggested-fix swap_pager_putpages stripe-boundary trim is off-by-one, invoking freeswapspace w 378 B view raw

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

fix.diff applied + combined nativekernel build rc=0 (-Werror)

fix.diff applied + combined nativekernel build rc=0 (-Werror)
↓ fix.diffcombined build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none (Info severity)

Evidence (decisive lines)

Source-confirmed at sys/vm/swap_pager.c:1713: stripe-boundary trim is off-by-one (freeswapspace with npages=0)

Verified recommended fix

Source-confirmed at sys/vm/swap_pager.c:1713: stripe-boundary trim is off-by-one (freeswapspace with npages=0)

Verdict

Source-confirmed at sys/vm/swap_pager.c:1713: stripe-boundary trim is off-by-one (freeswapspace with npages=0)