summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Kortchinsky <kostyak@google.com>2017-08-02 22:47:54 +0000
committerKostya Kortchinsky <kostyak@google.com>2017-08-02 22:47:54 +0000
commit5dea2733b9b133262190ffec6f967e81d0e8b27b (patch)
treeb1c21f8de778e82b3869de2b727562e0580b8b67
parentac2979953f5a661ebb67eb8f4a36d63ae0db19c3 (diff)
[tsan] Check for pvalloc overlow
Summary: `CheckForPvallocOverflow` was introduced with D35818 to detect when pvalloc would wrap when rounding up to the next multiple of the page size. Add this check to TSan's pvalloc implementation. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D36245 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@309897 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/tsan/rtl/tsan_mman.cc4
-rw-r--r--lib/tsan/tests/unit/tsan_mman_test.cc8
2 files changed, 11 insertions, 1 deletions
diff --git a/lib/tsan/rtl/tsan_mman.cc b/lib/tsan/rtl/tsan_mman.cc
index 3f7a5e76c..8ef031646 100644
--- a/lib/tsan/rtl/tsan_mman.cc
+++ b/lib/tsan/rtl/tsan_mman.cc
@@ -256,6 +256,10 @@ void *user_valloc(ThreadState *thr, uptr pc, uptr sz) {
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));
diff --git a/lib/tsan/tests/unit/tsan_mman_test.cc b/lib/tsan/tests/unit/tsan_mman_test.cc
index ed08247fa..05ae42867 100644
--- a/lib/tsan/tests/unit/tsan_mman_test.cc
+++ b/lib/tsan/tests/unit/tsan_mman_test.cc
@@ -139,6 +139,7 @@ TEST(Mman, Stats) {
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 @@ TEST(Mman, Valloc) {
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 - 1)),
+ "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