DF-5473 / run_vk.sh
#!/bin/sh # run_vk.sh — boot the vkernel on the guest, drive its single-user console, # capture everything. usage: run_vk.sh smoke|clean|bad|fixed RIG=/root/vkrig VK=/usr/obj/usr/src/sys/VKERNEL64/kernel.stripped MODE=${1:-smoke} # kernel text symbol addrs from this exact build (nm, fixed ET_EXEC): RIP_STRNCMP=0x706800 RIP_KPRINTF=0x50d850 SPRAY=0x100000000 # canonical-but-unmapped VA (48TB: above kernel KVA 512G..1T, below USRSTACK) TERM_BAD=0x3000000000000 LOG=$RIG/vkrun_$MODE.log rm -f $LOG feeder() { # wait for the single-user prompt (boot can take minutes on 1 vcpu) i=0 while [ $i -lt 90 ]; do if grep -q "Enter full pathname of shell" $LOG 2>/dev/null; then break fi sleep 5 i=$((i+1)) done echo "" # RETURN -> default /bin/sh sleep 10 # shell+termcap settle case "$MODE" in smoke) echo 'echo SMOKE_READY' sleep 3 echo 'sysctl -n kern.osrelease' sleep 3 echo 'ls /root' sleep 3 echo 'reboot' ;; clean) # userchain=0 -> harness uses an in-kernel terminating chain: # walk must complete and return, vkernel must stay up echo "/root/vktrigger 0 0 $RIP_STRNCMP $RIP_KPRINTF 6" sleep 8 echo 'echo CLEAN_DONE' sleep 3 echo 'halt' ;; bad) # userchain=$SPRAY: guest-user VA, mapped for the guest process but # NOT dereferenceable from vkernel kernel context (copyio.c:311 # never raw-derefs user VA) -> guaranteed fault in db_read_bytes # -> kdb_trap longjmp into the BSS-zeroed db_jmpbuf echo "/root/vktrigger $SPRAY $TERM_BAD $RIP_STRNCMP $RIP_KPRINTF 6" sleep 500 ;; fixed) echo "/root/vktrigger $SPRAY $TERM_BAD $RIP_STRNCMP $RIP_KPRINTF 6" sleep 8 echo 'echo FIXED_DONE' sleep 3 echo 'halt' ;; esac } feeder | timeout 540 $VK -m 96m -n 1 -r $RIG/vkroot.img \ -e 'vfs.root.mountfrom="ufs:/dev/vkd0s0a"' \ -s > $LOG 2>&1 echo "VK_EXIT=$?" | tee $RIG/vkexit_$MODE echo "===== last 45 lines of $LOG =====" tail -45 $LOG |