From 150d384e5c834d41d19d44a44af1163e15d9f991 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Wed, 7 Nov 2018 23:28:11 +0000 Subject: [PATCH] Fix a use-after-free in swp_pager_meta_free(). This was introduced in r326329 and explains the crashes mentioned in the commit log message for r339934. In particular, on INVARIANTS kernels, UMA trashing causes the loop to exit early, leaving swap blocks behind when they should have been freed. After r336984 this became more problematic since new anonymous mappings were more likely to reuse swapped-out subranges of existing VM objects, so faults would trigger pageins of freed memory rather than returning zeroed pages. Reviewed by: kib MFC after: 3 days Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17897 --- sys/vm/swap_pager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 76a574883619..b66a6caa4f1a 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -1972,13 +1972,13 @@ swp_pager_meta_free(vm_object_t object, vm_pindex_t pindex, vm_pindex_t count) swp_pager_update_freerange(&s_free, &n_free, sb->d[i]); sb->d[i] = SWAPBLK_NONE; } + pindex = sb->p + SWAP_META_PAGES; if (swp_pager_swblk_empty(sb, 0, start) && swp_pager_swblk_empty(sb, limit, SWAP_META_PAGES)) { SWAP_PCTRIE_REMOVE(&object->un_pager.swp.swp_blks, sb->p); uma_zfree(swblk_zone, sb); } - pindex = sb->p + SWAP_META_PAGES; } swp_pager_freeswapspace(s_free, n_free); }