From 74ddba0c95bc0bc2b1bf23bb95f5c6e3e539aec5 Mon Sep 17 00:00:00 2001 From: Matt Morehouse Date: Fri, 28 Jul 2017 19:52:31 +0000 Subject: [PATCH] Add end-to-end tests for overflows of byval arguments. Summary: Included is one test for passing structs by value and one test for passing C++ objects by value. Reviewers: eugenis, vitalybuka Reviewed By: eugenis Subscribers: srhines, kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D34827 llvm-svn: 309424 --- .../test/asan/TestCases/pass-object-byval.cc | 36 ++++++++++++++++++ .../asan/TestCases/pass-struct-byval-uar.cc | 38 +++++++++++++++++++ .../test/asan/TestCases/pass-struct-byval.cc | 23 +++++++++++ 3 files changed, 97 insertions(+) create mode 100644 compiler-rt/test/asan/TestCases/pass-object-byval.cc create mode 100644 compiler-rt/test/asan/TestCases/pass-struct-byval-uar.cc create mode 100644 compiler-rt/test/asan/TestCases/pass-struct-byval.cc diff --git a/compiler-rt/test/asan/TestCases/pass-object-byval.cc b/compiler-rt/test/asan/TestCases/pass-object-byval.cc new file mode 100644 index 000000000000..189fcbeb2883 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/pass-object-byval.cc @@ -0,0 +1,36 @@ +// Verify that objects passed by value get red zones and that the copy +// constructor is called. +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s --implicit-check-not \ +// RUN: Assertion{{.*}}failed +#include + +class A { + public: + A() : me(this) {} + A(const A &other) : me(this) { + for (int i = 0; i < 8; ++i) a[i] = other.a[i]; + } + + int a[8]; + A *me; +}; + +int bar(A *a) { + int *volatile ptr = &a->a[0]; + return *(ptr - 1); +} + +void foo(A a) { + assert(a.me == &a); + bar(&a); +} + +int main() { + A a; + foo(a); +} + +// CHECK: ERROR: AddressSanitizer: stack-buffer-overflow +// CHECK: READ of size 4 at +// CHECK: is located in stack of thread diff --git a/compiler-rt/test/asan/TestCases/pass-struct-byval-uar.cc b/compiler-rt/test/asan/TestCases/pass-struct-byval-uar.cc new file mode 100644 index 000000000000..3f2fd09c6d91 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/pass-struct-byval-uar.cc @@ -0,0 +1,38 @@ +// Test that use-after-return works with arguments passed by value. +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-NO-UAR %s +// RUN: not %env_asan_opts=detect_stack_use_after_return=1 %run %t 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-UAR %s +// +// On several architectures, the IR does not use byval arguments for foo() and +// instead creates a copy in main() and gives foo() a pointer to the copy. In +// that case, ASAN has nothing to poison on return from foo() and will not +// detect the UAR. +// REQUIRES: x86_64-target-arch, linux, not-android + +#include + +struct A { + int a[8]; +}; + +A *foo(A a) { + return &a; +} + +int main() { + A *a = foo(A()); + a->a[0] = 7; + std::fprintf(stderr, "\n"); // Ensures some output is generated for FileCheck + // to verify in the case where UAR is not + // detected. +} + +// CHECK-NO-UAR-NOT: ERROR: AddressSanitizer: stack-use-after-return +// CHECK-NO-UAR-NOT: WRITE of size 4 at +// CHECK-NO-UAR-NOT: Memory access at offset {{[0-9]+}} is inside this variable +// +// CHECK-UAR: ERROR: AddressSanitizer: stack-use-after-return +// CHECK-UAR: WRITE of size 4 at +// CHECK-UAR: Memory access at offset {{[0-9]+}} is inside this variable diff --git a/compiler-rt/test/asan/TestCases/pass-struct-byval.cc b/compiler-rt/test/asan/TestCases/pass-struct-byval.cc new file mode 100644 index 000000000000..ba49eccf41ca --- /dev/null +++ b/compiler-rt/test/asan/TestCases/pass-struct-byval.cc @@ -0,0 +1,23 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s + +struct A { + int a[8]; +}; + +int bar(A *a) { + int *volatile ptr = &a->a[0]; + return *(ptr - 1); +} + +void foo(A a) { + bar(&a); +} + +int main() { + foo(A()); +} + +// CHECK: ERROR: AddressSanitizer: stack-buffer-underflow +// CHECK: READ of size 4 at +// CHECK: is located in stack of thread