diff options
author | Kostya Kortchinsky <kostyak@google.com> | 2017-08-04 20:28:59 +0000 |
---|---|---|
committer | Kostya Kortchinsky <kostyak@google.com> | 2017-08-04 20:28:59 +0000 |
commit | d7d1681a0e66953e8552a26ca14019352a2aff0c (patch) | |
tree | 77c4b6cb1def0055e2812ec8b223c186cd6ca0d6 | |
parent | b24df62bb61c7db78eb389f1e646900e6af8508d (diff) | |
download | bcm5719-llvm-d7d1681a0e66953e8552a26ca14019352a2aff0c.tar.gz bcm5719-llvm-d7d1681a0e66953e8552a26ca14019352a2aff0c.zip |
[asan] Check for pvalloc overlow
Summary:
Last one of the `pvalloc` overflow checks!
`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 ASan's `pvalloc` implementation.
Reviewers: alekseyshl
Reviewed By: alekseyshl
Subscribers: llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D36257
llvm-svn: 310119
-rw-r--r-- | compiler-rt/lib/asan/asan_allocator.cc | 4 | ||||
-rw-r--r-- | compiler-rt/test/asan/TestCases/Linux/pvalloc-overflow.cc | 41 |
2 files changed, 45 insertions, 0 deletions
diff --git a/compiler-rt/lib/asan/asan_allocator.cc b/compiler-rt/lib/asan/asan_allocator.cc index 92963ddfc4d..c98f9a89cc7 100644 --- a/compiler-rt/lib/asan/asan_allocator.cc +++ b/compiler-rt/lib/asan/asan_allocator.cc @@ -839,6 +839,10 @@ void *asan_valloc(uptr size, BufferedStackTrace *stack) { void *asan_pvalloc(uptr size, BufferedStackTrace *stack) { uptr PageSize = GetPageSizeCached(); + if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) { + errno = errno_ENOMEM; + return AsanAllocator::FailureHandler::OnBadRequest(); + } // pvalloc(0) should allocate one page. size = size ? RoundUpTo(size, PageSize) : PageSize; return SetErrnoOnNull( diff --git a/compiler-rt/test/asan/TestCases/Linux/pvalloc-overflow.cc b/compiler-rt/test/asan/TestCases/Linux/pvalloc-overflow.cc new file mode 100644 index 00000000000..80a2b9ce8e4 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Linux/pvalloc-overflow.cc @@ -0,0 +1,41 @@ +// RUN: %clangxx_asan %s -o %t +// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %run %t m1 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=allocator_may_return_null=1 %run %t m1 2>&1 +// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %run %t psm1 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=allocator_may_return_null=1 %run %t psm1 2>&1 + +// UNSUPPORTED: freebsd + +// Checks that pvalloc overflows are caught. If the allocator is allowed to +// return null, the errno should be set to ENOMEM. + +#include <assert.h> +#include <errno.h> +#include <malloc.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +int main(int argc, char *argv[]) { + void *p; + size_t page_size; + + assert(argc == 2); + + page_size = sysconf(_SC_PAGESIZE); + + if (!strcmp(argv[1], "m1")) { + p = pvalloc((uintptr_t)-1); + assert(!p); + assert(errno == ENOMEM); + } + if (!strcmp(argv[1], "psm1")) { + p = pvalloc((uintptr_t)-(page_size - 1)); + assert(!p); + assert(errno == ENOMEM); + } + + return 0; +} + +// CHECK: AddressSanitizer's allocator is terminating the process |