Fix huge_ralloc() race when using mremap(2).

Fix huge_ralloc() to remove the old memory region from tree of huge
allocations *before* calling mremap(2), in order to make sure that no
other thread acquires the old memory region via mmap() and encounters
stale metadata in the tree.

Reported by: Rich Prohaska
This commit is contained in:
Jason Evans 2011-11-09 11:55:19 -08:00
parent 45e040a82c
commit 03bf7a7a26

View File

@ -234,6 +234,13 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
) { ) {
size_t newsize = huge_salloc(ret); size_t newsize = huge_salloc(ret);
/*
* Remove ptr from the tree of huge allocations before
* performing the remap operation, in order to avoid the
* possibility of another thread acquiring that mapping before
* this one removes it from the tree.
*/
huge_dalloc(ptr, false);
if (mremap(ptr, oldsize, newsize, MREMAP_MAYMOVE|MREMAP_FIXED, if (mremap(ptr, oldsize, newsize, MREMAP_MAYMOVE|MREMAP_FIXED,
ret) == MAP_FAILED) { ret) == MAP_FAILED) {
/* /*
@ -253,9 +260,8 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
if (opt_abort) if (opt_abort)
abort(); abort();
memcpy(ret, ptr, copysize); memcpy(ret, ptr, copysize);
idalloc(ptr); chunk_dealloc(ptr, oldsize);
} else }
huge_dalloc(ptr, false);
} else } else
#endif #endif
{ {