diff options
| author | Kostya Kortchinsky <kostyak@google.com> | 2017-07-25 21:18:02 +0000 |
|---|---|---|
| committer | Kostya Kortchinsky <kostyak@google.com> | 2017-07-25 21:18:02 +0000 |
| commit | 65fdf677f28407efea358027ecc56c7e1d0c41d8 (patch) | |
| tree | 3b1f3b6538fdefc3ae6256bbae409bddb3d4c6d4 /compiler-rt/test/scudo/valloc.cpp | |
| parent | 4e0a4b3674834d68e794cbf32d5bc2481fc11d85 (diff) | |
| download | bcm5719-llvm-65fdf677f28407efea358027ecc56c7e1d0c41d8.tar.gz bcm5719-llvm-65fdf677f28407efea358027ecc56c7e1d0c41d8.zip | |
[scudo] Check for pvalloc overflow
Summary:
Previously we were rounding up the size passed to `pvalloc` to the next
multiple of page size no matter what. There is an overflow possibility that
wasn't accounted for. So now, return null in the event of an overflow. The man
page doesn't seem to indicate the errno to set in this particular situation,
but the glibc unit tests go for ENOMEM (https://code.woboq.org/userspace/glibc/malloc/tst-pvalloc.c.html#54)
so we'll do the same.
Update the aligned allocation funtions tests to check for properly aligned
returned pointers, and the `pvalloc` corner cases.
@alekseyshl: do you want me to do the same in the other Sanitizers?
Reviewers: alekseyshl
Reviewed By: alekseyshl
Subscribers: kubamracek, alekseyshl, llvm-commits
Differential Revision: https://reviews.llvm.org/D35818
llvm-svn: 309033
Diffstat (limited to 'compiler-rt/test/scudo/valloc.cpp')
| -rw-r--r-- | compiler-rt/test/scudo/valloc.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/compiler-rt/test/scudo/valloc.cpp b/compiler-rt/test/scudo/valloc.cpp new file mode 100644 index 00000000000..010dac2a5ea --- /dev/null +++ b/compiler-rt/test/scudo/valloc.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_scudo %s -o %t +// RUN: %run %t valid 2>&1 +// RUN: %run %t invalid 2>&1 + +// Tests that valloc and pvalloc work as intended. + +#include <assert.h> +#include <errno.h> +#include <malloc.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +size_t round_up_to(size_t size, size_t alignment) { + return (size + alignment - 1) & ~(alignment - 1); +} + +int main(int argc, char **argv) +{ + void *p = nullptr; + size_t size, page_size; + + assert(argc == 2); + + page_size = sysconf(_SC_PAGESIZE); + // Check that the page size is a power of two. + assert((page_size & (page_size - 1)) == 0); + + if (!strcmp(argv[1], "valid")) { + for (int i = (sizeof(void *) == 4) ? 3 : 4; i < 21; i++) { + size = 1U << i; + p = valloc(size - (2 * sizeof(void *))); + assert(p); + assert(((uintptr_t)p & (page_size - 1)) == 0); + free(p); + p = pvalloc(size - (2 * sizeof(void *))); + assert(p); + assert(((uintptr_t)p & (page_size - 1)) == 0); + assert(malloc_usable_size(p) >= round_up_to(size, page_size)); + free(p); + p = valloc(size); + assert(p); + assert(((uintptr_t)p & (page_size - 1)) == 0); + free(p); + p = pvalloc(size); + assert(p); + assert(((uintptr_t)p & (page_size - 1)) == 0); + assert(malloc_usable_size(p) >= round_up_to(size, page_size)); + free(p); + } + } + if (!strcmp(argv[1], "invalid")) { + // Size passed to pvalloc overflows when rounded up. + p = pvalloc((size_t)-1); + assert(!p); + assert(errno == ENOMEM); + errno = 0; + p = pvalloc((size_t)-page_size); + assert(!p); + assert(errno == ENOMEM); + } + return 0; +} |

