diff options
author | Ivan Krasin <krasin@chromium.org> | 2015-10-20 17:34:47 +0000 |
---|---|---|
committer | Ivan Krasin <krasin@chromium.org> | 2015-10-20 17:34:47 +0000 |
commit | cffe8caed3d1c5ba85948d70efa5bee24dd2f334 (patch) | |
tree | 5f534e37f14bca85c48d3cbcd33a4f2c8f0caaec | |
parent | 0f5ac9f5713ca06e3afcc307452a1282d2a0aa9e (diff) | |
download | bcm5719-llvm-cffe8caed3d1c5ba85948d70efa5bee24dd2f334.tar.gz bcm5719-llvm-cffe8caed3d1c5ba85948d70efa5bee24dd2f334.zip |
Disabling speculative loads under asan.
Summary:
While instrumenting std::string with asan I discovered that speculative load might load data from poisoned region. Disabling all speculative loads for asan-annotated functions.
The test follows the std::string implementation.
Corresponding CL in llvm: http://reviews.llvm.org/D13264
Patch by Mike Aizatsky, the review page for the CL is http://reviews.llvm.org/D13265
Reviewers: aizatsky
Subscribers: kcc, llvm-commits
Differential Revision: http://reviews.llvm.org/D13905
llvm-svn: 250837
-rw-r--r-- | compiler-rt/test/asan/TestCases/speculative_load.cc | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/compiler-rt/test/asan/TestCases/speculative_load.cc b/compiler-rt/test/asan/TestCases/speculative_load.cc new file mode 100644 index 00000000000..2409d7a5eee --- /dev/null +++ b/compiler-rt/test/asan/TestCases/speculative_load.cc @@ -0,0 +1,50 @@ +// Verifies that speculative loads from unions do not happen under asan. +// RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1 +// RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 +// RUN: %clangxx_asan -O2 %s -o %t && %run %t 2>&1 +// RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&1 + +#include <sanitizer/asan_interface.h> + +struct S { + struct _long { + void* _pad; + const char* _ptr; + }; + + struct _short { + unsigned char _size; + char _ch[23]; + }; + + union { + _short _s; + _long _l; + } _data; + + S() { + _data._s._size = 0; + __asan_poison_memory_region(_data._s._ch, 23); + } + + bool is_long() const { + return _data._s._size & 1; + } + + const char* get_pointer() const { + return is_long() ? _data._l._ptr : _data._s._ch; + } +}; + + +inline void side_effect(const void *arg) { + __asm__ __volatile__("" : : "r" (arg) : "memory"); +} + +int main(int argc, char **argv) { + S s; + side_effect(&s); // optimizer is too smart otherwise + const char *ptr = s.get_pointer(); + side_effect(ptr); // force use ptr + return 0; +} |