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
This commit is contained in:
Mark Johnston 2018-11-07 23:28:11 +00:00
parent a3fd276be0
commit 150d384e5c

View File

@ -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);
}