DF-5667 / vk_probe5.sh
#!/bin/sh # DF-5667 probe v5 (fixed-kernel introspection) — resolves why kernacc() # still returns TRUE for dead per-CPU slots after the is_globaldata_space # fix: reads kernel_map->{min_addr,max_addr} via /dev/kmem and probes # kernacc() below / inside / above the per-CPU window via DDB (hex args). set -u VK=/usr/obj/usr/src/sys/VKERNEL64/kernel.debug LOG=/tmp/vk5667.log cd /usr/obj/usr/src/sys/VKERNEL64 pkill -9 -f kernel.debug 2>/dev/null; sleep 1 rm -f /tmp/vkin $LOG mkfifo /tmp/vkin (sleep 900 > /tmp/vkin 2>/dev/null) </dev/null & HOLDER=$! nsym() { nm $VK | awk -v s="$1" '$3==s{print "0x"$1}' | head -1; } SYM_PRV=$(nsym CPU_prvspace); SYM_KMAP=$(nsym kernel_map) F_KERNACC=$(nsym kernacc); F_KVAC=$(nsym kvm_access_check) echo "DF5667V5 SYMS prv=$SYM_PRV kmap=$SYM_KMAP kernacc=$F_KERNACC kvac=$F_KVAC" ( exec 3> /tmp/vkin; echo "ufs:vkd0" >&3 ) & ./kernel.debug -m 512m -r /vkroot.img -n 2 -e init_path=/bin/vkinit \ -s < /tmp/vkin 2>&1 | tee $LOG > /dev/console & i=0; while [ $i -lt 150 ]; do grep -q "Mounting root from ufs:vkd0" $LOG 2>/dev/null && grep -q "^# " $LOG 2>/dev/null && break pgrep -f "kernel.debug -m 512m" >/dev/null 2>&1 || break sleep 1; i=$((i+1)); done sleep 4 send() { ( exec 4> /tmp/vkin; echo "$1" >&4 ); } send "echo DF5667V5_STAGE1" send "dd if=/dev/kmem bs=8 count=1 skip=\$(( $SYM_PRV / 8 )) 2>/dev/null | od -An -tx1" send "dd if=/dev/kmem bs=8 count=1 skip=\$(( $SYM_KMAP / 8 )) 2>/dev/null | od -An -tx1" sleep 5 parse8() { grep -a -A1 "$2" $LOG | tail -1 | tr -d '\r' | awk -v pre="$1" '{v=pre; for(i=NF;i>=1;i--) v=v $i; print v}'; } # re-extract the od line FOLLOWING each command B=$(awk '/od -An/{getline; gsub(/\r/,""); v="0x"; n=split($0,a," "); for(i=n;i>=1;i--) v=v a[i]; print v; exit}' $LOG) P=$(awk '/kernel_map|kmap/{found=1} found&&/od -An/{getline; getline; gsub(/\r/,""); v="0x"; n=split($0,a," "); for(i=n;i>=1;i--) v=v a[i]; print v; exit}' $LOG) # fallback: second od output line [ -z "$P" ] && P=$(awk '/od -An/{c++; if(c==2){getline; gsub(/\r/,""); v="0x"; n=split($0,a," "); for(i=n;i>=1;i--) v=v a[i]; print v; exit}}' $LOG) echo "DF5667V5 BASE=$B KMAP_PTR=$P" if [ -n "$P" ]; then send "dd if=/dev/kmem bs=128 count=1 skip=\$(( $P / 128 )) 2>/dev/null | od -An -tx1" sleep 4 fi # DDB kernacc probes around the window (hex args!) send "sysctl -w debug.enter_debugger=ddb"; sleep 4 ( exec 5> /tmp/vkin printf 'call %s(0x8000300123, 8, 1)\n' "$F_KERNACC" >&5; sleep 2 printf 'call %s(0x8000420123, 8, 1)\n' "$F_KERNACC" >&5; sleep 2 printf 'call %s(0x8000c10123, 8, 1)\n' "$F_KERNACC" >&5; sleep 2 printf 'call %s(0x7fff7000, 8, 1)\n' "$F_KERNACC" >&5; sleep 2 printf 'call %s(0x8000300000, 0x8000301000, 1)\n' "$F_KVAC" >&5; sleep 2 ) & sleep 16 send "c"; sleep 3 send "echo DF5667V5_DONE; reboot"; sleep 6 echo "=== results ===" sed -n "/DF5667V5_STAGE1/,/V5_DONE/p" $LOG | tail -60 kill $HOLDER 2>/dev/null; pkill -9 -f kernel.debug 2>/dev/null echo "DF5667V5_DRIVER_DONE" |