DF-2621 / instrument.diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | --- a/sys/vfs/hammer2/hammer2_admin.c 2026-08-28 15:24:47.450135496 +0000 +++ b/sys/vfs/hammer2/hammer2_admin.c 2026-08-28 15:25:09.529848981 +0000 @@ -421,7 +421,40 @@ /* * A mounted PFS needs Xops threads to support frontend operations. + * + * DF2621 VERIFICATION INSTRUMENTATION (temporary, in-guest build only). */ +static hammer2_pfs_t *df2621_freed_ring[16]; +static int df2621_freed_ridx; +static int df2621_uaf_reports; + +void hammer2_df2621_mark_free(hammer2_pfs_t *pmp); +void +hammer2_df2621_mark_free(hammer2_pfs_t *pmp) +{ + df2621_freed_ring[df2621_freed_ridx++ & 15] = pmp; + kprintf("DF2621: pfsfree kfree pmp=%p\n", pmp); +} + +static void +df2621_check_freed(hammer2_thread_t *thr, hammer2_pfs_t *pmp) +{ + int i; + + if (pmp == NULL || df2621_uaf_reports >= 200) + return; + for (i = 0; i < 16; ++i) { + if (df2621_freed_ring[i] == pmp) { + ++df2621_uaf_reports; + kprintf("DF2621: UAF-WRITE thr=%p clindex=%d " + "spin_ex(&pmp->xop_spin) on FREED pmp=%p " + "(report %d)\n", + thr, thr->clindex, pmp, df2621_uaf_reports); + return; + } + } +} + void hammer2_xop_helper_create(hammer2_pfs_t *pmp) { @@ -431,9 +464,14 @@ lockmgr(&pmp->lock, LK_EXCLUSIVE); pmp->has_xop_threads = 1; + kprintf("DF2621: helper_create pmp=%p old_groups=%p nchains=%d\n", + pmp, pmp->xop_groups, + pmp->iroot ? pmp->iroot->cluster.nchains : -1); pmp->xop_groups = kmalloc(hammer2_xop_nthreads * sizeof(hammer2_xop_group_t), M_HAMMER2, M_WAITOK | M_ZERO); + kprintf("DF2621: helper_create pmp=%p new_groups=%p (OLD LEAKED)\n", + pmp, pmp->xop_groups); for (i = 0; i < pmp->iroot->cluster.nchains; ++i) { for (j = 0; j < hammer2_xop_nthreads; ++j) { if (pmp->xop_groups[j].thrs[i].td) @@ -453,6 +491,8 @@ int i; int j; + kprintf("DF2621: helper_cleanup enter pmp=%p groups=%p nmasters=%d\n", + pmp, pmp->xop_groups, pmp->pfs_nmasters); if (pmp->xop_groups == NULL) { KKASSERT(pmp->has_xop_threads == 0); return; @@ -463,8 +503,11 @@ if (pmp->xop_groups[j].thrs[i].td) hammer2_thr_delete(&pmp->xop_groups[j].thrs[i]); } + kprintf("DF2621: helper_cleanup col %d deleted\n", i); } pmp->has_xop_threads = 0; + kprintf("DF2621: helper_cleanup freeing groups=%p\n", + pmp->xop_groups); kfree(pmp->xop_groups, M_HAMMER2); pmp->xop_groups = NULL; } @@ -1076,6 +1119,7 @@ uint32_t hash[XOP_HASH_SIZE] = { 0 }; hammer2_xop_head_t *xop; + df2621_check_freed(thr, pmp); hammer2_spin_ex(&pmp->xop_spin); TAILQ_FOREACH(xop, &thr->xopq, collect[clindex].entry) { /* --- a/sys/vfs/hammer2/hammer2_vfsops.c 2026-08-28 15:24:47.454135445 +0000 +++ b/sys/vfs/hammer2/hammer2_vfsops.c 2026-08-28 15:25:09.545848774 +0000 @@ -718,7 +718,9 @@ if (chains_still_present) { kprintf("hammer2: cannot free pmp %p, still in use\n", pmp); } else { + extern void hammer2_df2621_mark_free(hammer2_pfs_t *); kmalloc_destroy_obj(&pmp->minode); + hammer2_df2621_mark_free(pmp); kfree(pmp, M_HAMMER2); } } @@ -743,6 +745,7 @@ wlist = &hammer2_pfslist; else wlist = &hammer2_spmplist; + kprintf("DF2621: pfsfree_scan hmp=%p which=%d enter\n", hmp, which); again: TAILQ_FOREACH(pmp, wlist, mntentry) { if ((iroot = pmp->iroot) == NULL) @@ -769,6 +772,8 @@ * Make sure all synchronization threads are locked * down. */ + kprintf("DF2621: pfsfree_scan freeze begin pmp=%p groups=%p\n", + pmp, pmp->xop_groups); for (i = 0; i < HAMMER2_MAXCLUSTER; ++i) { if (pmp->pfs_hmps[i] == NULL) continue; @@ -807,6 +812,8 @@ /* * Remove the chain from matching elements of the PFS. */ + kprintf("DF2621: pfsfree_scan delete cols begin pmp=%p hmp=%p\n", + pmp, hmp); for (i = 0; i < HAMMER2_MAXCLUSTER; ++i) { if (pmp->pfs_hmps[i] != hmp) continue; @@ -863,6 +870,7 @@ */ KKASSERT(TAILQ_EMPTY(&pmp->syncq)); KKASSERT(TAILQ_EMPTY(&pmp->depq)); + kprintf("DF2621: pfsfree_scan pmp empty -> pfsfree\n"); hammer2_pfsfree(pmp); goto again; } @@ -871,6 +879,7 @@ * If elements still remain we need to set the REMASTER * flag and unfreeze it. */ + kprintf("DF2621: pfsfree_scan unfreeze+remaster pmp=%p\n", pmp); for (i = 0; i < HAMMER2_MAXCLUSTER; ++i) { if (pmp->pfs_hmps[i] == NULL) continue; |