DragonFlyBSD Kernel Audit
DF-0797 / panic.txt
← back to finding ↓ download raw
Fatal trap 12: page fault while in kernel mode
cpuid = 2; lapic id = 2
fault virtual address	= 0xfffff80128a50a28
fault code		= supervisor write data, page not present
instruction pointer	= 0x8:0xffffffff80948789
stack pointer	        = 0x10:0xfffff80118251488
frame pointer	        = 0x10:0xfffff80118251558
code segment		= base 0x0, limit 0xfffff, type 0x1b
			= DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags	= interrupt enabled, resume, IOPL = 0
current process		= 979
current thread          = pri 6 
kernel: type 12 trap, code=2

CPU2 stopping CPUs: 0x0000003b
 stopped
Stopped at      hammer_install_volume+0x519:    orq     %rdi,0x10a30(%rbx,%rdx,8)
db>

---

DF-0797 PANIC ANALYSIS
======================

Trigger: mount -t hammer -o nohistory /dev/vn0 /mnt  on a HAMMER v1 image
whose volume header has vol_no = 0x7FFFFFFF (patched at byte offset 0x90 in
struct hammer_volume_ondisk; CRC left stale because it is never validated).

Panic instruction decoded:
   orq %rdi, 0x10a30(%rbx,%rdx,8)
      %rbx           = hmp (struct hammer_mount *)
      0x10a30        = offset of volume_map[] within struct hammer_mount
      (%rbx,...,8)   = base + index*8  =>  hmp->volume_map[i]
      %rdx           = i = __hammer_vol_index(0x7FFFFFFF) = 0x7FFFFFFF >> 6 = 0x1FFFFFF
      %rdi           = __hammer_vol_low(0x7FFFFFFF) = 1ULL << (0x7FFFFFFF & 63) = 1ULL << 63

This is the EXACT compilation of hammer.h:1583:
   hmp->volume_map[i] |= __hammer_vol_low(vol->vol_no);
called from hammer_ondisk.c:234:
   hammer_volume_number_add(hmp, volume);

with vol_no=0x7FFFFFFF, i=0x1FFFFFF, the access lands at
   hmp + 0x10a30 + 0x1FFFFFF*8 = hmp + 0x10a30 + 0x0FFFFF8 = ~+255 MiB
=> unmapped page => supervisor write data, page not present => fatal trap 12.

This is the in-kernel proof of the DF-0797 out-of-bounds write primitive.