[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

llvm-svn: 309897
This commit is contained in:
Kostya Kortchinsky 2017-08-02 22:47:54 +00:00
parent 9fb9d71d3e
commit 0357e8de3b
2 changed files with 11 additions and 1 deletions

View File

@ -256,6 +256,10 @@ void *user_valloc(ThreadState *thr, uptr pc, uptr sz) {
void *user_pvalloc(ThreadState *thr, uptr pc, uptr sz) { void *user_pvalloc(ThreadState *thr, uptr pc, uptr sz) {
uptr PageSize = GetPageSizeCached(); uptr PageSize = GetPageSizeCached();
if (UNLIKELY(CheckForPvallocOverflow(sz, PageSize))) {
errno = errno_ENOMEM;
return Allocator::FailureHandler::OnBadRequest();
}
// pvalloc(0) should allocate one page. // pvalloc(0) should allocate one page.
sz = sz ? RoundUpTo(sz, PageSize) : PageSize; sz = sz ? RoundUpTo(sz, PageSize) : PageSize;
return SetErrnoOnNull(user_alloc_internal(thr, pc, sz, PageSize)); return SetErrnoOnNull(user_alloc_internal(thr, pc, sz, PageSize));

View File

@ -139,6 +139,7 @@ TEST(Mman, Stats) {
TEST(Mman, Valloc) { TEST(Mman, Valloc) {
ThreadState *thr = cur_thread(); ThreadState *thr = cur_thread();
uptr page_size = GetPageSizeCached();
void *p = user_valloc(thr, 0, 100); void *p = user_valloc(thr, 0, 100);
EXPECT_NE(p, (void*)0); EXPECT_NE(p, (void*)0);
@ -150,8 +151,13 @@ TEST(Mman, Valloc) {
p = user_pvalloc(thr, 0, 0); p = user_pvalloc(thr, 0, 0);
EXPECT_NE(p, (void*)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); 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 #if !SANITIZER_DEBUG