forked from OSchip/llvm-project
Update and improve compiler-rt tests for -mllvm -asan_use_after_return=(never|[runtime]|always).
In addition: - optionally add global flag to capture compile intent for UAR: __asan_detect_use_after_return_always. The global is a SANITIZER_WEAK_ATTRIBUTE. for issue: https://github.com/google/sanitizers/issues/1394 Reviewed By: vitalybuka Differential Revision: https://reviews.llvm.org/D103304
This commit is contained in:
parent
c2f2c1b32c
commit
927688a4cd
|
@ -167,4 +167,5 @@ INTERFACE_FUNCTION(__sanitizer_unaligned_store64)
|
|||
INTERFACE_FUNCTION(__asan_update_allocation_context)
|
||||
INTERFACE_WEAK_FUNCTION(__asan_default_options)
|
||||
INTERFACE_WEAK_FUNCTION(__asan_default_suppressions)
|
||||
INTERFACE_WEAK_FUNCTION(__asan_detect_use_after_return_always)
|
||||
INTERFACE_WEAK_FUNCTION(__asan_on_error)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "lsan/lsan_common.h"
|
||||
#include "sanitizer_common/sanitizer_atomic.h"
|
||||
#include "sanitizer_common/sanitizer_flags.h"
|
||||
#include "sanitizer_common/sanitizer_internal_defs.h"
|
||||
#include "sanitizer_common/sanitizer_libc.h"
|
||||
#include "sanitizer_common/sanitizer_symbolizer.h"
|
||||
#include "ubsan/ubsan_init.h"
|
||||
|
@ -36,6 +37,17 @@ uptr __asan_shadow_memory_dynamic_address; // Global interface symbol.
|
|||
int __asan_option_detect_stack_use_after_return; // Global interface symbol.
|
||||
uptr *__asan_test_only_reported_buggy_pointer; // Used only for testing asan.
|
||||
|
||||
#if !SANITIZER_WINDOWS
|
||||
// Instrumented code can set this value in terms of -asan_use_after_return
|
||||
// * __asan_detect_use_after_return_always is undefined: all instrumented
|
||||
// modules either compiled with asan_use_after_return 1 (runtime) or 0
|
||||
// (never)
|
||||
// * __asan_detect_use_after_return_always is defined: at least one of modules
|
||||
// compiled with asan_use_after_return 2 (always)
|
||||
extern "C" SANITIZER_WEAK_ATTRIBUTE const int
|
||||
__asan_detect_use_after_return_always;
|
||||
#endif // !SANITIZER_WINDOWS
|
||||
|
||||
namespace __asan {
|
||||
|
||||
uptr AsanMappingProfile[kAsanMappingProfileSize];
|
||||
|
@ -387,6 +399,17 @@ static bool UNUSED __local_asan_dyninit = [] {
|
|||
}();
|
||||
#endif
|
||||
|
||||
static void InitAsanOptionDetectStackUseAfterReturn() {
|
||||
__asan_option_detect_stack_use_after_return =
|
||||
flags()->detect_stack_use_after_return;
|
||||
#if !SANITIZER_WINDOWS
|
||||
if (&__asan_detect_use_after_return_always) {
|
||||
CHECK_EQ(1, __asan_detect_use_after_return_always);
|
||||
__asan_option_detect_stack_use_after_return = 1;
|
||||
}
|
||||
#endif // !SANITIZER_WINDOWS
|
||||
}
|
||||
|
||||
static void AsanInitInternal() {
|
||||
if (LIKELY(asan_inited)) return;
|
||||
SanitizerToolName = "AddressSanitizer";
|
||||
|
@ -428,8 +451,7 @@ static void AsanInitInternal() {
|
|||
|
||||
__sanitizer_set_report_path(common_flags()->log_path);
|
||||
|
||||
__asan_option_detect_stack_use_after_return =
|
||||
flags()->detect_stack_use_after_return;
|
||||
InitAsanOptionDetectStackUseAfterReturn();
|
||||
|
||||
__sanitizer::InitializePlatformEarly();
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
___asan_default_options
|
||||
___asan_default_suppressions
|
||||
___asan_detect_use_after_return_always
|
||||
___asan_on_error
|
||||
___asan_set_shadow_00
|
||||
___asan_set_shadow_f1
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// This test checks that the implementation of use-after-return
|
||||
// is async-signal-safe.
|
||||
// RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread && %run %t
|
||||
// RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread -mllvm -asan-use-after-return=never && %run %t
|
||||
// RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread -mllvm -asan-use-after-return=always && %run %t
|
||||
// REQUIRES: stable-runtime
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -3,16 +3,32 @@
|
|||
// RUN: %clangxx_asan -O2 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O3 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t
|
||||
// RUN: %clangxx_asan -O0 %s -pthread -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O1 %s -pthread -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O2 %s -pthread -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O3 %s -pthread -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O3 %s -pthread -o %t -mllvm -asan-use-after-return=never && %run %t
|
||||
// Regression test for a CHECK failure with small stack size and large frame.
|
||||
// RUN: %clangxx_asan -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=131072 && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s
|
||||
// RUN: %clangxx_asan -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=131072 -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s
|
||||
//
|
||||
// Test that we can find UAR in a thread other than main:
|
||||
// Test that we can find UAR in a thread other than main (UAR mode: runtime):
|
||||
// RUN: %clangxx_asan -DUseThread -O2 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s
|
||||
//
|
||||
// Test the max_uar_stack_size_log/min_uar_stack_size_log flag.
|
||||
// (uses the previous)
|
||||
//
|
||||
// RUN: %env_asan_opts=detect_stack_use_after_return=1:max_uar_stack_size_log=20:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s
|
||||
// RUN: %env_asan_opts=detect_stack_use_after_return=1:min_uar_stack_size_log=24:max_uar_stack_size_log=24:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-24 %s
|
||||
//
|
||||
// Test that we can find UAR in a thread other than main (UAR mode: always):
|
||||
// RUN: %clangxx_asan -DUseThread -O2 %s -pthread -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s
|
||||
//
|
||||
// Test the max_uar_stack_size_log/min_uar_stack_size_log flag.
|
||||
// (uses the previous)
|
||||
//
|
||||
// RUN: %env_asan_opts=max_uar_stack_size_log=20:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s
|
||||
// RUN: %env_asan_opts=min_uar_stack_size_log=24:max_uar_stack_size_log=24:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-24 %s
|
||||
|
||||
// This test runs out of stack on AArch64.
|
||||
// UNSUPPORTED: aarch64
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O2 %s -o %t -mllvm -asan-use-after-return=always && not %run %t 2>&1 | FileCheck %s
|
||||
// XFAIL: windows-msvc
|
||||
|
||||
// FIXME: Fix this test under GCC.
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
// 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
|
||||
// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-use-after-return=never && \
|
||||
// RUN: %run %t 2>&1 | FileCheck --check-prefix=CHECK-NO-UAR %s
|
||||
// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-use-after-return=always && \
|
||||
// RUN: not %run %t 2>&1 | 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
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Test how we produce the scariness score.
|
||||
|
||||
// UAR Mode: runtime
|
||||
// RUN: %clangxx_asan -O0 %s -o %t
|
||||
// On OSX and Windows, alloc_dealloc_mismatch=1 isn't 100% reliable, so it's
|
||||
// off by default. It's safe for these tests, though, so we turn it on.
|
||||
|
@ -33,6 +34,41 @@
|
|||
// RUN: not %run %t 25 2>&1 | FileCheck %s --check-prefix=CHECK25
|
||||
// RUN: not %run %t 26 2>&1 | FileCheck %s --check-prefix=CHECK26
|
||||
// RUN: not %run %t 27 2>&1 | FileCheck %s --check-prefix=CHECK27
|
||||
//
|
||||
// UAR Mode: always
|
||||
// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-use-after-return=always
|
||||
// On OSX and Windows, alloc_dealloc_mismatch=1 isn't 100% reliable, so it's
|
||||
// off by default. It's safe for these tests, though, so we turn it on.
|
||||
// RUN: export %env_asan_opts=handle_abort=1:print_scariness=1:alloc_dealloc_mismatch=1
|
||||
// Make sure the stack is limited (may not be the default under GNU make)
|
||||
// RUN: ulimit -s 4096
|
||||
// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK1
|
||||
// RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK2
|
||||
// RUN: not %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK3
|
||||
// RUN: not %run %t 4 2>&1 | FileCheck %s --check-prefix=CHECK4
|
||||
// RUN: not %run %t 5 2>&1 | FileCheck %s --check-prefix=CHECK5
|
||||
// RUN: not %run %t 6 2>&1 | FileCheck %s --check-prefix=CHECK6
|
||||
// RUN: not %run %t 7 2>&1 | FileCheck %s --check-prefix=CHECK7
|
||||
// RUN: not %run %t 8 2>&1 | FileCheck %s --check-prefix=CHECK8
|
||||
// RUN: not %run %t 9 2>&1 | FileCheck %s --check-prefix=CHECK9
|
||||
// RUN: not %run %t 10 2>&1 | FileCheck %s --check-prefix=CHECK10
|
||||
// RUN: not %run %t 11 2>&1 | FileCheck %s --check-prefix=CHECK11
|
||||
// RUN: not %run %t 12 2>&1 | FileCheck %s --check-prefix=CHECK12
|
||||
// RUN: not %run %t 13 2>&1 | FileCheck %s --check-prefix=CHECK13
|
||||
// RUN: not %run %t 14 2>&1 | FileCheck %s --check-prefix=CHECK14
|
||||
// RUN: not %run %t 15 2>&1 | FileCheck %s --check-prefix=CHECK15
|
||||
// RUN: not %run %t 16 2>&1 | FileCheck %s --check-prefix=CHECK16
|
||||
// RUN: not %run %t 17 2>&1 | FileCheck %s --check-prefix=CHECK17
|
||||
// RUN: not %run %t 18 2>&1 | FileCheck %s --check-prefix=CHECK18
|
||||
// RUN: not %run %t 19 2>&1 | FileCheck %s --check-prefix=CHECK19
|
||||
// RUN: not %run %t 20 2>&1 | FileCheck %s --check-prefix=CHECK20
|
||||
// RUN: not %run %t 21 2>&1 | FileCheck %s --check-prefix=CHECK21
|
||||
// RUN: not %run %t 22 2>&1 | FileCheck %s --check-prefix=CHECK22
|
||||
// RUN: not %run %t 23 2>&1 | FileCheck %s --check-prefix=CHECK23
|
||||
// RUN: not %run %t 24 2>&1 | FileCheck %s --check-prefix=CHECK24
|
||||
// RUN: not %run %t 25 2>&1 | FileCheck %s --check-prefix=CHECK25
|
||||
// RUN: not %run %t 26 2>&1 | FileCheck %s --check-prefix=CHECK26
|
||||
// RUN: not %run %t 27 2>&1 | FileCheck %s --check-prefix=CHECK27
|
||||
// Parts of the test are too platform-specific:
|
||||
// REQUIRES: x86_64-target-arch
|
||||
// REQUIRES: shell
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Test that use-after-return works with exceptions.
|
||||
// RUN: %clangxx_asan -O0 %s -o %t
|
||||
// RUN: %env_asan_opts=detect_stack_use_after_return=1 %run %t
|
||||
// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-use-after-return=always
|
||||
// RUN: %run %t
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
|
@ -2645,6 +2645,18 @@ bool ModuleAddressSanitizer::instrumentModule(Module &M) {
|
|||
appendToGlobalDtors(M, AsanDtorFunction, Priority);
|
||||
}
|
||||
|
||||
#if !SANITIZER_WINDOWS
|
||||
assert(ClUseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
|
||||
if (ClUseAfterReturn == AsanDetectStackUseAfterReturnMode::Always) {
|
||||
Type *IntTy = Type::getInt32Ty(*C);
|
||||
M.getOrInsertGlobal("__asan_detect_use_after_return_always", IntTy, [&] {
|
||||
return new GlobalVariable(
|
||||
M, IntTy, /*isConstant=*/true, GlobalValue::WeakODRLinkage,
|
||||
ConstantInt::get(IntTy, 1), "__asan_detect_use_after_return_always");
|
||||
});
|
||||
}
|
||||
#endif // !SANITIZER_WINDOWS
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=0 -S | FileCheck %s --check-prefixes=CHECK,NEVER
|
||||
; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=1 -S | FileCheck %s --check-prefixes=CHECK,RUNTIME
|
||||
; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=0 -S | FileCheck %s --check-prefixes=CHECK,NEVER --implicit-check-not=__asan_detect_use_after_return_always
|
||||
; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=1 -S | FileCheck %s --check-prefixes=CHECK,RUNTIME --implicit-check-not=__asan_detect_use_after_return_always
|
||||
; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=2 -S | FileCheck %s --check-prefixes=CHECK,ALWAYS
|
||||
target datalayout = "e-i64:64-f80:128-s:64-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; ALWAYS-LABEL: @__asan_detect_use_after_return_always =
|
||||
; ALWAYS-SAME: weak_odr constant i32 1
|
||||
|
||||
declare void @Foo(i8*)
|
||||
|
||||
define void @Empty() uwtable sanitize_address {
|
||||
|
|
|
@ -135,6 +135,7 @@ target(asan_target_type, "asan") {
|
|||
# asan
|
||||
"-Wl,-U,___asan_default_options",
|
||||
"-Wl,-U,___asan_default_suppressions",
|
||||
"-Wl,-U,___asan_detect_use_after_return_always",
|
||||
"-Wl,-U,___asan_on_error",
|
||||
"-Wl,-U,___asan_set_shadow_00",
|
||||
"-Wl,-U,___asan_set_shadow_f1",
|
||||
|
|
Loading…
Reference in New Issue