summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Evans <je@fb.com>2011-11-09 19:55:19 (GMT)
committerJason Evans <je@fb.com>2011-11-09 19:55:19 (GMT)
commitfa351d9fdcbbbfe7455279311fdf3d65751a4e75 (patch)
tree0400baca9a1c86321e1cad9cd195da051102d044 /src
parentca9ee1a409c32e052ab04ca727bbc257a43795fc (diff)
downloadjemalloc-fa351d9fdcbbbfe7455279311fdf3d65751a4e75.zip
jemalloc-fa351d9fdcbbbfe7455279311fdf3d65751a4e75.tar.gz
jemalloc-fa351d9fdcbbbfe7455279311fdf3d65751a4e75.tar.bz2
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
Diffstat (limited to 'src')
-rw-r--r--src/huge.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/huge.c b/src/huge.c
index ac3f3a0..5ee9f54 100644
--- a/src/huge.c
+++ b/src/huge.c
@@ -234,6 +234,13 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
) {
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,
ret) == MAP_FAILED) {
/*
@@ -253,9 +260,8 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
if (opt_abort)
abort();
memcpy(ret, ptr, copysize);
- idalloc(ptr);
- } else
- huge_dalloc(ptr, false);
+ chunk_dealloc(ptr, oldsize);
+ }
} else
#endif
{