diff options
author | andrew <andrew@FreeBSD.org> | 2012-07-30 10:58:13 +0000 |
---|---|---|
committer | andrew <andrew@FreeBSD.org> | 2012-07-30 10:58:13 +0000 |
commit | cfeab007a554034f0b3ab4a677cf9dd2696c12f9 (patch) | |
tree | 40cc44a3d02ed86de24f2117a55680e4f0eb01a0 /lib/asan/output_tests | |
parent | 07af089f1449ec5506ca7ede5b593e11a0f48603 (diff) | |
download | FreeBSD-src-cfeab007a554034f0b3ab4a677cf9dd2696c12f9.zip FreeBSD-src-cfeab007a554034f0b3ab4a677cf9dd2696c12f9.tar.gz |
Import compiler-rt r160957.
Diffstat (limited to 'lib/asan/output_tests')
21 files changed, 579 insertions, 0 deletions
diff --git a/lib/asan/output_tests/clone_test.cc b/lib/asan/output_tests/clone_test.cc new file mode 100644 index 0000000..b18d255 --- /dev/null +++ b/lib/asan/output_tests/clone_test.cc @@ -0,0 +1,34 @@ +#ifdef __linux__ +#include <stdio.h> +#include <sched.h> +#include <sys/syscall.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +int Child(void *arg) { + char x[32] = {0}; // Stack gets poisoned. + printf("Child: %p\n", x); + _exit(1); // NoReturn, stack will remain unpoisoned unless we do something. +} + +int main(int argc, char **argv) { + const int kStackSize = 1 << 20; + char child_stack[kStackSize + 1]; + char *sp = child_stack + kStackSize; // Stack grows down. + printf("Parent: %p\n", sp); + pid_t clone_pid = clone(Child, sp, CLONE_FILES | CLONE_VM, NULL, 0, 0, 0); + waitpid(clone_pid, NULL, 0); + for (int i = 0; i < kStackSize; i++) + child_stack[i] = i; + int ret = child_stack[argc - 1]; + printf("PASSED\n"); + return ret; +} +#else // not __linux__ +#include <stdio.h> +int main() { + printf("PASSED\n"); + // Check-Common: PASSED +} +#endif diff --git a/lib/asan/output_tests/deep_tail_call.cc b/lib/asan/output_tests/deep_tail_call.cc new file mode 100644 index 0000000..cb69e89 --- /dev/null +++ b/lib/asan/output_tests/deep_tail_call.cc @@ -0,0 +1,15 @@ +// Check-Common: AddressSanitizer global-buffer-overflow +int global[10]; +// Check-Common: {{#0.*call4}} +void __attribute__((noinline)) call4(int i) { global[i+10]++; } +// Check-Common: {{#1.*call3}} +void __attribute__((noinline)) call3(int i) { call4(i); } +// Check-Common: {{#2.*call2}} +void __attribute__((noinline)) call2(int i) { call3(i); } +// Check-Common: {{#3.*call1}} +void __attribute__((noinline)) call1(int i) { call2(i); } +// Check-Common: {{#4.*main}} +int main(int argc, char **argv) { + call1(argc); + return global[0]; +} diff --git a/lib/asan/output_tests/default_options.cc b/lib/asan/output_tests/default_options.cc new file mode 100644 index 0000000..d6c7029 --- /dev/null +++ b/lib/asan/output_tests/default_options.cc @@ -0,0 +1,12 @@ +const char *kAsanDefaultOptions="verbosity=1 foo=bar"; + +extern "C" +__attribute__((no_address_safety_analysis)) +const char *__asan_default_options() { + return kAsanDefaultOptions; +} + +int main() { + // Check-Common: foo=bar + return 0; +} diff --git a/lib/asan/output_tests/dlclose-test-so.cc b/lib/asan/output_tests/dlclose-test-so.cc new file mode 100644 index 0000000..73e0050 --- /dev/null +++ b/lib/asan/output_tests/dlclose-test-so.cc @@ -0,0 +1,33 @@ +//===----------- dlclose-test-so.cc -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Regression test for +// http://code.google.com/p/address-sanitizer/issues/detail?id=19 +//===----------------------------------------------------------------------===// +#include <stdio.h> + +static int pad1; +static int static_var; +static int pad2; + +extern "C" +int *get_address_of_static_var() { + return &static_var; +} + +__attribute__((constructor)) +void at_dlopen() { + printf("%s: I am being dlopened\n", __FILE__); +} +__attribute__((destructor)) +void at_dlclose() { + printf("%s: I am being dlclosed\n", __FILE__); +} diff --git a/lib/asan/output_tests/dlclose-test.cc b/lib/asan/output_tests/dlclose-test.cc new file mode 100644 index 0000000..16126eb --- /dev/null +++ b/lib/asan/output_tests/dlclose-test.cc @@ -0,0 +1,74 @@ +//===----------- dlclose-test.cc --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Regression test for +// http://code.google.com/p/address-sanitizer/issues/detail?id=19 +// Bug description: +// 1. application dlopens foo.so +// 2. asan registers all globals from foo.so +// 3. application dlcloses foo.so +// 4. application mmaps some memory to the location where foo.so was before +// 5. application starts using this mmaped memory, but asan still thinks there +// are globals. +// 6. BOOM +//===----------------------------------------------------------------------===// +#include <assert.h> +#include <dlfcn.h> +#include <stdio.h> +#include <string.h> +#include <sys/mman.h> + +#include <string> + +using std::string; + +static const int kPageSize = 4096; + +typedef int *(fun_t)(); + +int main(int argc, char *argv[]) { + string path = string(argv[0]) + "-so.so"; + printf("opening %s ... \n", path.c_str()); + void *lib = dlopen(path.c_str(), RTLD_NOW); + if (!lib) { + printf("error in dlopen(): %s\n", dlerror()); + return 1; + } + fun_t *get = (fun_t*)dlsym(lib, "get_address_of_static_var"); + if (!get) { + printf("failed dlsym\n"); + return 1; + } + int *addr = get(); + assert(((size_t)addr % 32) == 0); // should be 32-byte aligned. + printf("addr: %p\n", addr); + addr[0] = 1; // make sure we can write there. + + // Now dlclose the shared library. + printf("attempting to dlclose\n"); + if (dlclose(lib)) { + printf("failed to dlclose\n"); + return 1; + } + // Now, the page where 'addr' is unmapped. Map it. + size_t page_beg = ((size_t)addr) & ~(kPageSize - 1); + void *res = mmap((void*)(page_beg), kPageSize, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 0, 0); + if (res == (char*)-1L) { + printf("failed to mmap\n"); + return 1; + } + addr[1] = 2; // BOOM (if the bug is not fixed). + printf("PASS\n"); + // Check-Common: PASS + return 0; +} diff --git a/lib/asan/output_tests/global-overflow.cc b/lib/asan/output_tests/global-overflow.cc new file mode 100644 index 0000000..a63eb73 --- /dev/null +++ b/lib/asan/output_tests/global-overflow.cc @@ -0,0 +1,16 @@ +#include <string.h> +int main(int argc, char **argv) { + static char XXX[10]; + static char YYY[10]; + static char ZZZ[10]; + memset(XXX, 0, 10); + memset(YYY, 0, 10); + memset(ZZZ, 0, 10); + int res = YYY[argc * 10]; // BOOOM + // Check-Common: {{READ of size 1 at 0x.* thread T0}} + // Check-Common: {{ #0 0x.* in main .*global-overflow.cc:9}} + // Check-Common: {{0x.* is located 0 bytes to the right of global variable}} + // Check-Common: {{.*YYY.* of size 10}} + res += XXX[argc] + ZZZ[argc]; + return res; +} diff --git a/lib/asan/output_tests/heap-overflow.cc b/lib/asan/output_tests/heap-overflow.cc new file mode 100644 index 0000000..534fbe0 --- /dev/null +++ b/lib/asan/output_tests/heap-overflow.cc @@ -0,0 +1,22 @@ +#include <stdlib.h> +#include <string.h> +int main(int argc, char **argv) { + char *x = (char*)malloc(10 * sizeof(char)); + memset(x, 0, 10); + int res = x[argc * 10]; // BOOOM + free(x); + return res; +} + +// Check-Common: {{READ of size 1 at 0x.* thread T0}} +// Check-Common: {{ #0 0x.* in main .*heap-overflow.cc:6}} +// Check-Common: {{0x.* is located 0 bytes to the right of 10-byte region}} +// Check-Common: {{allocated by thread T0 here:}} + +// Check-Linux: {{ #0 0x.* in .*malloc}} +// Check-Linux: {{ #1 0x.* in main .*heap-overflow.cc:4}} + +// Check-Darwin: {{ #0 0x.* in .*mz_malloc.*}} +// Check-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}} +// Check-Darwin: {{ #2 0x.* in malloc.*}} +// Check-Darwin: {{ #3 0x.* in main heap-overflow.cc:4}} diff --git a/lib/asan/output_tests/interception_failure_test-linux.cc b/lib/asan/output_tests/interception_failure_test-linux.cc new file mode 100644 index 0000000..9e8b753 --- /dev/null +++ b/lib/asan/output_tests/interception_failure_test-linux.cc @@ -0,0 +1,17 @@ +#include <stdlib.h> +#include <stdio.h> + +extern "C" long strtol(const char *nptr, char **endptr, int base) { + fprintf(stderr, "my_strtol_interceptor\n"); + return 0; +} + +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return (int)strtol(x, 0, 10); +} + +// Check-Common: my_strtol_interceptor +// CHECK-NOT: heap-use-after-free + diff --git a/lib/asan/output_tests/interception_malloc_test-linux.cc b/lib/asan/output_tests/interception_malloc_test-linux.cc new file mode 100644 index 0000000..4bb3bd6 --- /dev/null +++ b/lib/asan/output_tests/interception_malloc_test-linux.cc @@ -0,0 +1,19 @@ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +extern "C" void *__interceptor_malloc(size_t size); +extern "C" void *malloc(size_t size) { + write(2, "malloc call\n", sizeof("malloc call\n") - 1); + return __interceptor_malloc(size); +} + +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return (int)strtol(x, 0, 10); +} + +// Check-Common: malloc call +// Check-Common: heap-use-after-free + diff --git a/lib/asan/output_tests/interception_test-linux.cc b/lib/asan/output_tests/interception_test-linux.cc new file mode 100644 index 0000000..0523510 --- /dev/null +++ b/lib/asan/output_tests/interception_test-linux.cc @@ -0,0 +1,18 @@ +#include <stdlib.h> +#include <stdio.h> + +extern "C" long __interceptor_strtol(const char *nptr, char **endptr, int base); +extern "C" long strtol(const char *nptr, char **endptr, int base) { + fprintf(stderr, "my_strtol_interceptor\n"); + return __interceptor_strtol(nptr, endptr, base); +} + +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return (int)strtol(x, 0, 10); +} + +// Check-Common: my_strtol_interceptor +// Check-Common: heap-use-after-free + diff --git a/lib/asan/output_tests/large_func_test.cc b/lib/asan/output_tests/large_func_test.cc new file mode 100644 index 0000000..49751b3 --- /dev/null +++ b/lib/asan/output_tests/large_func_test.cc @@ -0,0 +1,48 @@ +#include <stdlib.h> +__attribute__((noinline)) +static void LargeFunction(int *x, int zero) { + x[0]++; + x[1]++; + x[2]++; + x[3]++; + x[4]++; + x[5]++; + x[6]++; + x[7]++; + x[8]++; + x[9]++; + + x[zero + 111]++; // we should report this exact line + + x[10]++; + x[11]++; + x[12]++; + x[13]++; + x[14]++; + x[15]++; + x[16]++; + x[17]++; + x[18]++; + x[19]++; +} + +int main(int argc, char **argv) { + int *x = new int[100]; + LargeFunction(x, argc - 1); + delete x; +} + +// Check-Common: {{.*ERROR: AddressSanitizer heap-buffer-overflow on address}} +// Check-Common: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} +// Check-Common: {{READ of size 4 at 0x.* thread T0}} + +// atos incorrectly extracts the symbol name for the static functions on +// Darwin. +// Check-Linux: {{ #0 0x.* in LargeFunction.*large_func_test.cc:15}} +// Check-Darwin: {{ #0 0x.* in .*LargeFunction.*large_func_test.cc:15}} + +// Check-Common: {{ #1 0x.* in main .*large_func_test.cc:31}} +// Check-Common: {{0x.* is located 44 bytes to the right of 400-byte region}} +// Check-Common: {{allocated by thread T0 here:}} +// Check-Common: {{ #0 0x.* in operator new.*}} +// Check-Common: {{ #1 0x.* in main .*large_func_test.cc:30}} diff --git a/lib/asan/output_tests/memcmp_test.cc b/lib/asan/output_tests/memcmp_test.cc new file mode 100644 index 0000000..d0e5a43 --- /dev/null +++ b/lib/asan/output_tests/memcmp_test.cc @@ -0,0 +1,10 @@ +#include <string.h> +int main(int argc, char **argv) { + char a1[] = {argc, 2, 3, 4}; + char a2[] = {1, 2*argc, 3, 4}; +// Check-Common: AddressSanitizer stack-buffer-overflow +// Check-Common: {{#0.*memcmp}} +// Check-Common: {{#1.*main}} + int res = memcmp(a1, a2, 4 + argc); // BOOM + return res; +} diff --git a/lib/asan/output_tests/null_deref.cc b/lib/asan/output_tests/null_deref.cc new file mode 100644 index 0000000..c152a42 --- /dev/null +++ b/lib/asan/output_tests/null_deref.cc @@ -0,0 +1,17 @@ +__attribute__((noinline)) +static void NullDeref(int *ptr) { + ptr[10]++; +} +int main() { + NullDeref((int*)0); +} + +// Check-Common: {{.*ERROR: AddressSanitizer crashed on unknown address}} +// Check-Common: {{0x0*00028 .*pc 0x.*}} +// Check-Common: {{AddressSanitizer can not provide additional info. ABORTING}} + +// atos on Mac cannot extract the symbol name correctly. +// Check-Linux: {{ #0 0x.* in NullDeref.*null_deref.cc:3}} +// Check-Darwin: {{ #0 0x.* in .*NullDeref.*null_deref.cc:3}} + +// Check-Common: {{ #1 0x.* in main.*null_deref.cc:6}} diff --git a/lib/asan/output_tests/shared-lib-test-so.cc b/lib/asan/output_tests/shared-lib-test-so.cc new file mode 100644 index 0000000..686a245 --- /dev/null +++ b/lib/asan/output_tests/shared-lib-test-so.cc @@ -0,0 +1,21 @@ +//===----------- shared-lib-test-so.cc --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +int pad[10]; +int GLOB[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +extern "C" +void inc(int index) { + GLOB[index]++; +} diff --git a/lib/asan/output_tests/shared-lib-test.cc b/lib/asan/output_tests/shared-lib-test.cc new file mode 100644 index 0000000..060fcde --- /dev/null +++ b/lib/asan/output_tests/shared-lib-test.cc @@ -0,0 +1,42 @@ +//===----------- shared-lib-test.cc -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +//===----------------------------------------------------------------------===// +#include <dlfcn.h> +#include <stdio.h> +#include <string.h> + +#include <string> + +using std::string; + +typedef void (fun_t)(int x); + +int main(int argc, char *argv[]) { + string path = string(argv[0]) + "-so.so"; + printf("opening %s ... \n", path.c_str()); + void *lib = dlopen(path.c_str(), RTLD_NOW); + if (!lib) { + printf("error in dlopen(): %s\n", dlerror()); + return 1; + } + fun_t *inc = (fun_t*)dlsym(lib, "inc"); + if (!inc) return 1; + printf("ok\n"); + inc(1); + inc(-1); // BOOM + return 0; +} + +// Check-Common: {{.*ERROR: AddressSanitizer global-buffer-overflow}} +// Check-Common: {{READ of size 4 at 0x.* thread T0}} +// Check-Common: {{ #0 0x.*}} +// Check-Common: {{ #1 0x.* in main .*shared-lib-test.cc:35}} diff --git a/lib/asan/output_tests/stack-overflow.cc b/lib/asan/output_tests/stack-overflow.cc new file mode 100644 index 0000000..35fa8a6 --- /dev/null +++ b/lib/asan/output_tests/stack-overflow.cc @@ -0,0 +1,11 @@ +#include <string.h> +int main(int argc, char **argv) { + char x[10]; + memset(x, 0, 10); + int res = x[argc * 10]; // BOOOM + return res; +} + +// Check-Common: {{READ of size 1 at 0x.* thread T0}} +// Check-Common: {{ #0 0x.* in main .*stack-overflow.cc:5}} +// Check-Common: {{Address 0x.* is .* frame <main>}} diff --git a/lib/asan/output_tests/stack-use-after-return.cc.disabled b/lib/asan/output_tests/stack-use-after-return.cc.disabled new file mode 100644 index 0000000..f497157 --- /dev/null +++ b/lib/asan/output_tests/stack-use-after-return.cc.disabled @@ -0,0 +1,27 @@ +#include <stdio.h> + +__attribute__((noinline)) +char *Ident(char *x) { + fprintf(stderr, "1: %p\n", x); + return x; +} + +__attribute__((noinline)) +char *Func1() { + char local; + return Ident(&local); +} + +__attribute__((noinline)) +void Func2(char *x) { + fprintf(stderr, "2: %p\n", x); + *x = 1; + // Check-Common: {{WRITE of size 1 .* thread T0}} + // Check-Common: {{ #0.*Func2.*stack-use-after-return.cc:18}} + // Check-Common: {{is located in frame <.*Func1.*> of T0's stack}} +} + +int main(int argc, char **argv) { + Func2(Func1()); + return 0; +} diff --git a/lib/asan/output_tests/strncpy-overflow.cc b/lib/asan/output_tests/strncpy-overflow.cc new file mode 100644 index 0000000..66d5810 --- /dev/null +++ b/lib/asan/output_tests/strncpy-overflow.cc @@ -0,0 +1,24 @@ +#include <string.h> +#include <stdlib.h> +int main(int argc, char **argv) { + char *hello = (char*)malloc(6); + strcpy(hello, "hello"); + char *short_buffer = (char*)malloc(9); + strncpy(short_buffer, hello, 10); // BOOM + return short_buffer[8]; +} + +// Check-Common: {{WRITE of size 1 at 0x.* thread T0}} +// Check-Linux: {{ #0 0x.* in .*strncpy}} +// Check-Darwin: {{ #0 0x.* in wrap_strncpy}} +// Check-Common: {{ #1 0x.* in main .*strncpy-overflow.cc:7}} +// Check-Common: {{0x.* is located 0 bytes to the right of 9-byte region}} +// Check-Common: {{allocated by thread T0 here:}} + +// Check-Linux: {{ #0 0x.* in .*malloc}} +// Check-Linux: {{ #1 0x.* in main .*strncpy-overflow.cc:6}} + +// Check-Darwin: {{ #0 0x.* in .*mz_malloc.*}} +// Check-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}} +// Check-Darwin: {{ #2 0x.* in malloc.*}} +// Check-Darwin: {{ #3 0x.* in main .*strncpy-overflow.cc:6}} diff --git a/lib/asan/output_tests/test_output.sh b/lib/asan/output_tests/test_output.sh new file mode 100755 index 0000000..6510043 --- /dev/null +++ b/lib/asan/output_tests/test_output.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +set -e # fail on any error + +OS=`uname` +CXX=$1 +CC=$2 +FILE_CHECK=$3 +CXXFLAGS="-mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -g" +SYMBOLIZER=../scripts/asan_symbolize.py +TMP_ASAN_REPORT=asan_report.tmp + +run_program() { + ./$1 2>&1 | $SYMBOLIZER 2> /dev/null | c++filt > $TMP_ASAN_REPORT +} + +# check_program exe_file source_file check_prefixf +check_program() { + run_program $1 + $FILE_CHECK $2 --check-prefix=$3 < $TMP_ASAN_REPORT + rm -f $TMP_ASAN_REPORT +} + +C_TEST=use-after-free +echo "Sanity checking a test in pure C" +$CC -g -faddress-sanitizer -O2 $C_TEST.c +check_program a.out $C_TEST.c CHECK +rm ./a.out + +echo "Sanity checking a test in pure C with -pie" +$CC -g -faddress-sanitizer -O2 $C_TEST.c -pie +check_program a.out $C_TEST.c CHECK +rm ./a.out + +echo "Testing sleep_before_dying" +$CC -g -faddress-sanitizer -O2 $C_TEST.c +export ASAN_OPTIONS="sleep_before_dying=1" +check_program a.out $C_TEST.c CHECKSLEEP +export ASAN_OPTIONS="" +rm ./a.out + +# FIXME: some tests do not need to be ran for all the combinations of arch +# and optimization mode. +for t in *.cc; do + for b in 32 64; do + for O in 0 1 2 3; do + c=`basename $t .cc` + if [[ "$c" == *"-so" ]]; then + continue + fi + if [[ "$c" == *"-linux" ]]; then + if [[ "$OS" != "Linux" ]]; then + continue + fi + fi + c_so=$c-so + exe=$c.$b.O$O + so=$c.$b.O$O-so.so + echo testing $exe + build_command="$CXX $CXXFLAGS -m$b -faddress-sanitizer -O$O $c.cc -o $exe" + [ "$DEBUG" == "1" ] && echo $build_command + $build_command + [ -e "$c_so.cc" ] && $CXX $CXXFLAGS -m$b -faddress-sanitizer -O$O $c_so.cc -fPIC -shared -o $so + run_program $exe + # Check common expected lines for OS. + $FILE_CHECK $c.cc --check-prefix="Check-Common" < $TMP_ASAN_REPORT + # Check OS-specific lines. + if [ `grep -c "Check-$OS" $c.cc` -gt 0 ] + then + $FILE_CHECK $c.cc --check-prefix="Check-$OS" < $TMP_ASAN_REPORT + fi + rm ./$exe + rm ./$TMP_ASAN_REPORT + [ -e "$so" ] && rm ./$so + done + done +done + +exit 0 diff --git a/lib/asan/output_tests/use-after-free.c b/lib/asan/output_tests/use-after-free.c new file mode 100644 index 0000000..801d3f6 --- /dev/null +++ b/lib/asan/output_tests/use-after-free.c @@ -0,0 +1,9 @@ +#include <stdlib.h> +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return x[5]; +} + +// CHECK: heap-use-after-free +// CHECKSLEEP: Sleeping for 1 second diff --git a/lib/asan/output_tests/use-after-free.cc b/lib/asan/output_tests/use-after-free.cc new file mode 100644 index 0000000..c3e9dbe --- /dev/null +++ b/lib/asan/output_tests/use-after-free.cc @@ -0,0 +1,31 @@ +#include <stdlib.h> +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return x[5]; +} + +// Check-Common: {{.*ERROR: AddressSanitizer heap-use-after-free on address}} +// Check-Common: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} +// Check-Common: {{READ of size 1 at 0x.* thread T0}} +// Check-Common: {{ #0 0x.* in main .*use-after-free.cc:5}} +// Check-Common: {{0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*}} +// Check-Common: {{freed by thread T0 here:}} + +// Check-Linux: {{ #0 0x.* in .*free}} +// Check-Linux: {{ #1 0x.* in main .*use-after-free.cc:4}} + +// Check-Darwin: {{ #0 0x.* in .*mz_free.*}} +// We override free() on Darwin, thus no malloc_zone_free +// Check-Darwin: {{ #1 0x.* in wrap_free}} +// Check-Darwin: {{ #2 0x.* in main .*use-after-free.cc:4}} + +// Check-Common: {{previously allocated by thread T0 here:}} + +// Check-Linux: {{ #0 0x.* in .*malloc}} +// Check-Linux: {{ #1 0x.* in main .*use-after-free.cc:3}} + +// Check-Darwin: {{ #0 0x.* in .*mz_malloc.*}} +// Check-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}} +// Check-Darwin: {{ #2 0x.* in malloc.*}} +// Check-Darwin: {{ #3 0x.* in main .*use-after-free.cc:3}} |