diff options
author | Ed Schouten <ed@FreeBSD.org> | 2013-05-27 18:27:12 +0000 |
---|---|---|
committer | Ed Schouten <ed@FreeBSD.org> | 2013-05-27 18:27:12 +0000 |
commit | 11023dc647fd8f41418da90d59db138400d0f334 (patch) | |
tree | 50f0ab80515576749ef638dd0766b70a65904bfa /lib/msan/lit_tests | |
parent | 58aabf08b77d221489f10e274812ec60917c21a8 (diff) |
Diffstat (limited to 'lib/msan/lit_tests')
-rw-r--r-- | lib/msan/lit_tests/CMakeLists.txt | 32 | ||||
-rw-r--r-- | lib/msan/lit_tests/Linux/glob.cc | 26 | ||||
-rw-r--r-- | lib/msan/lit_tests/Linux/glob_test_root/aa | 0 | ||||
-rw-r--r-- | lib/msan/lit_tests/Linux/glob_test_root/ab | 0 | ||||
-rw-r--r-- | lib/msan/lit_tests/Linux/glob_test_root/ba | 0 | ||||
-rw-r--r-- | lib/msan/lit_tests/Linux/lit.local.cfg | 9 | ||||
-rw-r--r-- | lib/msan/lit_tests/Linux/syscalls.cc | 50 | ||||
-rw-r--r-- | lib/msan/lit_tests/Unit/lit.cfg | 26 | ||||
-rw-r--r-- | lib/msan/lit_tests/Unit/lit.site.cfg.in | 17 | ||||
-rw-r--r-- | lib/msan/lit_tests/c-strdup.c | 17 | ||||
-rw-r--r-- | lib/msan/lit_tests/default_blacklist.cc | 3 | ||||
-rw-r--r-- | lib/msan/lit_tests/getaddrinfo-positive.cc | 19 | ||||
-rw-r--r-- | lib/msan/lit_tests/getaddrinfo.cc | 24 | ||||
-rw-r--r-- | lib/msan/lit_tests/heap-origin.cc | 33 | ||||
-rw-r--r-- | lib/msan/lit_tests/lit.cfg | 85 | ||||
-rw-r--r-- | lib/msan/lit_tests/lit.site.cfg.in | 18 | ||||
-rw-r--r-- | lib/msan/lit_tests/no_sanitize_memory.cc | 34 | ||||
-rw-r--r-- | lib/msan/lit_tests/no_sanitize_memory_prop.cc | 33 | ||||
-rw-r--r-- | lib/msan/lit_tests/readdir64.cc | 27 | ||||
-rw-r--r-- | lib/msan/lit_tests/stack-origin.cc | 32 |
20 files changed, 485 insertions, 0 deletions
diff --git a/lib/msan/lit_tests/CMakeLists.txt b/lib/msan/lit_tests/CMakeLists.txt new file mode 100644 index 0000000000000..ed2da6b839f57 --- /dev/null +++ b/lib/msan/lit_tests/CMakeLists.txt @@ -0,0 +1,32 @@ +set(MSAN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) +set(MSAN_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/..) + +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + ) + +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg + ) + +if(COMPILER_RT_CAN_EXECUTE_TESTS) + # Run MSan tests only if we're sure we may produce working binaries. + set(MSAN_TEST_DEPS + ${SANITIZER_COMMON_LIT_TEST_DEPS} + ${MSAN_RUNTIME_LIBRARIES} + msan_blacklist) + set(MSAN_TEST_PARAMS + msan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + ) + if(LLVM_INCLUDE_TESTS) + list(APPEND MSAN_TEST_DEPS MsanUnitTests) + endif() + add_lit_testsuite(check-msan "Running the MemorySanitizer tests" + ${CMAKE_CURRENT_BINARY_DIR} + PARAMS ${MSAN_TEST_PARAMS} + DEPENDS ${MSAN_TEST_DEPS} + ) + set_target_properties(check-msan PROPERTIES FOLDER "MSan tests") +endif() diff --git a/lib/msan/lit_tests/Linux/glob.cc b/lib/msan/lit_tests/Linux/glob.cc new file mode 100644 index 0000000000000..513679c6d3d7f --- /dev/null +++ b/lib/msan/lit_tests/Linux/glob.cc @@ -0,0 +1,26 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t %p 2>&1 | FileCheck %s +// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t %p 2>&1 | FileCheck %s + +#include <assert.h> +#include <glob.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +int main(int argc, char *argv[]) { + assert(argc == 2); + char buf[1024]; + snprintf(buf, sizeof(buf), "%s/%s", argv[1], "glob_test_root/*a"); + + glob_t globbuf; + int res = glob(buf, 0, 0, &globbuf); + + printf("%d %s\n", errno, strerror(errno)); + assert(res == 0); + assert(globbuf.gl_pathc == 2); + printf("%zu\n", strlen(globbuf.gl_pathv[0])); + printf("%zu\n", strlen(globbuf.gl_pathv[1])); + printf("PASS\n"); + // CHECK: PASS + return 0; +} diff --git a/lib/msan/lit_tests/Linux/glob_test_root/aa b/lib/msan/lit_tests/Linux/glob_test_root/aa new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/lib/msan/lit_tests/Linux/glob_test_root/aa diff --git a/lib/msan/lit_tests/Linux/glob_test_root/ab b/lib/msan/lit_tests/Linux/glob_test_root/ab new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/lib/msan/lit_tests/Linux/glob_test_root/ab diff --git a/lib/msan/lit_tests/Linux/glob_test_root/ba b/lib/msan/lit_tests/Linux/glob_test_root/ba new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/lib/msan/lit_tests/Linux/glob_test_root/ba diff --git a/lib/msan/lit_tests/Linux/lit.local.cfg b/lib/msan/lit_tests/Linux/lit.local.cfg new file mode 100644 index 0000000000000..57271b8078a49 --- /dev/null +++ b/lib/msan/lit_tests/Linux/lit.local.cfg @@ -0,0 +1,9 @@ +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +if root.host_os not in ['Linux']: + config.unsupported = True diff --git a/lib/msan/lit_tests/Linux/syscalls.cc b/lib/msan/lit_tests/Linux/syscalls.cc new file mode 100644 index 0000000000000..c12eda39189ee --- /dev/null +++ b/lib/msan/lit_tests/Linux/syscalls.cc @@ -0,0 +1,50 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t 2>&1 +// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t 2>&1 + +#include <assert.h> +#include <errno.h> +#include <glob.h> +#include <stdio.h> +#include <string.h> + +#include <sanitizer/linux_syscall_hooks.h> +#include <sanitizer/msan_interface.h> + +/* Test the presence of __sanitizer_syscall_ in the tool runtime, and general + sanity of their behaviour. */ + +int main(int argc, char *argv[]) { + char buf[1000]; + const int kTen = 10; + memset(buf, 0, sizeof(buf)); + __msan_unpoison(buf, sizeof(buf)); + __sanitizer_syscall_pre_recvmsg(0, buf, 0); + __sanitizer_syscall_pre_rt_sigpending(buf, kTen); + __sanitizer_syscall_pre_getdents(0, buf, kTen); + __sanitizer_syscall_pre_getdents64(0, buf, kTen); + + __msan_unpoison(buf, sizeof(buf)); + __sanitizer_syscall_post_recvmsg(0, 0, buf, 0); + __sanitizer_syscall_post_rt_sigpending(-1, buf, kTen); + __sanitizer_syscall_post_getdents(0, 0, buf, kTen); + __sanitizer_syscall_post_getdents64(0, 0, buf, kTen); + assert(__msan_test_shadow(buf, sizeof(buf)) == -1); + + __msan_unpoison(buf, sizeof(buf)); + __sanitizer_syscall_post_recvmsg(kTen, 0, buf, 0); + + // Tell the kernel that the output struct size is 10 bytes, verify that those + // bytes are unpoisoned, and the next byte is not. + __msan_poison(buf, kTen + 1); + __sanitizer_syscall_post_rt_sigpending(0, buf, kTen); + assert(__msan_test_shadow(buf, sizeof(buf)) == kTen); + + __msan_poison(buf, kTen + 1); + __sanitizer_syscall_post_getdents(kTen, 0, buf, kTen); + assert(__msan_test_shadow(buf, sizeof(buf)) == kTen); + + __msan_poison(buf, kTen + 1); + __sanitizer_syscall_post_getdents64(kTen, 0, buf, kTen); + assert(__msan_test_shadow(buf, sizeof(buf)) == kTen); + return 0; +} diff --git a/lib/msan/lit_tests/Unit/lit.cfg b/lib/msan/lit_tests/Unit/lit.cfg new file mode 100644 index 0000000000000..ee379d0deaedd --- /dev/null +++ b/lib/msan/lit_tests/Unit/lit.cfg @@ -0,0 +1,26 @@ +# -*- Python -*- + +import os + +def get_required_attr(config, attr_name): + attr_value = getattr(config, attr_name, None) + if not attr_value: + lit.fatal("No attribute %r in test configuration! You may need to run " + "tests from your build directory or add this attribute " + "to lit.site.cfg " % attr_name) + return attr_value + +# Setup attributes common for all compiler-rt projects. +compiler_rt_src_root = get_required_attr(config, 'compiler_rt_src_root') +compiler_rt_lit_unit_cfg = os.path.join(compiler_rt_src_root, "lib", + "lit.common.unit.cfg") +lit.load_config(config, compiler_rt_lit_unit_cfg) + +# Setup config name. +config.name = 'MemorySanitizer-Unit' + +# Setup test source and exec root. For unit tests, we define +# it as build directory with MSan unit tests. +msan_binary_dir = get_required_attr(config, "msan_binary_dir") +config.test_exec_root = os.path.join(msan_binary_dir, "tests") +config.test_source_root = config.test_exec_root diff --git a/lib/msan/lit_tests/Unit/lit.site.cfg.in b/lib/msan/lit_tests/Unit/lit.site.cfg.in new file mode 100644 index 0000000000000..a91f6713303a1 --- /dev/null +++ b/lib/msan/lit_tests/Unit/lit.site.cfg.in @@ -0,0 +1,17 @@ +## Autogenerated by LLVM/Clang configuration. +# Do not edit! + +config.target_triple = "@TARGET_TRIPLE@" +config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@" +config.llvm_build_mode = "@LLVM_BUILD_MODE@" +config.msan_binary_dir = "@MSAN_BINARY_DIR@" + +try: + config.llvm_build_mode = config.llvm_build_mode % lit.params +except KeyError,e: + key, = e.args + lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key, key)) + +# Let the main config do the real work. +lit.load_config(config, "@MSAN_SOURCE_DIR@/lit_tests/Unit/lit.cfg") diff --git a/lib/msan/lit_tests/c-strdup.c b/lib/msan/lit_tests/c-strdup.c new file mode 100644 index 0000000000000..7772f0f307b72 --- /dev/null +++ b/lib/msan/lit_tests/c-strdup.c @@ -0,0 +1,17 @@ +// RUN: %clang_msan -m64 -O0 %s -o %t && %t >%t.out 2>&1 +// RUN: %clang_msan -m64 -O1 %s -o %t && %t >%t.out 2>&1 +// RUN: %clang_msan -m64 -O2 %s -o %t && %t >%t.out 2>&1 +// RUN: %clang_msan -m64 -O3 %s -o %t && %t >%t.out 2>&1 + +// Test that strdup in C programs is intercepted. +// GLibC headers translate strdup to __strdup at -O1 and higher. + +#include <stdlib.h> +#include <string.h> +int main(int argc, char **argv) { + char buf[] = "abc"; + char *p = strdup(buf); + if (*p) + exit(0); + return 0; +} diff --git a/lib/msan/lit_tests/default_blacklist.cc b/lib/msan/lit_tests/default_blacklist.cc new file mode 100644 index 0000000000000..32cc02257cb09 --- /dev/null +++ b/lib/msan/lit_tests/default_blacklist.cc @@ -0,0 +1,3 @@ +// Test that MSan uses the default blacklist from resource directory. +// RUN: %clangxx_msan -### %s 2>&1 | FileCheck %s +// CHECK: fsanitize-blacklist={{.*}}msan_blacklist.txt diff --git a/lib/msan/lit_tests/getaddrinfo-positive.cc b/lib/msan/lit_tests/getaddrinfo-positive.cc new file mode 100644 index 0000000000000..f16679cc2aa26 --- /dev/null +++ b/lib/msan/lit_tests/getaddrinfo-positive.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdlib.h> + +int main(void) { + struct addrinfo *ai; + struct addrinfo hint; + int res = getaddrinfo("localhost", NULL, &hint, &ai); + // CHECK: UMR in __interceptor_getaddrinfo at offset 0 inside + // CHECK: WARNING: Use of uninitialized value + // CHECK: #0 {{.*}} in main {{.*}}getaddrinfo-positive.cc:[[@LINE-3]] + return 0; +} diff --git a/lib/msan/lit_tests/getaddrinfo.cc b/lib/msan/lit_tests/getaddrinfo.cc new file mode 100644 index 0000000000000..0518cf4733d0f --- /dev/null +++ b/lib/msan/lit_tests/getaddrinfo.cc @@ -0,0 +1,24 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdlib.h> + +void poison_stack_ahead() { + char buf[100000]; + // With -O0 this poisons a large chunk of stack. +} + +int main(void) { + poison_stack_ahead(); + + struct addrinfo *ai; + + // This should trigger loading of libnss_dns and friends. + // Those libraries are typically uninstrumented.They will call strlen() on a + // stack-allocated buffer, which is very likely to be poisoned. Test that we + // don't report this as an UMR. + int res = getaddrinfo("not-in-etc-hosts", NULL, NULL, &ai); + return 0; +} diff --git a/lib/msan/lit_tests/heap-origin.cc b/lib/msan/lit_tests/heap-origin.cc new file mode 100644 index 0000000000000..54e2c31438ff8 --- /dev/null +++ b/lib/msan/lit_tests/heap-origin.cc @@ -0,0 +1,33 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out + +// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out +// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O1 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out +// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out +// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out + +#include <stdlib.h> +int main(int argc, char **argv) { + char *volatile x = (char*)malloc(5 * sizeof(char)); + if (*x) + exit(0); + // CHECK: WARNING: Use of uninitialized value + // CHECK: {{#0 0x.* in main .*heap-origin.cc:}}[[@LINE-3]] + + // CHECK-ORIGINS: Uninitialized value was created by a heap allocation + // CHECK-ORIGINS: {{#0 0x.* in .*malloc}} + // CHECK-ORIGINS: {{#1 0x.* in main .*heap-origin.cc:}}[[@LINE-8]] + + // CHECK: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*heap-origin.cc:.* main}} + return 0; +} diff --git a/lib/msan/lit_tests/lit.cfg b/lib/msan/lit_tests/lit.cfg new file mode 100644 index 0000000000000..42381885fe8e5 --- /dev/null +++ b/lib/msan/lit_tests/lit.cfg @@ -0,0 +1,85 @@ +# -*- Python -*- + +import os + +def get_required_attr(config, attr_name): + attr_value = getattr(config, attr_name, None) + if not attr_value: + lit.fatal("No attribute %r in test configuration! You may need to run " + "tests from your build directory or add this attribute " + "to lit.site.cfg " % attr_name) + return attr_value + +# Setup config name. +config.name = 'MemorySanitizer' + +# Setup source root. +config.test_source_root = os.path.dirname(__file__) + +def DisplayNoConfigMessage(): + lit.fatal("No site specific configuration available! " + + "Try running your test from the build tree or running " + + "make check-msan") + +# Figure out LLVM source root. +llvm_src_root = getattr(config, 'llvm_src_root', None) +if llvm_src_root is None: + # We probably haven't loaded the site-specific configuration: the user + # is likely trying to run a test file directly, and the site configuration + # wasn't created by the build system. + msan_site_cfg = lit.params.get('msan_site_config', None) + if (msan_site_cfg) and (os.path.exists(msan_site_cfg)): + lit.load_config(config, msan_site_cfg) + raise SystemExit + + # Try to guess the location of site-specific configuration using llvm-config + # util that can point where the build tree is. + llvm_config = lit.util.which("llvm-config", config.environment["PATH"]) + if not llvm_config: + DisplayNoConfigMessage() + + # Find out the presumed location of generated site config. + llvm_obj_root = lit.util.capture(["llvm-config", "--obj-root"]).strip() + msan_site_cfg = os.path.join(llvm_obj_root, "projects", "compiler-rt", + "lib", "msan", "lit_tests", "lit.site.cfg") + if (not msan_site_cfg) or (not os.path.exists(msan_site_cfg)): + DisplayNoConfigMessage() + + lit.load_config(config, msan_site_cfg) + raise SystemExit + +# Setup attributes common for all compiler-rt projects. +compiler_rt_src_root = get_required_attr(config, "compiler_rt_src_root") +compiler_rt_lit_cfg = os.path.join(compiler_rt_src_root, "lib", + "lit.common.cfg") +if (not compiler_rt_lit_cfg) or (not os.path.exists(compiler_rt_lit_cfg)): + lit.fatal("Can't find common compiler-rt lit config at: %r" + % compiler_rt_lit_cfg) +lit.load_config(config, compiler_rt_lit_cfg) + +# Setup default compiler flags used with -fsanitize=memory option. +clang_msan_cflags = ["-fsanitize=memory", + "-mno-omit-leaf-frame-pointer", + "-fno-omit-frame-pointer", + "-fno-optimize-sibling-calls", + "-g"] +clang_msan_cxxflags = ["-ccc-cxx "] + clang_msan_cflags +config.substitutions.append( ("%clang_msan ", + " ".join([config.clang] + clang_msan_cflags) + + " ") ) +config.substitutions.append( ("%clangxx_msan ", + " ".join([config.clang] + clang_msan_cxxflags) + + " ") ) + +# Setup path to external LLVM symbolizer to run MemorySanitizer output tests. +llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) +if llvm_tools_dir: + llvm_symbolizer_path = os.path.join(llvm_tools_dir, "llvm-symbolizer") + config.environment['MSAN_SYMBOLIZER_PATH'] = llvm_symbolizer_path + +# Default test suffixes. +config.suffixes = ['.c', '.cc', '.cpp'] + +# MemorySanitizer tests are currently supported on Linux only. +if config.host_os not in ['Linux']: + config.unsupported = True diff --git a/lib/msan/lit_tests/lit.site.cfg.in b/lib/msan/lit_tests/lit.site.cfg.in new file mode 100644 index 0000000000000..3b969e0b06142 --- /dev/null +++ b/lib/msan/lit_tests/lit.site.cfg.in @@ -0,0 +1,18 @@ +config.target_triple = "@TARGET_TRIPLE@" +config.host_os = "@HOST_OS@" +config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@" +config.llvm_obj_root = "@LLVM_BINARY_DIR@" +config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" +config.clang = "@LLVM_BINARY_DIR@/bin/clang" + +# LLVM tools dir can be passed in lit parameters, so try to +# apply substitution. +try: + config.llvm_tools_dir = config.llvm_tools_dir % lit.params +except KeyError,e: + key, = e.args + lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key, key)) + +# Let the main config do the real work. +lit.load_config(config, "@MSAN_SOURCE_DIR@/lit_tests/lit.cfg") diff --git a/lib/msan/lit_tests/no_sanitize_memory.cc b/lib/msan/lit_tests/no_sanitize_memory.cc new file mode 100644 index 0000000000000..48afc17e35e92 --- /dev/null +++ b/lib/msan/lit_tests/no_sanitize_memory.cc @@ -0,0 +1,34 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t >%t.out 2>&1 +// RUN: %clangxx_msan -m64 -O1 %s -o %t && %t >%t.out 2>&1 +// RUN: %clangxx_msan -m64 -O2 %s -o %t && %t >%t.out 2>&1 +// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t >%t.out 2>&1 + +// RUN: %clangxx_msan -m64 -O0 %s -o %t -DCHECK_IN_F && %t >%t.out 2>&1 +// RUN: %clangxx_msan -m64 -O1 %s -o %t -DCHECK_IN_F && %t >%t.out 2>&1 +// RUN: %clangxx_msan -m64 -O2 %s -o %t -DCHECK_IN_F && %t >%t.out 2>&1 +// RUN: %clangxx_msan -m64 -O3 %s -o %t -DCHECK_IN_F && %t >%t.out 2>&1 + +// Test that (no_sanitize_memory) functions +// * don't check shadow values (-DCHECK_IN_F) +// * treat all values loaded from memory as fully initialized (-UCHECK_IN_F) + +#include <stdlib.h> +#include <stdio.h> + +__attribute__((noinline)) +__attribute__((no_sanitize_memory)) +int f(void) { + int x; + int * volatile p = &x; +#ifdef CHECK_IN_F + if (*p) + exit(0); +#endif + return *p; +} + +int main(void) { + if (f()) + exit(0); + return 0; +} diff --git a/lib/msan/lit_tests/no_sanitize_memory_prop.cc b/lib/msan/lit_tests/no_sanitize_memory_prop.cc new file mode 100644 index 0000000000000..c74ca6b89db98 --- /dev/null +++ b/lib/msan/lit_tests/no_sanitize_memory_prop.cc @@ -0,0 +1,33 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t >%t.out 2>&1 +// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out + +// Test that (no_sanitize_memory) functions propagate shadow. + +// Note that at -O0 there is no report, because 'x' in 'f' is spilled to the +// stack, and then loaded back as a fully initialiazed value (due to +// no_sanitize_memory attribute). + +#include <stdlib.h> +#include <stdio.h> + +__attribute__((noinline)) +__attribute__((no_sanitize_memory)) +int f(int x) { + return x; +} + +int main(void) { + int x; + int * volatile p = &x; + int y = f(*p); + // CHECK: WARNING: Use of uninitialized value + // CHECK: {{#0 0x.* in main .*no_sanitize_memory_prop.cc:}}[[@LINE+1]] + if (y) + exit(0); + return 0; +} diff --git a/lib/msan/lit_tests/readdir64.cc b/lib/msan/lit_tests/readdir64.cc new file mode 100644 index 0000000000000..0ec106c741f51 --- /dev/null +++ b/lib/msan/lit_tests/readdir64.cc @@ -0,0 +1,27 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t +// RUN: %clangxx_msan -m64 -O1 %s -o %t && %t +// RUN: %clangxx_msan -m64 -O2 %s -o %t && %t +// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t + +// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %t +// RUN: %clangxx_msan -m64 -O1 -D_FILE_OFFSET_BITS=64 %s -o %t && %t +// RUN: %clangxx_msan -m64 -O2 -D_FILE_OFFSET_BITS=64 %s -o %t && %t +// RUN: %clangxx_msan -m64 -O3 -D_FILE_OFFSET_BITS=64 %s -o %t && %t + +// Test that readdir64 is intercepted as well as readdir. + +#include <sys/types.h> +#include <dirent.h> +#include <stdlib.h> + + +int main(void) { + DIR *dir = opendir("."); + struct dirent *d = readdir(dir); + if (d->d_name[0]) { + closedir(dir); + exit(0); + } + closedir(dir); + return 0; +} diff --git a/lib/msan/lit_tests/stack-origin.cc b/lib/msan/lit_tests/stack-origin.cc new file mode 100644 index 0000000000000..90f5273092242 --- /dev/null +++ b/lib/msan/lit_tests/stack-origin.cc @@ -0,0 +1,32 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out +// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out + +// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out +// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O1 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out +// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out +// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out + +#include <stdlib.h> +int main(int argc, char **argv) { + int x; + int *volatile p = &x; + if (*p) + exit(0); + // CHECK: WARNING: Use of uninitialized value + // CHECK: {{#0 0x.* in main .*stack-origin.cc:}}[[@LINE-3]] + + // CHECK-ORIGINS: Uninitialized value was created by an allocation of 'x' in the stack frame of function 'main' + + // CHECK: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*stack-origin.cc:.* main}} + return 0; +} |