Index: lib/tsan/rtl/tsan_mman.cc =================================================================== --- lib/tsan/rtl/tsan_mman.cc +++ lib/tsan/rtl/tsan_mman.cc @@ -256,6 +256,10 @@ void *user_pvalloc(ThreadState *thr, uptr pc, uptr sz) { uptr PageSize = GetPageSizeCached(); + if (UNLIKELY(CheckForPvallocOverflow(sz, PageSize))) { + errno = errno_ENOMEM; + return Allocator::FailureHandler::OnBadRequest(); + } // pvalloc(0) should allocate one page. sz = sz ? RoundUpTo(sz, PageSize) : PageSize; return SetErrnoOnNull(user_alloc_internal(thr, pc, sz, PageSize)); Index: lib/tsan/tests/unit/tsan_mman_test.cc =================================================================== --- lib/tsan/tests/unit/tsan_mman_test.cc +++ lib/tsan/tests/unit/tsan_mman_test.cc @@ -139,6 +139,7 @@ TEST(Mman, Valloc) { ThreadState *thr = cur_thread(); + uptr page_size = GetPageSizeCached(); void *p = user_valloc(thr, 0, 100); EXPECT_NE(p, (void*)0); @@ -150,8 +151,13 @@ p = user_pvalloc(thr, 0, 0); EXPECT_NE(p, (void*)0); - EXPECT_EQ(GetPageSizeCached(), __sanitizer_get_allocated_size(p)); + EXPECT_EQ(page_size, __sanitizer_get_allocated_size(p)); user_free(thr, 0, p); + + EXPECT_DEATH(p = user_pvalloc(thr, 0, (uptr)-page_size), + "allocator is terminating the process instead of returning 0"); + EXPECT_DEATH(p = user_pvalloc(thr, 0, (uptr)-1), + "allocator is terminating the process instead of returning 0"); } #if !SANITIZER_DEBUG