From f0720e6929b7f2d6960a3b762bcba75f32f126e5 Mon Sep 17 00:00:00 2001 From: kamil Date: Sun, 18 Aug 2019 20:15:58 +0000 Subject: [PATCH] Add ATF c and c++ tests for TSan, MSan, libFuzzer These tests require Clang/LLVM 7 or newer on NetBSD. Contributed by Yang Zheng during GSoC 2018. --- distrib/sets/lists/tests/mi | 41 +++- tests/usr.bin/c++/Makefile | 25 +- tests/usr.bin/c++/t_fuzzer_oom.sh | 166 +++++++++++++ tests/usr.bin/c++/t_fuzzer_simple.sh | 182 ++++++++++++++ tests/usr.bin/c++/t_fuzzer_timeout.sh | 162 +++++++++++++ tests/usr.bin/c++/t_msan_allocated_memory.sh | 163 +++++++++++++ tests/usr.bin/c++/t_msan_check_mem.sh | 167 +++++++++++++ tests/usr.bin/c++/t_msan_free.sh | 159 ++++++++++++ tests/usr.bin/c++/t_msan_heap.sh | 139 +++++++++++ tests/usr.bin/c++/t_msan_partial_poison.sh | 171 +++++++++++++ tests/usr.bin/c++/t_msan_poison.sh | 167 +++++++++++++ tests/usr.bin/c++/t_msan_realloc.sh | 163 +++++++++++++ tests/usr.bin/c++/t_msan_shadow.sh | 183 ++++++++++++++ tests/usr.bin/c++/t_msan_stack.sh | 159 ++++++++++++ tests/usr.bin/c++/t_msan_unpoison.sh | 183 ++++++++++++++ tests/usr.bin/c++/t_tsan_data_race.sh | 180 ++++++++++++++ .../usr.bin/c++/t_tsan_heap_use_after_free.sh | 216 +++++++++++++++++ .../c++/t_tsan_lock_order_inversion.sh | 200 +++++++++++++++ .../c++/t_tsan_locked_mutex_destroy.sh | 216 +++++++++++++++++ tests/usr.bin/c++/t_tsan_signal_errno.sh | 204 ++++++++++++++++ tests/usr.bin/c++/t_tsan_thread_leak.sh | 204 ++++++++++++++++ tests/usr.bin/c++/t_tsan_vptr_race.sh | 228 ++++++++++++++++++ tests/usr.bin/cc/Makefile | 24 +- tests/usr.bin/cc/t_fuzzer_oom.sh | 166 +++++++++++++ tests/usr.bin/cc/t_fuzzer_simple.sh | 182 ++++++++++++++ tests/usr.bin/cc/t_fuzzer_timeout.sh | 162 +++++++++++++ tests/usr.bin/cc/t_msan_allocated_memory.sh | 164 +++++++++++++ tests/usr.bin/cc/t_msan_check_mem.sh | 168 +++++++++++++ tests/usr.bin/cc/t_msan_free.sh | 159 ++++++++++++ tests/usr.bin/cc/t_msan_heap.sh | 139 +++++++++++ tests/usr.bin/cc/t_msan_partial_poison.sh | 171 +++++++++++++ tests/usr.bin/cc/t_msan_poison.sh | 167 +++++++++++++ tests/usr.bin/cc/t_msan_realloc.sh | 163 +++++++++++++ tests/usr.bin/cc/t_msan_shadow.sh | 183 ++++++++++++++ tests/usr.bin/cc/t_msan_stack.sh | 159 ++++++++++++ tests/usr.bin/cc/t_msan_unpoison.sh | 183 ++++++++++++++ tests/usr.bin/cc/t_tsan_data_race.sh | 180 ++++++++++++++ .../usr.bin/cc/t_tsan_heap_use_after_free.sh | 216 +++++++++++++++++ .../usr.bin/cc/t_tsan_lock_order_inversion.sh | 200 +++++++++++++++ .../usr.bin/cc/t_tsan_locked_mutex_destroy.sh | 216 +++++++++++++++++ tests/usr.bin/cc/t_tsan_signal_errno.sh | 204 ++++++++++++++++ tests/usr.bin/cc/t_tsan_thread_leak.sh | 204 ++++++++++++++++ 42 files changed, 7085 insertions(+), 3 deletions(-) create mode 100644 tests/usr.bin/c++/t_fuzzer_oom.sh create mode 100644 tests/usr.bin/c++/t_fuzzer_simple.sh create mode 100644 tests/usr.bin/c++/t_fuzzer_timeout.sh create mode 100644 tests/usr.bin/c++/t_msan_allocated_memory.sh create mode 100644 tests/usr.bin/c++/t_msan_check_mem.sh create mode 100644 tests/usr.bin/c++/t_msan_free.sh create mode 100644 tests/usr.bin/c++/t_msan_heap.sh create mode 100644 tests/usr.bin/c++/t_msan_partial_poison.sh create mode 100644 tests/usr.bin/c++/t_msan_poison.sh create mode 100644 tests/usr.bin/c++/t_msan_realloc.sh create mode 100644 tests/usr.bin/c++/t_msan_shadow.sh create mode 100644 tests/usr.bin/c++/t_msan_stack.sh create mode 100644 tests/usr.bin/c++/t_msan_unpoison.sh create mode 100644 tests/usr.bin/c++/t_tsan_data_race.sh create mode 100644 tests/usr.bin/c++/t_tsan_heap_use_after_free.sh create mode 100644 tests/usr.bin/c++/t_tsan_lock_order_inversion.sh create mode 100644 tests/usr.bin/c++/t_tsan_locked_mutex_destroy.sh create mode 100644 tests/usr.bin/c++/t_tsan_signal_errno.sh create mode 100644 tests/usr.bin/c++/t_tsan_thread_leak.sh create mode 100644 tests/usr.bin/c++/t_tsan_vptr_race.sh create mode 100644 tests/usr.bin/cc/t_fuzzer_oom.sh create mode 100644 tests/usr.bin/cc/t_fuzzer_simple.sh create mode 100644 tests/usr.bin/cc/t_fuzzer_timeout.sh create mode 100644 tests/usr.bin/cc/t_msan_allocated_memory.sh create mode 100644 tests/usr.bin/cc/t_msan_check_mem.sh create mode 100644 tests/usr.bin/cc/t_msan_free.sh create mode 100644 tests/usr.bin/cc/t_msan_heap.sh create mode 100644 tests/usr.bin/cc/t_msan_partial_poison.sh create mode 100644 tests/usr.bin/cc/t_msan_poison.sh create mode 100644 tests/usr.bin/cc/t_msan_realloc.sh create mode 100644 tests/usr.bin/cc/t_msan_shadow.sh create mode 100644 tests/usr.bin/cc/t_msan_stack.sh create mode 100644 tests/usr.bin/cc/t_msan_unpoison.sh create mode 100644 tests/usr.bin/cc/t_tsan_data_race.sh create mode 100644 tests/usr.bin/cc/t_tsan_heap_use_after_free.sh create mode 100644 tests/usr.bin/cc/t_tsan_lock_order_inversion.sh create mode 100644 tests/usr.bin/cc/t_tsan_locked_mutex_destroy.sh create mode 100644 tests/usr.bin/cc/t_tsan_signal_errno.sh create mode 100644 tests/usr.bin/cc/t_tsan_thread_leak.sh diff --git a/distrib/sets/lists/tests/mi b/distrib/sets/lists/tests/mi index 31cf6878d6d3..74478437a636 100644 --- a/distrib/sets/lists/tests/mi +++ b/distrib/sets/lists/tests/mi @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.818 2019/07/28 13:49:23 christos Exp $ +# $NetBSD: mi,v 1.819 2019/08/18 20:15:59 kamil Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -3840,6 +3840,26 @@ ./usr/tests/usr.bin/c++/t_ubsan_int_neg_overflow tests-usr.bin-tests compattestfile,atf,cxx ./usr/tests/usr.bin/c++/t_ubsan_int_sub_overflow tests-usr.bin-tests compattestfile,atf,cxx ./usr/tests/usr.bin/c++/t_ubsan_vla_out_of_bounds tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_msan_allocated_memory tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_msan_check_mem tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_msan_free tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_msan_heap tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_msan_partial_poison tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_msan_poison tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_msan_realloc tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_msan_shadow tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_msan_stack tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_msan_unpoison tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_tsan_data_race tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_tsan_heap_use_after_free tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_tsan_lock_order_inversion tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_tsan_locked_mutex_destroy tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_tsan_signal_errno tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_tsan_thread_leak tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_tsan_vptr_race tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_fuzzer_oom tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_fuzzer_simple tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_fuzzer_timeout tests-usr.bin-tests compattestfile,atf,cxx ./usr/tests/usr.bin/cc tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/cc/Atffile tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/cc/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua @@ -3856,6 +3876,25 @@ ./usr/tests/usr.bin/cc/t_ubsan_int_neg_overflow tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/cc/t_ubsan_int_sub_overflow tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/cc/t_ubsan_vla_out_of_bounds tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_msan_allocated_memory tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_msan_check_mem tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_msan_free tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_msan_heap tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_msan_partial_poison tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_msan_poison tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_msan_realloc tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_msan_shadow tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_msan_stack tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_msan_unpoison tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_tsan_data_race tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_tsan_heap_use_after_free tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_tsan_lock_order_inversion tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_tsan_locked_mutex_destroy tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_tsan_signal_errno tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_tsan_thread_leak tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_fuzzer_oom tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_fuzzer_simple tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_fuzzer_timeout tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/cmp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/cmp/Atffile tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/cmp/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua diff --git a/tests/usr.bin/c++/Makefile b/tests/usr.bin/c++/Makefile index da890ecee6fd..98484b00bd25 100644 --- a/tests/usr.bin/c++/Makefile +++ b/tests/usr.bin/c++/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.11 2019/01/29 20:07:03 mgorny Exp $ +# $NetBSD: Makefile,v 1.12 2019/08/18 20:15:58 kamil Exp $ .include @@ -29,6 +29,29 @@ TESTS_SH+= t_hello TESTS_SH+= t_pthread_once TESTS_SH+= t_static_destructor +TESTS_SH+= t_fuzzer_oom +TESTS_SH+= t_fuzzer_simple +TESTS_SH+= t_fuzzer_timeout + +TESTS_SH+= t_msan_allocated_memory +TESTS_SH+= t_msan_check_mem +TESTS_SH+= t_msan_free +TESTS_SH+= t_msan_heap +TESTS_SH+= t_msan_partial_poison +TESTS_SH+= t_msan_poison +TESTS_SH+= t_msan_realloc +TESTS_SH+= t_msan_shadow +TESTS_SH+= t_msan_stack +TESTS_SH+= t_msan_unpoison + +TESTS_SH+= t_tsan_data_race +TESTS_SH+= t_tsan_heap_use_after_free +TESTS_SH+= t_tsan_lock_order_inversion +TESTS_SH+= t_tsan_locked_mutex_destroy +TESTS_SH+= t_tsan_signal_errno +TESTS_SH+= t_tsan_thread_leak +TESTS_SH+= t_tsan_vptr_race + .for test in ${ASAN_TESTS} TESTS_SH_SRC_${test}= asan_common.subr ${test}.sh .endfor diff --git a/tests/usr.bin/c++/t_fuzzer_oom.sh b/tests/usr.bin/c++/t_fuzzer_oom.sh new file mode 100644 index 000000000000..816867aff6cc --- /dev/null +++ b/tests/usr.bin/c++/t_fuzzer_oom.sh @@ -0,0 +1,166 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case oom +oom_head() { + atf_set "descr" "Test thread sanitizer for out-of-memory condition" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case oom_profile +oom_profile_head() { + atf_set "descr" "Test thread sanitizer for out-of-memory with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case oom_pic +oom_pic_head() { + atf_set "descr" "Test thread sanitizer for out-of-memory with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case oom_pie +oom_pie_head() { + atf_set "descr" "Test thread sanitizer for out-of-memory with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +oom_body(){ + cat > test.cc << EOF +#include +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) malloc(16*1024*1024); + return 0; +} +EOF + + c++ -fsanitize=fuzzer -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: out-of-memory" ./test -rss_limit_mb=30 +} + +oom_profile_body(){ + cat > test.cc << EOF +#include +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) malloc(16*1024*1024); + return 0; +} +EOF + + c++ -fsanitize=fuzzer -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: out-of-memory" ./test -rss_limit_mb=30 +} + +oom_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(const uint8_t *data, size_t size); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + return help(data, size); +} +EOF + + cat > pic.cc << EOF +#include +#include +#include + +int help(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) malloc(16*1024*1024); + return 0; +} +EOF + + c++ -fsanitize=fuzzer -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=fuzzer -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: out-of-memory" ./test -rss_limit_mb=30 +} +oom_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) malloc(16*1024*1024); + return 0; +} +EOF + + c++ -fsanitize=fuzzer -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: out-of-memory" ./test -rss_limit_mb=30 +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case oom + atf_add_test_case oom_profile + atf_add_test_case oom_pie + atf_add_test_case oom_pic +} diff --git a/tests/usr.bin/c++/t_fuzzer_simple.sh b/tests/usr.bin/c++/t_fuzzer_simple.sh new file mode 100644 index 000000000000..f4791915d189 --- /dev/null +++ b/tests/usr.bin/c++/t_fuzzer_simple.sh @@ -0,0 +1,182 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case simple +simple_head() { + atf_set "descr" "Test thread sanitizer for error exit condition" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case simple_profile +simple_profile_head() { + atf_set "descr" "Test thread sanitizer for simple with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case simple_pic +simple_pic_head() { + atf_set "descr" "Test thread sanitizer for simple with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case simple_pie +simple_pie_head() { + atf_set "descr" "Test thread sanitizer for simple with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +simple_body(){ + cat > test.cc << EOF +#include +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') { + fprintf(stderr, "BINGO\n"); + exit(1); + } + + return 0; +} +EOF + + c++ -fsanitize=fuzzer -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"BINGO" ./test +} + +simple_profile_body(){ + cat > test.cc << EOF +#include +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') { + fprintf(stderr, "BINGO\n"); + exit(1); + } + + return 0; +} +EOF + + c++ -fsanitize=fuzzer -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"BINGO" ./test +} + +simple_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(const uint8_t *data, size_t size); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + return help(data, size); +} +EOF + + cat > pic.cc << EOF +#include +#include +#include + +int help(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') { + fprintf(stderr, "BINGO\n"); + exit(1); + } + + return 0; +} +EOF + + c++ -fsanitize=fuzzer -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=fuzzer -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"BINGO" ./test +} +simple_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') { + fprintf(stderr, "BINGO\n"); + exit(1); + } + + return 0; +} +EOF + + c++ -fsanitize=fuzzer -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"BINGO" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case simple + atf_add_test_case simple_profile + atf_add_test_case simple_pie + atf_add_test_case simple_pic +} diff --git a/tests/usr.bin/c++/t_fuzzer_timeout.sh b/tests/usr.bin/c++/t_fuzzer_timeout.sh new file mode 100644 index 000000000000..3a34f2dedcc2 --- /dev/null +++ b/tests/usr.bin/c++/t_fuzzer_timeout.sh @@ -0,0 +1,162 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case timeout +timeout_head() { + atf_set "descr" "Test thread sanitizer for timeout condition" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case timeout_profile +timeout_profile_head() { + atf_set "descr" "Test thread sanitizer for timeout with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case timeout_pic +timeout_pic_head() { + atf_set "descr" "Test thread sanitizer for timeout with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case timeout_pie +timeout_pie_head() { + atf_set "descr" "Test thread sanitizer for timeout with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +timeout_body(){ + cat > test.cc << EOF +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) ; + return 0; +} +EOF + + c++ -fsanitize=fuzzer -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: timeout" ./test -timeout=5 +} + +timeout_profile_body(){ + cat > test.cc << EOF +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) ; + return 0; +} +EOF + + c++ -fsanitize=fuzzer -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: timeout" ./test -timeout=5 +} + +timeout_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(const uint8_t *data, size_t size); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + return help(data, size); +} +EOF + + cat > pic.cc << EOF +#include +#include + +int help(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) ; + return 0; +} +EOF + + c++ -fsanitize=fuzzer -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=fuzzer -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: timeout" ./test -timeout=5 +} +timeout_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) ; + return 0; +} +EOF + + c++ -fsanitize=fuzzer -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: timeout" ./test -timeout=5 +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case timeout + atf_add_test_case timeout_profile + atf_add_test_case timeout_pie + atf_add_test_case timeout_pic +} diff --git a/tests/usr.bin/c++/t_msan_allocated_memory.sh b/tests/usr.bin/c++/t_msan_allocated_memory.sh new file mode 100644 index 000000000000..2b391e0f6cfe --- /dev/null +++ b/tests/usr.bin/c++/t_msan_allocated_memory.sh @@ -0,0 +1,163 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case allocated_memory +allocated_memory_head() { + atf_set "descr" "Test memory sanitizer for __msan_allocated_memory interface" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case allocated_memory_profile +allocated_memory_profile_head() { + atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case allocated_memory_pic +allocated_memory_pic_head() { + atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case allocated_memory_pie +allocated_memory_pie_head() { + atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +allocated_memory_body(){ + cat > test.cc << EOF +#include +#include + +int main() { + int x = 0; + __msan_allocated_memory(&x, sizeof(x)); + return x; +} +EOF + + c++ -fsanitize=memory -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +allocated_memory_profile_body(){ + cat > test.cc << EOF +#include +#include + +int main() { + int x = 0; + __msan_allocated_memory(&x, sizeof(x)); + return x; +} +EOF + + c++ -fsanitize=memory -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +allocated_memory_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +#include + +int help(int argc) { + int x = 0; + __msan_allocated_memory(&x, sizeof(x)); + return x; +} +EOF + + c++ -fsanitize=memory -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} +allocated_memory_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include + +int main() { + int x = 0; + __msan_allocated_memory(&x, sizeof(x)); + return x; +} +EOF + + c++ -fsanitize=memory -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case allocated_memory + atf_add_test_case allocated_memory_profile + atf_add_test_case allocated_memory_pie + atf_add_test_case allocated_memory_pic +} diff --git a/tests/usr.bin/c++/t_msan_check_mem.sh b/tests/usr.bin/c++/t_msan_check_mem.sh new file mode 100644 index 000000000000..d529c76ef88e --- /dev/null +++ b/tests/usr.bin/c++/t_msan_check_mem.sh @@ -0,0 +1,167 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case check_mem +check_mem_head() { + atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized interface" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case check_mem_profile +check_mem_profile_head() { + atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case check_mem_pic +check_mem_pic_head() { + atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case check_mem_pie +check_mem_pie_head() { + atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +check_mem_body(){ + cat > test.cc << EOF +#include +#include + +int main(int argc, char **argv) { + int *volatile p = (int *)malloc(sizeof(int)); + + __msan_check_mem_is_initialized(p, sizeof(*p)); + return 0; +} +EOF + + c++ -fsanitize=memory -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 0 inside" ./test +} + +check_mem_profile_body(){ + cat > test.cc << EOF +#include +#include + +int main(int argc, char **argv) { + int *volatile p = (int *)malloc(sizeof(int)); + + __msan_check_mem_is_initialized(p, sizeof(*p)); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 0 inside" ./test +} + +check_mem_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +#include + +int help(int argc) { + int *volatile p = (int *)malloc(sizeof(int)); + + __msan_check_mem_is_initialized(p, sizeof(*p)); + return 0; +} +EOF + + c++ -fsanitize=memory -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 0 inside" ./test +} +check_mem_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include + +int main(int argc, char **argv) { + int *volatile p = (int *)malloc(sizeof(int)); + + __msan_check_mem_is_initialized(p, sizeof(*p)); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 0 inside" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case check_mem + atf_add_test_case check_mem_profile + atf_add_test_case check_mem_pie + atf_add_test_case check_mem_pic +} diff --git a/tests/usr.bin/c++/t_msan_free.sh b/tests/usr.bin/c++/t_msan_free.sh new file mode 100644 index 000000000000..4bb66c43f5b9 --- /dev/null +++ b/tests/usr.bin/c++/t_msan_free.sh @@ -0,0 +1,159 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case free +free_head() { + atf_set "descr" "Test memory sanitizer for use-after-free case" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case free_profile +free_profile_head() { + atf_set "descr" "Test memory sanitizer for use-after-free with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case free_pic +free_pic_head() { + atf_set "descr" "Test memory sanitizer for use-after-free with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case free_pie +free_pie_head() { + atf_set "descr" "Test memory sanitizer for use-after-free with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +free_body(){ + cat > test.cc << EOF +#include +int main() { + int *a = (int *)malloc(sizeof(int)); + *a = 9; + free(a); + return *a; +} +EOF + + c++ -fsanitize=memory -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +free_profile_body(){ + cat > test.cc << EOF +#include +int main() { + int *a = (int *)malloc(sizeof(int)); + *a = 9; + free(a); + return *a; +} +EOF + + c++ -fsanitize=memory -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +free_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +int help(int argc) { + int *a = (int *)malloc(sizeof(int)); + *a = 9; + free(a); + return *a; +} +EOF + + c++ -fsanitize=memory -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} +free_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +int main() { + int *a = (int *)malloc(sizeof(int)); + *a = 9; + free(a); + return *a; +} +EOF + + c++ -fsanitize=memory -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case free + atf_add_test_case free_profile + atf_add_test_case free_pie + atf_add_test_case free_pic +} diff --git a/tests/usr.bin/c++/t_msan_heap.sh b/tests/usr.bin/c++/t_msan_heap.sh new file mode 100644 index 000000000000..4fed5cb044b3 --- /dev/null +++ b/tests/usr.bin/c++/t_msan_heap.sh @@ -0,0 +1,139 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case heap +heap_head() { + atf_set "descr" "Test memory sanitizer for uninitialized heap value case" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case heap_profile +heap_profile_head() { + atf_set "descr" "Test memory sanitizer for uninitialized heap value with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case heap_pic +heap_pic_head() { + atf_set "descr" "Test memory sanitizer for uninitialized heap value with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case heap_pie +heap_pie_head() { + atf_set "descr" "Test memory sanitizer for uninitialized heap value with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +heap_body(){ + cat > test.cc << EOF +#include +int main() { int *a = (int *)malloc(sizeof(int)); return *a; } +EOF + + c++ -fsanitize=memory -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +heap_profile_body(){ + cat > test.cc << EOF +#include +int main() { int *a = (int *)malloc(sizeof(int)); return *a; } +EOF + + c++ -fsanitize=memory -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +heap_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +int help(int argc) { int *a = (int *)malloc(sizeof(int)); return *a; } +EOF + + c++ -fsanitize=memory -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} +heap_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +int main() { int *a = (int *)malloc(sizeof(int)); return *a; } +EOF + + c++ -fsanitize=memory -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case heap + atf_add_test_case heap_profile + atf_add_test_case heap_pie + atf_add_test_case heap_pic +} diff --git a/tests/usr.bin/c++/t_msan_partial_poison.sh b/tests/usr.bin/c++/t_msan_partial_poison.sh new file mode 100644 index 000000000000..32749ccf6f26 --- /dev/null +++ b/tests/usr.bin/c++/t_msan_partial_poison.sh @@ -0,0 +1,171 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case partial_poison +partial_poison_head() { + atf_set "descr" "Test memory sanitizer for __msan_partial_poison interface" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case partial_poison_profile +partial_poison_profile_head() { + atf_set "descr" "Test memory sanitizer for __msan_partial_poison with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case partial_poison_pic +partial_poison_pic_head() { + atf_set "descr" "Test memory sanitizer for __msan_partial_poison with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case partial_poison_pie +partial_poison_pie_head() { + atf_set "descr" "Test memory sanitizer for __msan_partial_poison with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +partial_poison_body(){ + cat > test.cc << EOF +#include +#include + +int main(void) { + char x[4]; + char x_s[4] = {0x77, 0x65, 0x43, 0x21}; + __msan_partial_poison(&x, &x_s, sizeof(x_s)); + __msan_print_shadow(&x, sizeof(x_s)); + return 0; +} +EOF + + c++ -fsanitize=memory -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:": 77654321" ./test +} + +partial_poison_profile_body(){ + cat > test.cc << EOF +#include +#include + +int main(void) { + char x[4]; + char x_s[4] = {0x77, 0x65, 0x43, 0x21}; + __msan_partial_poison(&x, &x_s, sizeof(x_s)); + __msan_print_shadow(&x, sizeof(x_s)); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:": 77654321" ./test +} + +partial_poison_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +#include + +int help(int argc) { + char x[4]; + char x_s[4] = {0x77, 0x65, 0x43, 0x21}; + __msan_partial_poison(&x, &x_s, sizeof(x_s)); + __msan_print_shadow(&x, sizeof(x_s)); + return 0; +} +EOF + + c++ -fsanitize=memory -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:": 77654321" ./test +} +partial_poison_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include + +int main(void) { + char x[4]; + char x_s[4] = {0x77, 0x65, 0x43, 0x21}; + __msan_partial_poison(&x, &x_s, sizeof(x_s)); + __msan_print_shadow(&x, sizeof(x_s)); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:": 77654321" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case partial_poison + atf_add_test_case partial_poison_profile + atf_add_test_case partial_poison_pie + atf_add_test_case partial_poison_pic +} diff --git a/tests/usr.bin/c++/t_msan_poison.sh b/tests/usr.bin/c++/t_msan_poison.sh new file mode 100644 index 000000000000..418bd871617a --- /dev/null +++ b/tests/usr.bin/c++/t_msan_poison.sh @@ -0,0 +1,167 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case poison +poison_head() { + atf_set "descr" "Test memory sanitizer for __msan_poison interface" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case poison_profile +poison_profile_head() { + atf_set "descr" "Test memory sanitizer for __msan_poison with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case poison_pic +poison_pic_head() { + atf_set "descr" "Test memory sanitizer for __msan_poison with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case poison_pie +poison_pie_head() { + atf_set "descr" "Test memory sanitizer for __msan_poison with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +poison_body(){ + cat > test.cc << EOF +#include + +int main(void) { + char p[32] = {}; + __msan_poison(p + 10, 2); + + __msan_check_mem_is_initialized(p + 5, 20); + return 0; +} +EOF + + c++ -fsanitize=memory -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 5 inside" ./test +} + +poison_profile_body(){ + cat > test.cc << EOF +#include + +int main(void) { + char p[32] = {}; + __msan_poison(p + 10, 2); + + __msan_check_mem_is_initialized(p + 5, 20); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 5 inside" ./test +} + +poison_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include + +int help(int argc) { + char p[32] = {}; + __msan_poison(p + 10, 2); + + __msan_check_mem_is_initialized(p + 5, 20); + return 0; +} +EOF + + c++ -fsanitize=memory -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 5 inside" ./test +} +poison_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include + +int main(void) { + char p[32] = {}; + __msan_poison(p + 10, 2); + + __msan_check_mem_is_initialized(p + 5, 20); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 5 inside" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case poison + atf_add_test_case poison_profile + atf_add_test_case poison_pie + atf_add_test_case poison_pic +} diff --git a/tests/usr.bin/c++/t_msan_realloc.sh b/tests/usr.bin/c++/t_msan_realloc.sh new file mode 100644 index 000000000000..104c22512364 --- /dev/null +++ b/tests/usr.bin/c++/t_msan_realloc.sh @@ -0,0 +1,163 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case realloc +realloc_head() { + atf_set "descr" "Test memory sanitizer for realloc" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case realloc_profile +realloc_profile_head() { + atf_set "descr" "Test memory sanitizer for realloc with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case realloc_pic +realloc_pic_head() { + atf_set "descr" "Test memory sanitizer for realloc with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case realloc_pie +realloc_pie_head() { + atf_set "descr" "Test memory sanitizer for realloc with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +realloc_body(){ + cat > test.cc << EOF +#include +int main(int argc, char **argv) { + char *p = (char *)malloc(100); + p = (char *)realloc(p, 10000); + char x = p[50]; + free(p); + return x; +} +EOF + + c++ -fsanitize=memory -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +realloc_profile_body(){ + cat > test.cc << EOF +#include +int main(int argc, char **argv) { + char *p = (char *)malloc(100); + p = (char *)realloc(p, 10000); + char x = p[50]; + free(p); + return x; +} +EOF + + c++ -fsanitize=memory -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +realloc_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +int help(int argc) { + char *p = (char *)malloc(100); + p = (char *)realloc(p, 10000); + char x = p[50]; + free(p); + return x; +} +EOF + + c++ -fsanitize=memory -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} +realloc_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +int main(int argc, char **argv) { + char *p = (char *)malloc(100); + p = (char *)realloc(p, 10000); + char x = p[50]; + free(p); + return x; +} +EOF + + c++ -fsanitize=memory -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case realloc + atf_add_test_case realloc_profile + atf_add_test_case realloc_pie + atf_add_test_case realloc_pic +} diff --git a/tests/usr.bin/c++/t_msan_shadow.sh b/tests/usr.bin/c++/t_msan_shadow.sh new file mode 100644 index 000000000000..c4ba355e4f32 --- /dev/null +++ b/tests/usr.bin/c++/t_msan_shadow.sh @@ -0,0 +1,183 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case shadow +shadow_head() { + atf_set "descr" "Test memory sanitizer for shadow interface" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case shadow_profile +shadow_profile_head() { + atf_set "descr" "Test memory sanitizer for shadow with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case shadow_pic +shadow_pic_head() { + atf_set "descr" "Test memory sanitizer for shadow with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case shadow_pie +shadow_pie_head() { + atf_set "descr" "Test memory sanitizer for shadow with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +shadow_body(){ + cat > test.cc << EOF +#include +#include +#include + +int main(int argc, char **argv) { + char str[] = "abc"; + char str2[] = "cdefghi"; + __msan_poison(str + 2, 1); + __msan_copy_shadow(str2 + 2, str, 4); + printf("%ld\n", __msan_test_shadow(str, 4)); + __msan_print_shadow(str2, 8); + return 0; +} +EOF + + c++ -fsanitize=memory -o test test.cc + paxctl +a test + atf_check -s ignore -o match:"2" -e match:"00000000 ff000000" ./test +} + +shadow_profile_body(){ + cat > test.cc << EOF +#include +#include +#include + +int main(int argc, char **argv) { + char str[] = "abc"; + char str2[] = "cdefghi"; + __msan_poison(str + 2, 1); + __msan_copy_shadow(str2 + 2, str, 4); + printf("%ld\n", __msan_test_shadow(str, 4)); + __msan_print_shadow(str2, 8); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o match:"2" -e match:"00000000 ff000000" ./test +} + +shadow_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +#include +#include + +int help(int argc) { + char str[] = "abc"; + char str2[] = "cdefghi"; + __msan_poison(str + 2, 1); + __msan_copy_shadow(str2 + 2, str, 4); + printf("%ld\n", __msan_test_shadow(str, 4)); + __msan_print_shadow(str2, 8); + return 0; +} +EOF + + c++ -fsanitize=memory -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o match:"2" -e match:"00000000 ff000000" ./test +} +shadow_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include +#include + +int main(int argc, char **argv) { + char str[] = "abc"; + char str2[] = "cdefghi"; + __msan_poison(str + 2, 1); + __msan_copy_shadow(str2 + 2, str, 4); + printf("%ld\n", __msan_test_shadow(str, 4)); + __msan_print_shadow(str2, 8); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o match:"2" -e match:"00000000 ff000000" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case shadow + atf_add_test_case shadow_profile + atf_add_test_case shadow_pie + atf_add_test_case shadow_pic +} diff --git a/tests/usr.bin/c++/t_msan_stack.sh b/tests/usr.bin/c++/t_msan_stack.sh new file mode 100644 index 000000000000..049dc55ca902 --- /dev/null +++ b/tests/usr.bin/c++/t_msan_stack.sh @@ -0,0 +1,159 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case stack +stack_head() { + atf_set "descr" "Test memory sanitizer for free-stack-pointer case" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case stack_profile +stack_profile_head() { + atf_set "descr" "Test memory sanitizer for free-stack-pointer with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case stack_pic +stack_pic_head() { + atf_set "descr" "Test memory sanitizer for free-stack-pointer with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case stack_pie +stack_pie_head() { + atf_set "descr" "Test memory sanitizer for free-stack-pointer with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +stack_body(){ + cat > test.cc << EOF +#include +int main() { + int a = 0; + int *p = &a; + free(p); + return 0; +} +EOF + + c++ -fsanitize=memory -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"MemorySanitizer: bad pointer" ./test +} + +stack_profile_body(){ + cat > test.cc << EOF +#include +int main() { + int a = 0; + int *p = &a; + free(p); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"MemorySanitizer: bad pointer" ./test +} + +stack_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +int help(int argc) { + int a = 0; + int *p = &a; + free(p); + return 0; +} +EOF + + c++ -fsanitize=memory -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"MemorySanitizer: bad pointer" ./test +} +stack_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +int main() { + int a = 0; + int *p = &a; + free(p); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"MemorySanitizer: bad pointer" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case stack + atf_add_test_case stack_profile + atf_add_test_case stack_pie + atf_add_test_case stack_pic +} diff --git a/tests/usr.bin/c++/t_msan_unpoison.sh b/tests/usr.bin/c++/t_msan_unpoison.sh new file mode 100644 index 000000000000..e4ed141e2b7d --- /dev/null +++ b/tests/usr.bin/c++/t_msan_unpoison.sh @@ -0,0 +1,183 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case unpoison +unpoison_head() { + atf_set "descr" "Test memory sanitizer for __msan_unpoison interface" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case unpoison_profile +unpoison_profile_head() { + atf_set "descr" "Test memory sanitizer for __msan_unpoison with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case unpoison_pic +unpoison_pic_head() { + atf_set "descr" "Test memory sanitizer for __msan_unpoison with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case unpoison_pie +unpoison_pie_head() { + atf_set "descr" "Test memory sanitizer for __msan_unpoison with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +unpoison_body(){ + cat > test.cc << EOF +#include + +int main(void) { + char p[32] = {}; + char q[32] = {}; + __msan_poison(p + 10, 2); + __msan_poison(q, 32); + __msan_unpoison(p + 10, 2); + __msan_unpoison_string(q); + __msan_check_mem_is_initialized(p, 32); + __msan_check_mem_is_initialized(p, 32); + return 0; +} +EOF + + c++ -fsanitize=memory -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e not-match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +unpoison_profile_body(){ + cat > test.cc << EOF +#include + +int main(void) { + char p[32] = {}; + char q[32] = {}; + __msan_poison(p + 10, 2); + __msan_poison(q, 32); + __msan_unpoison(p + 10, 2); + __msan_unpoison_string(q); + __msan_check_mem_is_initialized(p, 32); + __msan_check_mem_is_initialized(p, 32); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e not-match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +unpoison_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include + +int help(int argc) { + char p[32] = {}; + char q[32] = {}; + __msan_poison(p + 10, 2); + __msan_poison(q, 32); + __msan_unpoison(p + 10, 2); + __msan_unpoison_string(q); + __msan_check_mem_is_initialized(p, 32); + __msan_check_mem_is_initialized(p, 32); + return 0; +} +EOF + + c++ -fsanitize=memory -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e not-match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} +unpoison_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include + +int main(void) { + char p[32] = {}; + char q[32] = {}; + __msan_poison(p + 10, 2); + __msan_poison(q, 32); + __msan_unpoison(p + 10, 2); + __msan_unpoison_string(q); + __msan_check_mem_is_initialized(p, 32); + __msan_check_mem_is_initialized(p, 32); + return 0; +} +EOF + + c++ -fsanitize=memory -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e not-match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case unpoison + atf_add_test_case unpoison_profile + atf_add_test_case unpoison_pie + atf_add_test_case unpoison_pic +} diff --git a/tests/usr.bin/c++/t_tsan_data_race.sh b/tests/usr.bin/c++/t_tsan_data_race.sh new file mode 100644 index 000000000000..9f43fddb7eef --- /dev/null +++ b/tests/usr.bin/c++/t_tsan_data_race.sh @@ -0,0 +1,180 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case data_race +data_race_head() { + atf_set "descr" "Test thread sanitizer for data race condition" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case data_race_profile +data_race_profile_head() { + atf_set "descr" "Test thread sanitizer for data race with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case data_race_pic +data_race_pic_head() { + atf_set "descr" "Test thread sanitizer for data race with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case data_race_pie +data_race_pie_head() { + atf_set "descr" "Test thread sanitizer for data race with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +data_race_body(){ + cat > test.cc << EOF +#include +int GlobalData; pthread_barrier_t barrier; +void *Thread(void *a) { pthread_barrier_wait(&barrier); GlobalData = 42; return 0; } +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + GlobalData = 43; + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race " ./test +} + +data_race_profile_body(){ + cat > test.cc << EOF +#include +int GlobalData; pthread_barrier_t barrier; +void *Thread(void *a) { pthread_barrier_wait(&barrier); GlobalData = 42; return 0; } +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + GlobalData = 43; + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race " ./test +} + +data_race_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +int GlobalData; pthread_barrier_t barrier; +void *Thread(void *a) { pthread_barrier_wait(&barrier); GlobalData = 42; return 0; } +int help(int argc) { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + GlobalData = 43; + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race " ./test +} +data_race_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +int GlobalData; pthread_barrier_t barrier; +void *Thread(void *a) { pthread_barrier_wait(&barrier); GlobalData = 42; return 0; } +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + GlobalData = 43; + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race " ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case data_race + atf_add_test_case data_race_profile + atf_add_test_case data_race_pie + atf_add_test_case data_race_pic +} diff --git a/tests/usr.bin/c++/t_tsan_heap_use_after_free.sh b/tests/usr.bin/c++/t_tsan_heap_use_after_free.sh new file mode 100644 index 000000000000..d2ad6629aef9 --- /dev/null +++ b/tests/usr.bin/c++/t_tsan_heap_use_after_free.sh @@ -0,0 +1,216 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case heap_use_after_free +heap_use_after_free_head() { + atf_set "descr" "Test thread sanitizer for use-after-free condition" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case heap_use_after_free_profile +heap_use_after_free_profile_head() { + atf_set "descr" "Test thread sanitizer for use-after-free with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case heap_use_after_free_pic +heap_use_after_free_pic_head() { + atf_set "descr" "Test thread sanitizer for use-after-free with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case heap_use_after_free_pie +heap_use_after_free_pie_head() { + atf_set "descr" "Test thread sanitizer for use-after-free with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +heap_use_after_free_body(){ + cat > test.cc << EOF +#include +#include + +int *ptr; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + *ptr = 42; + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + ptr = (int *)malloc(sizeof(int)); + pthread_create(&t, NULL, Thread, NULL); + free(ptr); + pthread_barrier_wait(&barrier); + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: heap-use-after-free" ./test +} + +heap_use_after_free_profile_body(){ + cat > test.cc << EOF +#include +#include + +int *ptr; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + *ptr = 42; + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + ptr = (int *)malloc(sizeof(int)); + pthread_create(&t, NULL, Thread, NULL); + free(ptr); + pthread_barrier_wait(&barrier); + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: heap-use-after-free" ./test +} + +heap_use_after_free_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +#include + +int *ptr; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + *ptr = 42; + return 0; +} + +int help(int argc) { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + ptr = (int *)malloc(sizeof(int)); + pthread_create(&t, NULL, Thread, NULL); + free(ptr); + pthread_barrier_wait(&barrier); + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: heap-use-after-free" ./test +} +heap_use_after_free_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include + +int *ptr; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + *ptr = 42; + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + ptr = (int *)malloc(sizeof(int)); + pthread_create(&t, NULL, Thread, NULL); + free(ptr); + pthread_barrier_wait(&barrier); + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: heap-use-after-free" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case heap_use_after_free + atf_add_test_case heap_use_after_free_profile + atf_add_test_case heap_use_after_free_pie + atf_add_test_case heap_use_after_free_pic +} diff --git a/tests/usr.bin/c++/t_tsan_lock_order_inversion.sh b/tests/usr.bin/c++/t_tsan_lock_order_inversion.sh new file mode 100644 index 000000000000..1f2f1e0a7478 --- /dev/null +++ b/tests/usr.bin/c++/t_tsan_lock_order_inversion.sh @@ -0,0 +1,200 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case lock_order_inversion +lock_order_inversion_head() { + atf_set "descr" "Test thread sanitizer for lock order inversion condition" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case lock_order_inversion_profile +lock_order_inversion_profile_head() { + atf_set "descr" "Test thread sanitizer for lock order inversion with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case lock_order_inversion_pic +lock_order_inversion_pic_head() { + atf_set "descr" "Test thread sanitizer for lock order inversion with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case lock_order_inversion_pie +lock_order_inversion_pie_head() { + atf_set "descr" "Test thread sanitizer for lock order inversion with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +lock_order_inversion_body(){ + cat > test.cc << EOF +#include + +pthread_mutex_t l1, l2; +int main() { + pthread_mutex_init(&l1, NULL); + pthread_mutex_init(&l2, NULL); + pthread_mutex_lock(&l2); + pthread_mutex_lock(&l1); + pthread_mutex_unlock(&l1); + pthread_mutex_unlock(&l2); + + pthread_mutex_lock(&l1); + pthread_mutex_lock(&l2); + pthread_mutex_unlock(&l2); + pthread_mutex_unlock(&l1); + return 0; +} +EOF + + c++ -fsanitize=thread -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: lock-order-inversion" ./test +} + +lock_order_inversion_profile_body(){ + cat > test.cc << EOF +#include + +pthread_mutex_t l1, l2; +int main() { + pthread_mutex_init(&l1, NULL); + pthread_mutex_init(&l2, NULL); + pthread_mutex_lock(&l2); + pthread_mutex_lock(&l1); + pthread_mutex_unlock(&l1); + pthread_mutex_unlock(&l2); + + pthread_mutex_lock(&l1); + pthread_mutex_lock(&l2); + pthread_mutex_unlock(&l2); + pthread_mutex_unlock(&l1); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: lock-order-inversion" ./test +} + +lock_order_inversion_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include + +pthread_mutex_t l1, l2; +int help(int argc) { + pthread_mutex_init(&l1, NULL); + pthread_mutex_init(&l2, NULL); + pthread_mutex_lock(&l2); + pthread_mutex_lock(&l1); + pthread_mutex_unlock(&l1); + pthread_mutex_unlock(&l2); + + pthread_mutex_lock(&l1); + pthread_mutex_lock(&l2); + pthread_mutex_unlock(&l2); + pthread_mutex_unlock(&l1); + return 0; +} +EOF + + c++ -fsanitize=thread -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: lock-order-inversion" ./test +} +lock_order_inversion_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include + +pthread_mutex_t l1, l2; +int main() { + pthread_mutex_init(&l1, NULL); + pthread_mutex_init(&l2, NULL); + pthread_mutex_lock(&l2); + pthread_mutex_lock(&l1); + pthread_mutex_unlock(&l1); + pthread_mutex_unlock(&l2); + + pthread_mutex_lock(&l1); + pthread_mutex_lock(&l2); + pthread_mutex_unlock(&l2); + pthread_mutex_unlock(&l1); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: lock-order-inversion" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case lock_order_inversion + atf_add_test_case lock_order_inversion_profile + atf_add_test_case lock_order_inversion_pie + atf_add_test_case lock_order_inversion_pic +} diff --git a/tests/usr.bin/c++/t_tsan_locked_mutex_destroy.sh b/tests/usr.bin/c++/t_tsan_locked_mutex_destroy.sh new file mode 100644 index 000000000000..fa115294cc66 --- /dev/null +++ b/tests/usr.bin/c++/t_tsan_locked_mutex_destroy.sh @@ -0,0 +1,216 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case locked_mutex_destroy +locked_mutex_destroy_head() { + atf_set "descr" "Test thread sanitizer for destroying locked mutex condition" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case locked_mutex_destroy_profile +locked_mutex_destroy_profile_head() { + atf_set "descr" "Test thread sanitizer for destroying locked mutex with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case locked_mutex_destroy_pic +locked_mutex_destroy_pic_head() { + atf_set "descr" "Test thread sanitizer for destroying locked mutex with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case locked_mutex_destroy_pie +locked_mutex_destroy_pie_head() { + atf_set "descr" "Test thread sanitizer for destroying locked mutex with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +locked_mutex_destroy_body(){ + cat > test.cc << EOF +#include +#include + +pthread_mutex_t mutex; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_mutex_lock(&mutex); + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_mutex_init(&mutex, NULL); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + pthread_mutex_destroy(&mutex); + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test +} + +locked_mutex_destroy_profile_body(){ + cat > test.cc << EOF +#include +#include + +pthread_mutex_t mutex; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_mutex_lock(&mutex); + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_mutex_init(&mutex, NULL); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + pthread_mutex_destroy(&mutex); + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test +} + +locked_mutex_destroy_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +#include + +pthread_mutex_t mutex; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_mutex_lock(&mutex); + pthread_barrier_wait(&barrier); + return 0; +} + +int help(int argc) { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_mutex_init(&mutex, NULL); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + pthread_mutex_destroy(&mutex); + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test +} +locked_mutex_destroy_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include + +pthread_mutex_t mutex; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_mutex_lock(&mutex); + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_mutex_init(&mutex, NULL); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + pthread_mutex_destroy(&mutex); + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case locked_mutex_destroy + atf_add_test_case locked_mutex_destroy_profile + atf_add_test_case locked_mutex_destroy_pie + atf_add_test_case locked_mutex_destroy_pic +} diff --git a/tests/usr.bin/c++/t_tsan_signal_errno.sh b/tests/usr.bin/c++/t_tsan_signal_errno.sh new file mode 100644 index 000000000000..ffd3fe064979 --- /dev/null +++ b/tests/usr.bin/c++/t_tsan_signal_errno.sh @@ -0,0 +1,204 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case signal_errno +signal_errno_head() { + atf_set "descr" "Test thread sanitizer for errno modification in signal condition" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case signal_errno_profile +signal_errno_profile_head() { + atf_set "descr" "Test thread sanitizer for errno modification in signal with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case signal_errno_pic +signal_errno_pic_head() { + atf_set "descr" "Test thread sanitizer for errno modification in signal with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case signal_errno_pie +signal_errno_pie_head() { + atf_set "descr" "Test thread sanitizer for errno modification in signal with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +signal_errno_body(){ + cat > test.cc << EOF +#include +#include +#include +#include + +pthread_t mainth; +static void MyHandler(int a, siginfo_t *s, void *c) { errno = 1; } +static void* sendsignal(void *p) { pthread_kill(mainth, SIGPROF); return NULL; } +int main() { + mainth = pthread_self(); + struct sigaction act = {}; + act.sa_sigaction = &MyHandler; + sigaction(SIGPROF, &act, 0); + pthread_t th; + pthread_create(&th, 0, sendsignal, 0); + pthread_join(th, 0); + return 0; +} +EOF + + c++ -fsanitize=thread -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: signal handler spoils errno" ./test +} + +signal_errno_profile_body(){ + cat > test.cc << EOF +#include +#include +#include +#include + +pthread_t mainth; +static void MyHandler(int a, siginfo_t *s, void *c) { errno = 1; } +static void* sendsignal(void *p) { pthread_kill(mainth, SIGPROF); return NULL; } +int main() { + mainth = pthread_self(); + struct sigaction act = {}; + act.sa_sigaction = &MyHandler; + sigaction(SIGPROF, &act, 0); + pthread_t th; + pthread_create(&th, 0, sendsignal, 0); + pthread_join(th, 0); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: signal handler spoils errno" ./test +} + +signal_errno_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +#include +#include +#include + +pthread_t mainth; +static void MyHandler(int a, siginfo_t *s, void *c) { errno = 1; } +static void* sendsignal(void *p) { pthread_kill(mainth, SIGPROF); return NULL; } +int help(int argc) { + mainth = pthread_self(); + struct sigaction act = {}; + act.sa_sigaction = &MyHandler; + sigaction(SIGPROF, &act, 0); + pthread_t th; + pthread_create(&th, 0, sendsignal, 0); + pthread_join(th, 0); + return 0; +} +EOF + + c++ -fsanitize=thread -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: signal handler spoils errno" ./test +} +signal_errno_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include +#include +#include + +pthread_t mainth; +static void MyHandler(int a, siginfo_t *s, void *c) { errno = 1; } +static void* sendsignal(void *p) { pthread_kill(mainth, SIGPROF); return NULL; } +int main() { + mainth = pthread_self(); + struct sigaction act = {}; + act.sa_sigaction = &MyHandler; + sigaction(SIGPROF, &act, 0); + pthread_t th; + pthread_create(&th, 0, sendsignal, 0); + pthread_join(th, 0); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: signal handler spoils errno" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case signal_errno + atf_add_test_case signal_errno_profile + atf_add_test_case signal_errno_pie + atf_add_test_case signal_errno_pic +} diff --git a/tests/usr.bin/c++/t_tsan_thread_leak.sh b/tests/usr.bin/c++/t_tsan_thread_leak.sh new file mode 100644 index 000000000000..584f129b34e5 --- /dev/null +++ b/tests/usr.bin/c++/t_tsan_thread_leak.sh @@ -0,0 +1,204 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case thread_leak +thread_leak_head() { + atf_set "descr" "Test thread sanitizer for thread leak condition" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case thread_leak_profile +thread_leak_profile_head() { + atf_set "descr" "Test thread sanitizer for thread leak with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case thread_leak_pic +thread_leak_pic_head() { + atf_set "descr" "Test thread sanitizer for thread leak with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case thread_leak_pie +thread_leak_pie_head() { + atf_set "descr" "Test thread sanitizer for thread leak with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +thread_leak_body(){ + cat > test.cc << EOF +#include +#include + +int GlobalData; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + sleep(1); + return 0; +} +EOF + + c++ -fsanitize=thread -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: thread leak" ./test +} + +thread_leak_profile_body(){ + cat > test.cc << EOF +#include +#include + +int GlobalData; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + sleep(1); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: thread leak" ./test +} + +thread_leak_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +#include + +int GlobalData; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + return 0; +} + +int help(int argc) { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + sleep(1); + return 0; +} +EOF + + c++ -fsanitize=thread -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: thread leak" ./test +} +thread_leak_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +#include + +int GlobalData; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + sleep(1); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: thread leak" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case thread_leak + atf_add_test_case thread_leak_profile + atf_add_test_case thread_leak_pie + atf_add_test_case thread_leak_pic +} diff --git a/tests/usr.bin/c++/t_tsan_vptr_race.sh b/tests/usr.bin/c++/t_tsan_vptr_race.sh new file mode 100644 index 000000000000..04d8b78e8355 --- /dev/null +++ b/tests/usr.bin/c++/t_tsan_vptr_race.sh @@ -0,0 +1,228 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \ + ! echo __clang__ | c++ -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case vptr_race +vptr_race_head() { + atf_set "descr" "Test thread sanitizer for vptr race condition" + atf_set "require.progs" "c++ paxctl" +} + +atf_test_case vptr_race_profile +vptr_race_profile_head() { + atf_set "descr" "Test thread sanitizer for vptr race with profiling option" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case vptr_race_pic +vptr_race_pic_head() { + atf_set "descr" "Test thread sanitizer for vptr race with position independent code (PIC) flag" + atf_set "require.progs" "c++ paxctl" +} +atf_test_case vptr_race_pie +vptr_race_pie_head() { + atf_set "descr" "Test thread sanitizer for vptr race with position independent execution (PIE) flag" + atf_set "require.progs" "c++ paxctl" +} + +vptr_race_body(){ + cat > test.cc << EOF +#include +pthread_barrier_t barrier; +struct A { + volatile bool done; + A(): done(false) { } + virtual void Done() { done = true; } + virtual ~A() { while (!done) ; } +}; +struct B: A {}; +A *obj = new B; +void *Thread1(void *x) { + pthread_barrier_wait(&barrier); + obj->Done(); + return NULL; +} +int main() { + pthread_barrier_init(&barrier, NULL, 2); + pthread_t t; + pthread_create(&t, NULL, Thread1, NULL); + pthread_barrier_wait(&barrier); + delete obj; + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race on vptr \(ctor/dtor vs virtual call\)" ./test +} + +vptr_race_profile_body(){ + cat > test.cc << EOF +#include +pthread_barrier_t barrier; +struct A { + volatile bool done; + A(): done(false) { } + virtual void Done() { done = true; } + virtual ~A() { while (!done) ; } +}; +struct B: A {}; +A *obj = new B; +void *Thread1(void *x) { + pthread_barrier_wait(&barrier); + obj->Done(); + return NULL; +} +int main() { + pthread_barrier_init(&barrier, NULL, 2); + pthread_t t; + pthread_create(&t, NULL, Thread1, NULL); + pthread_barrier_wait(&barrier); + delete obj; + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -pg test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race on vptr \(ctor/dtor vs virtual call\)" ./test +} + +vptr_race_pic_body(){ + cat > test.cc << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.cc << EOF +#include +pthread_barrier_t barrier; +struct A { + volatile bool done; + A(): done(false) { } + virtual void Done() { done = true; } + virtual ~A() { while (!done) ; } +}; +struct B: A {}; +A *obj = new B; +void *Thread1(void *x) { + pthread_barrier_wait(&barrier); + obj->Done(); + return NULL; +} +int help(int argc) { + pthread_barrier_init(&barrier, NULL, 2); + pthread_t t; + pthread_create(&t, NULL, Thread1, NULL); + pthread_barrier_wait(&barrier); + delete obj; + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -fPIC -shared -o libtest.so pic.cc + c++ -o test test.cc -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race on vptr \(ctor/dtor vs virtual call\)" ./test +} +vptr_race_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "c++ -pie not supported on this architecture" + fi + cat > test.cc << EOF +#include +pthread_barrier_t barrier; +struct A { + volatile bool done; + A(): done(false) { } + virtual void Done() { done = true; } + virtual ~A() { while (!done) ; } +}; +struct B: A {}; +A *obj = new B; +void *Thread1(void *x) { + pthread_barrier_wait(&barrier); + obj->Done(); + return NULL; +} +int main() { + pthread_barrier_init(&barrier, NULL, 2); + pthread_t t; + pthread_create(&t, NULL, Thread1, NULL); + pthread_barrier_wait(&barrier); + delete obj; + pthread_join(t, NULL); + return 0; +} +EOF + + c++ -fsanitize=thread -o test -fpie -pie test.cc + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race on vptr \(ctor/dtor vs virtual call\)" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case vptr_race + atf_add_test_case vptr_race_profile + atf_add_test_case vptr_race_pie + atf_add_test_case vptr_race_pic +} diff --git a/tests/usr.bin/cc/Makefile b/tests/usr.bin/cc/Makefile index f1e3aa95b4d3..6755a0ed632b 100644 --- a/tests/usr.bin/cc/Makefile +++ b/tests/usr.bin/cc/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.7 2019/02/09 00:12:14 mrg Exp $ +# $NetBSD: Makefile,v 1.8 2019/08/18 20:15:58 kamil Exp $ .include @@ -25,6 +25,28 @@ TESTS_SH+= $(UBSAN_TESTS) TESTS_SH+= t_hello TESTS_SH+= t_libgomp +TESTS_SH+= t_fuzzer_oom +TESTS_SH+= t_fuzzer_simple +TESTS_SH+= t_fuzzer_timeout + +TESTS_SH+= t_msan_allocated_memory +TESTS_SH+= t_msan_check_mem +TESTS_SH+= t_msan_free +TESTS_SH+= t_msan_heap +TESTS_SH+= t_msan_partial_poison +TESTS_SH+= t_msan_poison +TESTS_SH+= t_msan_realloc +TESTS_SH+= t_msan_shadow +TESTS_SH+= t_msan_stack +TESTS_SH+= t_msan_unpoison + +TESTS_SH+= t_tsan_data_race +TESTS_SH+= t_tsan_heap_use_after_free +TESTS_SH+= t_tsan_lock_order_inversion +TESTS_SH+= t_tsan_locked_mutex_destroy +TESTS_SH+= t_tsan_signal_errno +TESTS_SH+= t_tsan_thread_leak + .for test in ${ASAN_TESTS} TESTS_SH_SRC_${test}= asan_common.subr ${test}.sh .endfor diff --git a/tests/usr.bin/cc/t_fuzzer_oom.sh b/tests/usr.bin/cc/t_fuzzer_oom.sh new file mode 100644 index 000000000000..e5daaefe3dd6 --- /dev/null +++ b/tests/usr.bin/cc/t_fuzzer_oom.sh @@ -0,0 +1,166 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case oom +oom_head() { + atf_set "descr" "Test thread sanitizer for out-of-memory condition" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case oom_profile +oom_profile_head() { + atf_set "descr" "Test thread sanitizer for out-of-memory with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case oom_pic +oom_pic_head() { + atf_set "descr" "Test thread sanitizer for out-of-memory with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case oom_pie +oom_pie_head() { + atf_set "descr" "Test thread sanitizer for out-of-memory with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +oom_body(){ + cat > test.c << EOF +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) malloc(16*1024*1024); + return 0; +} +EOF + + cc -fsanitize=fuzzer -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: out-of-memory" ./test -rss_limit_mb=30 +} + +oom_profile_body(){ + cat > test.c << EOF +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) malloc(16*1024*1024); + return 0; +} +EOF + + cc -fsanitize=fuzzer -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: out-of-memory" ./test -rss_limit_mb=30 +} + +oom_pic_body(){ + cat > test.c << EOF +#include +#include +int help(const uint8_t *data, size_t size); +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + return help(data, size); +} +EOF + + cat > pic.c << EOF +#include +#include +#include + +int help(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) malloc(16*1024*1024); + return 0; +} +EOF + + cc -fsanitize=fuzzer -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=fuzzer -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: out-of-memory" ./test -rss_limit_mb=30 +} +oom_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) malloc(16*1024*1024); + return 0; +} +EOF + + cc -fsanitize=fuzzer -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: out-of-memory" ./test -rss_limit_mb=30 +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case oom + atf_add_test_case oom_profile + atf_add_test_case oom_pie + atf_add_test_case oom_pic +} diff --git a/tests/usr.bin/cc/t_fuzzer_simple.sh b/tests/usr.bin/cc/t_fuzzer_simple.sh new file mode 100644 index 000000000000..346b9aa54d0d --- /dev/null +++ b/tests/usr.bin/cc/t_fuzzer_simple.sh @@ -0,0 +1,182 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case simple +simple_head() { + atf_set "descr" "Test thread sanitizer for error exit condition" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case simple_profile +simple_profile_head() { + atf_set "descr" "Test thread sanitizer for simple with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case simple_pic +simple_pic_head() { + atf_set "descr" "Test thread sanitizer for simple with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case simple_pie +simple_pie_head() { + atf_set "descr" "Test thread sanitizer for simple with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +simple_body(){ + cat > test.c << EOF +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') { + fprintf(stderr, "BINGO\n"); + exit(1); + } + + return 0; +} +EOF + + cc -fsanitize=fuzzer -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"BINGO" ./test +} + +simple_profile_body(){ + cat > test.c << EOF +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') { + fprintf(stderr, "BINGO\n"); + exit(1); + } + + return 0; +} +EOF + + cc -fsanitize=fuzzer -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"BINGO" ./test +} + +simple_pic_body(){ + cat > test.c << EOF +#include +#include +int help(const uint8_t *data, size_t size); +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + return help(data, size); +} +EOF + + cat > pic.c << EOF +#include +#include +#include + +int help(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') { + fprintf(stderr, "BINGO\n"); + exit(1); + } + + return 0; +} +EOF + + cc -fsanitize=fuzzer -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=fuzzer -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"BINGO" ./test +} +simple_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') { + fprintf(stderr, "BINGO\n"); + exit(1); + } + + return 0; +} +EOF + + cc -fsanitize=fuzzer -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"BINGO" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case simple + atf_add_test_case simple_profile + atf_add_test_case simple_pie + atf_add_test_case simple_pic +} diff --git a/tests/usr.bin/cc/t_fuzzer_timeout.sh b/tests/usr.bin/cc/t_fuzzer_timeout.sh new file mode 100644 index 000000000000..270d4fed47fa --- /dev/null +++ b/tests/usr.bin/cc/t_fuzzer_timeout.sh @@ -0,0 +1,162 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case timeout +timeout_head() { + atf_set "descr" "Test thread sanitizer for timeout condition" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case timeout_profile +timeout_profile_head() { + atf_set "descr" "Test thread sanitizer for timeout with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case timeout_pic +timeout_pic_head() { + atf_set "descr" "Test thread sanitizer for timeout with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case timeout_pie +timeout_pie_head() { + atf_set "descr" "Test thread sanitizer for timeout with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +timeout_body(){ + cat > test.c << EOF +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) ; + return 0; +} +EOF + + cc -fsanitize=fuzzer -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: timeout" ./test -timeout=5 +} + +timeout_profile_body(){ + cat > test.c << EOF +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) ; + return 0; +} +EOF + + cc -fsanitize=fuzzer -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: timeout" ./test -timeout=5 +} + +timeout_pic_body(){ + cat > test.c << EOF +#include +#include +int help(const uint8_t *data, size_t size); +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + return help(data, size); +} +EOF + + cat > pic.c << EOF +#include +#include + +int help(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) ; + return 0; +} +EOF + + cc -fsanitize=fuzzer -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=fuzzer -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: timeout" ./test -timeout=5 +} +timeout_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'b') while (1) ; + return 0; +} +EOF + + cc -fsanitize=fuzzer -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"ERROR: libFuzzer: timeout" ./test -timeout=5 +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case timeout + atf_add_test_case timeout_profile + atf_add_test_case timeout_pie + atf_add_test_case timeout_pic +} diff --git a/tests/usr.bin/cc/t_msan_allocated_memory.sh b/tests/usr.bin/cc/t_msan_allocated_memory.sh new file mode 100644 index 000000000000..bf95c45ecfe1 --- /dev/null +++ b/tests/usr.bin/cc/t_msan_allocated_memory.sh @@ -0,0 +1,164 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case allocated_memory +allocated_memory_head() { + atf_set "descr" "Test memory sanitizer for __msan_allocated_memory interface" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case allocated_memory_profile +allocated_memory_profile_head() { + atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case allocated_memory_pic +allocated_memory_pic_head() { + atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case allocated_memory_pie +allocated_memory_pie_head() { + atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +allocated_memory_body(){ + cat > test.c << EOF +#include +#include + +int main() { + int x = 0; + __msan_allocated_memory(&x, sizeof(x)); + return x; +} +EOF + + cc -fsanitize=memory -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +allocated_memory_profile_body(){ + cat > test.c << EOF +#include +#include + +int main() { + int x = 0; + __msan_allocated_memory(&x, sizeof(x)); + return x; +} +EOF + + cc -fsanitize=memory -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +allocated_memory_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +#include + +int help(int argc) { + int x = 0; + __msan_allocated_memory(&x, sizeof(x)); + return x; +} +EOF + + cc -fsanitize=memory -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} +allocated_memory_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include + +int main() { + int x = 0; + __msan_allocated_memory(&x, sizeof(x)); + return x; +} +EOF + + cc -fsanitize=memory -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case allocated_memory + atf_add_test_case allocated_memory_profile + atf_add_test_case allocated_memory_pie + atf_add_test_case allocated_memory_pic +} diff --git a/tests/usr.bin/cc/t_msan_check_mem.sh b/tests/usr.bin/cc/t_msan_check_mem.sh new file mode 100644 index 000000000000..75ba9c13a4e2 --- /dev/null +++ b/tests/usr.bin/cc/t_msan_check_mem.sh @@ -0,0 +1,168 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case check_mem +check_mem_head() { + atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized interface" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case check_mem_profile +check_mem_profile_head() { + atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case check_mem_pic +check_mem_pic_head() { + atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case check_mem_pie +check_mem_pie_head() { + atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +check_mem_body(){ + cat > test.c << EOF +#include +#include + +int main(int argc, char **argv) { + int *volatile p = (int *)malloc(sizeof(int)); + + __msan_check_mem_is_initialized(p, sizeof(*p)); + return 0; +} +EOF + + cc -fsanitize=memory -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 0 inside" ./test +} + +check_mem_profile_body(){ + cat > test.c << EOF +#include +#include + +int main(int argc, char **argv) { + int *volatile p = (int *)malloc(sizeof(int)); + + __msan_check_mem_is_initialized(p, sizeof(*p)); + return 0; +} +EOF + + cc -fsanitize=memory -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 0 inside" ./test +} + +check_mem_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +#include + +int help(int argc) { + int *volatile p = (int *)malloc(sizeof(int)); + + __msan_check_mem_is_initialized(p, sizeof(*p)); + return 0; +} +EOF + + cc -fsanitize=memory -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 0 inside" ./test +} +check_mem_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include + +int main(int argc, char **argv) { + int *volatile p = (int *)malloc(sizeof(int)); + + __msan_check_mem_is_initialized(p, sizeof(*p)); + return 0; +} +EOF + + cc -fsanitize=memory -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 0 inside" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case check_mem + atf_add_test_case check_mem_profile + atf_add_test_case check_mem_pie + atf_add_test_case check_mem_pic +} diff --git a/tests/usr.bin/cc/t_msan_free.sh b/tests/usr.bin/cc/t_msan_free.sh new file mode 100644 index 000000000000..f7014539d867 --- /dev/null +++ b/tests/usr.bin/cc/t_msan_free.sh @@ -0,0 +1,159 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case free +free_head() { + atf_set "descr" "Test memory sanitizer for use-after-free case" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case free_profile +free_profile_head() { + atf_set "descr" "Test memory sanitizer for use-after-free with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case free_pic +free_pic_head() { + atf_set "descr" "Test memory sanitizer for use-after-free with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case free_pie +free_pie_head() { + atf_set "descr" "Test memory sanitizer for use-after-free with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +free_body(){ + cat > test.c << EOF +#include +int main() { + int *a = (int *)malloc(sizeof(int)); + *a = 9; + free(a); + return *a; +} +EOF + + cc -fsanitize=memory -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +free_profile_body(){ + cat > test.c << EOF +#include +int main() { + int *a = (int *)malloc(sizeof(int)); + *a = 9; + free(a); + return *a; +} +EOF + + cc -fsanitize=memory -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +free_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +int help(int argc) { + int *a = (int *)malloc(sizeof(int)); + *a = 9; + free(a); + return *a; +} +EOF + + cc -fsanitize=memory -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} +free_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +int main() { + int *a = (int *)malloc(sizeof(int)); + *a = 9; + free(a); + return *a; +} +EOF + + cc -fsanitize=memory -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case free + atf_add_test_case free_profile + atf_add_test_case free_pie + atf_add_test_case free_pic +} diff --git a/tests/usr.bin/cc/t_msan_heap.sh b/tests/usr.bin/cc/t_msan_heap.sh new file mode 100644 index 000000000000..02ab8f3a7da1 --- /dev/null +++ b/tests/usr.bin/cc/t_msan_heap.sh @@ -0,0 +1,139 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case heap +heap_head() { + atf_set "descr" "Test memory sanitizer for uninitialized heap value case" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case heap_profile +heap_profile_head() { + atf_set "descr" "Test memory sanitizer for uninitialized heap value with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case heap_pic +heap_pic_head() { + atf_set "descr" "Test memory sanitizer for uninitialized heap value with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case heap_pie +heap_pie_head() { + atf_set "descr" "Test memory sanitizer for uninitialized heap value with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +heap_body(){ + cat > test.c << EOF +#include +int main() { int *a = (int *)malloc(sizeof(int)); return *a; } +EOF + + cc -fsanitize=memory -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +heap_profile_body(){ + cat > test.c << EOF +#include +int main() { int *a = (int *)malloc(sizeof(int)); return *a; } +EOF + + cc -fsanitize=memory -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +heap_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +int help(int argc) { int *a = (int *)malloc(sizeof(int)); return *a; } +EOF + + cc -fsanitize=memory -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} +heap_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +int main() { int *a = (int *)malloc(sizeof(int)); return *a; } +EOF + + cc -fsanitize=memory -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case heap + atf_add_test_case heap_profile + atf_add_test_case heap_pie + atf_add_test_case heap_pic +} diff --git a/tests/usr.bin/cc/t_msan_partial_poison.sh b/tests/usr.bin/cc/t_msan_partial_poison.sh new file mode 100644 index 000000000000..9d5b9489c6db --- /dev/null +++ b/tests/usr.bin/cc/t_msan_partial_poison.sh @@ -0,0 +1,171 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case partial_poison +partial_poison_head() { + atf_set "descr" "Test memory sanitizer for __msan_partial_poison interface" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case partial_poison_profile +partial_poison_profile_head() { + atf_set "descr" "Test memory sanitizer for __msan_partial_poison with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case partial_poison_pic +partial_poison_pic_head() { + atf_set "descr" "Test memory sanitizer for __msan_partial_poison with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case partial_poison_pie +partial_poison_pie_head() { + atf_set "descr" "Test memory sanitizer for __msan_partial_poison with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +partial_poison_body(){ + cat > test.c << EOF +#include +#include + +int main(void) { + char x[4]; + char x_s[4] = {0x77, 0x65, 0x43, 0x21}; + __msan_partial_poison(&x, &x_s, sizeof(x_s)); + __msan_print_shadow(&x, sizeof(x_s)); + return 0; +} +EOF + + cc -fsanitize=memory -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:": 77654321" ./test +} + +partial_poison_profile_body(){ + cat > test.c << EOF +#include +#include + +int main(void) { + char x[4]; + char x_s[4] = {0x77, 0x65, 0x43, 0x21}; + __msan_partial_poison(&x, &x_s, sizeof(x_s)); + __msan_print_shadow(&x, sizeof(x_s)); + return 0; +} +EOF + + cc -fsanitize=memory -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:": 77654321" ./test +} + +partial_poison_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +#include + +int help(int argc) { + char x[4]; + char x_s[4] = {0x77, 0x65, 0x43, 0x21}; + __msan_partial_poison(&x, &x_s, sizeof(x_s)); + __msan_print_shadow(&x, sizeof(x_s)); + return 0; +} +EOF + + cc -fsanitize=memory -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:": 77654321" ./test +} +partial_poison_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include + +int main(void) { + char x[4]; + char x_s[4] = {0x77, 0x65, 0x43, 0x21}; + __msan_partial_poison(&x, &x_s, sizeof(x_s)); + __msan_print_shadow(&x, sizeof(x_s)); + return 0; +} +EOF + + cc -fsanitize=memory -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:": 77654321" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case partial_poison + atf_add_test_case partial_poison_profile + atf_add_test_case partial_poison_pie + atf_add_test_case partial_poison_pic +} diff --git a/tests/usr.bin/cc/t_msan_poison.sh b/tests/usr.bin/cc/t_msan_poison.sh new file mode 100644 index 000000000000..68b5f28c3188 --- /dev/null +++ b/tests/usr.bin/cc/t_msan_poison.sh @@ -0,0 +1,167 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case poison +poison_head() { + atf_set "descr" "Test memory sanitizer for __msan_poison interface" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case poison_profile +poison_profile_head() { + atf_set "descr" "Test memory sanitizer for __msan_poison with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case poison_pic +poison_pic_head() { + atf_set "descr" "Test memory sanitizer for __msan_poison with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case poison_pie +poison_pie_head() { + atf_set "descr" "Test memory sanitizer for __msan_poison with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +poison_body(){ + cat > test.c << EOF +#include + +int main(void) { + char p[32] = {}; + __msan_poison(p + 10, 2); + + __msan_check_mem_is_initialized(p + 5, 20); + return 0; +} +EOF + + cc -fsanitize=memory -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 5 inside" ./test +} + +poison_profile_body(){ + cat > test.c << EOF +#include + +int main(void) { + char p[32] = {}; + __msan_poison(p + 10, 2); + + __msan_check_mem_is_initialized(p + 5, 20); + return 0; +} +EOF + + cc -fsanitize=memory -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 5 inside" ./test +} + +poison_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include + +int help(int argc) { + char p[32] = {}; + __msan_poison(p + 10, 2); + + __msan_check_mem_is_initialized(p + 5, 20); + return 0; +} +EOF + + cc -fsanitize=memory -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 5 inside" ./test +} +poison_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include + +int main(void) { + char p[32] = {}; + __msan_poison(p + 10, 2); + + __msan_check_mem_is_initialized(p + 5, 20); + return 0; +} +EOF + + cc -fsanitize=memory -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"Uninitialized bytes in __msan_check_mem_is_initialized at offset 5 inside" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case poison + atf_add_test_case poison_profile + atf_add_test_case poison_pie + atf_add_test_case poison_pic +} diff --git a/tests/usr.bin/cc/t_msan_realloc.sh b/tests/usr.bin/cc/t_msan_realloc.sh new file mode 100644 index 000000000000..499f1d1c31d4 --- /dev/null +++ b/tests/usr.bin/cc/t_msan_realloc.sh @@ -0,0 +1,163 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case realloc +realloc_head() { + atf_set "descr" "Test memory sanitizer for realloc" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case realloc_profile +realloc_profile_head() { + atf_set "descr" "Test memory sanitizer for realloc with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case realloc_pic +realloc_pic_head() { + atf_set "descr" "Test memory sanitizer for realloc with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case realloc_pie +realloc_pie_head() { + atf_set "descr" "Test memory sanitizer for realloc with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +realloc_body(){ + cat > test.c << EOF +#include +int main(int argc, char **argv) { + char *p = (char *)malloc(100); + p = (char *)realloc(p, 10000); + char x = p[50]; + free(p); + return x; +} +EOF + + cc -fsanitize=memory -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +realloc_profile_body(){ + cat > test.c << EOF +#include +int main(int argc, char **argv) { + char *p = (char *)malloc(100); + p = (char *)realloc(p, 10000); + char x = p[50]; + free(p); + return x; +} +EOF + + cc -fsanitize=memory -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +realloc_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +int help(int argc) { + char *p = (char *)malloc(100); + p = (char *)realloc(p, 10000); + char x = p[50]; + free(p); + return x; +} +EOF + + cc -fsanitize=memory -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} +realloc_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +int main(int argc, char **argv) { + char *p = (char *)malloc(100); + p = (char *)realloc(p, 10000); + char x = p[50]; + free(p); + return x; +} +EOF + + cc -fsanitize=memory -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case realloc + atf_add_test_case realloc_profile + atf_add_test_case realloc_pie + atf_add_test_case realloc_pic +} diff --git a/tests/usr.bin/cc/t_msan_shadow.sh b/tests/usr.bin/cc/t_msan_shadow.sh new file mode 100644 index 000000000000..f5408825fcf3 --- /dev/null +++ b/tests/usr.bin/cc/t_msan_shadow.sh @@ -0,0 +1,183 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case shadow +shadow_head() { + atf_set "descr" "Test memory sanitizer for shadow interface" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case shadow_profile +shadow_profile_head() { + atf_set "descr" "Test memory sanitizer for shadow with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case shadow_pic +shadow_pic_head() { + atf_set "descr" "Test memory sanitizer for shadow with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case shadow_pie +shadow_pie_head() { + atf_set "descr" "Test memory sanitizer for shadow with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +shadow_body(){ + cat > test.c << EOF +#include +#include +#include + +int main(int argc, char **argv) { + char str[] = "abc"; + char str2[] = "cdefghi"; + __msan_poison(str + 2, 1); + __msan_copy_shadow(str2 + 2, str, 4); + printf("%ld\n", __msan_test_shadow(str, 4)); + __msan_print_shadow(str2, 8); + return 0; +} +EOF + + cc -fsanitize=memory -o test test.c + paxctl +a test + atf_check -s ignore -o match:"2" -e match:"00000000 ff000000" ./test +} + +shadow_profile_body(){ + cat > test.c << EOF +#include +#include +#include + +int main(int argc, char **argv) { + char str[] = "abc"; + char str2[] = "cdefghi"; + __msan_poison(str + 2, 1); + __msan_copy_shadow(str2 + 2, str, 4); + printf("%ld\n", __msan_test_shadow(str, 4)); + __msan_print_shadow(str2, 8); + return 0; +} +EOF + + cc -fsanitize=memory -o test -pg test.c + paxctl +a test + atf_check -s ignore -o match:"2" -e match:"00000000 ff000000" ./test +} + +shadow_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +#include +#include + +int help(int argc) { + char str[] = "abc"; + char str2[] = "cdefghi"; + __msan_poison(str + 2, 1); + __msan_copy_shadow(str2 + 2, str, 4); + printf("%ld\n", __msan_test_shadow(str, 4)); + __msan_print_shadow(str2, 8); + return 0; +} +EOF + + cc -fsanitize=memory -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o match:"2" -e match:"00000000 ff000000" ./test +} +shadow_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include +#include + +int main(int argc, char **argv) { + char str[] = "abc"; + char str2[] = "cdefghi"; + __msan_poison(str + 2, 1); + __msan_copy_shadow(str2 + 2, str, 4); + printf("%ld\n", __msan_test_shadow(str, 4)); + __msan_print_shadow(str2, 8); + return 0; +} +EOF + + cc -fsanitize=memory -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o match:"2" -e match:"00000000 ff000000" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case shadow + atf_add_test_case shadow_profile + atf_add_test_case shadow_pie + atf_add_test_case shadow_pic +} diff --git a/tests/usr.bin/cc/t_msan_stack.sh b/tests/usr.bin/cc/t_msan_stack.sh new file mode 100644 index 000000000000..c032a91725df --- /dev/null +++ b/tests/usr.bin/cc/t_msan_stack.sh @@ -0,0 +1,159 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case stack +stack_head() { + atf_set "descr" "Test memory sanitizer for free-stack-pointer case" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case stack_profile +stack_profile_head() { + atf_set "descr" "Test memory sanitizer for free-stack-pointer with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case stack_pic +stack_pic_head() { + atf_set "descr" "Test memory sanitizer for free-stack-pointer with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case stack_pie +stack_pie_head() { + atf_set "descr" "Test memory sanitizer for free-stack-pointer with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +stack_body(){ + cat > test.c << EOF +#include +int main() { + int a = 0; + int *p = &a; + free(p); + return 0; +} +EOF + + cc -fsanitize=memory -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"MemorySanitizer: bad pointer" ./test +} + +stack_profile_body(){ + cat > test.c << EOF +#include +int main() { + int a = 0; + int *p = &a; + free(p); + return 0; +} +EOF + + cc -fsanitize=memory -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"MemorySanitizer: bad pointer" ./test +} + +stack_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +int help(int argc) { + int a = 0; + int *p = &a; + free(p); + return 0; +} +EOF + + cc -fsanitize=memory -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"MemorySanitizer: bad pointer" ./test +} +stack_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +int main() { + int a = 0; + int *p = &a; + free(p); + return 0; +} +EOF + + cc -fsanitize=memory -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"MemorySanitizer: bad pointer" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case stack + atf_add_test_case stack_profile + atf_add_test_case stack_pie + atf_add_test_case stack_pic +} diff --git a/tests/usr.bin/cc/t_msan_unpoison.sh b/tests/usr.bin/cc/t_msan_unpoison.sh new file mode 100644 index 000000000000..18dc8333f715 --- /dev/null +++ b/tests/usr.bin/cc/t_msan_unpoison.sh @@ -0,0 +1,183 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case unpoison +unpoison_head() { + atf_set "descr" "Test memory sanitizer for __msan_unpoison interface" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case unpoison_profile +unpoison_profile_head() { + atf_set "descr" "Test memory sanitizer for __msan_unpoison with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case unpoison_pic +unpoison_pic_head() { + atf_set "descr" "Test memory sanitizer for __msan_unpoison with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case unpoison_pie +unpoison_pie_head() { + atf_set "descr" "Test memory sanitizer for __msan_unpoison with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +unpoison_body(){ + cat > test.c << EOF +#include + +int main(void) { + char p[32] = {}; + char q[32] = {}; + __msan_poison(p + 10, 2); + __msan_poison(q, 32); + __msan_unpoison(p + 10, 2); + __msan_unpoison_string(q); + __msan_check_mem_is_initialized(p, 32); + __msan_check_mem_is_initialized(p, 32); + return 0; +} +EOF + + cc -fsanitize=memory -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e not-match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +unpoison_profile_body(){ + cat > test.c << EOF +#include + +int main(void) { + char p[32] = {}; + char q[32] = {}; + __msan_poison(p + 10, 2); + __msan_poison(q, 32); + __msan_unpoison(p + 10, 2); + __msan_unpoison_string(q); + __msan_check_mem_is_initialized(p, 32); + __msan_check_mem_is_initialized(p, 32); + return 0; +} +EOF + + cc -fsanitize=memory -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e not-match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +unpoison_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include + +int help(int argc) { + char p[32] = {}; + char q[32] = {}; + __msan_poison(p + 10, 2); + __msan_poison(q, 32); + __msan_unpoison(p + 10, 2); + __msan_unpoison_string(q); + __msan_check_mem_is_initialized(p, 32); + __msan_check_mem_is_initialized(p, 32); + return 0; +} +EOF + + cc -fsanitize=memory -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=memory -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e not-match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} +unpoison_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include + +int main(void) { + char p[32] = {}; + char q[32] = {}; + __msan_poison(p + 10, 2); + __msan_poison(q, 32); + __msan_unpoison(p + 10, 2); + __msan_unpoison_string(q); + __msan_check_mem_is_initialized(p, 32); + __msan_check_mem_is_initialized(p, 32); + return 0; +} +EOF + + cc -fsanitize=memory -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e not-match:"WARNING: MemorySanitizer: use-of-uninitialized-value" ./test +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case unpoison + atf_add_test_case unpoison_profile + atf_add_test_case unpoison_pie + atf_add_test_case unpoison_pic +} diff --git a/tests/usr.bin/cc/t_tsan_data_race.sh b/tests/usr.bin/cc/t_tsan_data_race.sh new file mode 100644 index 000000000000..2b6c169373c5 --- /dev/null +++ b/tests/usr.bin/cc/t_tsan_data_race.sh @@ -0,0 +1,180 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case data_race +data_race_head() { + atf_set "descr" "Test thread sanitizer for data race condition" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case data_race_profile +data_race_profile_head() { + atf_set "descr" "Test thread sanitizer for data race with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case data_race_pic +data_race_pic_head() { + atf_set "descr" "Test thread sanitizer for data race with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case data_race_pie +data_race_pie_head() { + atf_set "descr" "Test thread sanitizer for data race with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +data_race_body(){ + cat > test.c << EOF +#include +int GlobalData; pthread_barrier_t barrier; +void *Thread(void *a) { pthread_barrier_wait(&barrier); GlobalData = 42; return 0; } +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + GlobalData = 43; + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race " ./test +} + +data_race_profile_body(){ + cat > test.c << EOF +#include +int GlobalData; pthread_barrier_t barrier; +void *Thread(void *a) { pthread_barrier_wait(&barrier); GlobalData = 42; return 0; } +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + GlobalData = 43; + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race " ./test +} + +data_race_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +int GlobalData; pthread_barrier_t barrier; +void *Thread(void *a) { pthread_barrier_wait(&barrier); GlobalData = 42; return 0; } +int help(int argc) { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + GlobalData = 43; + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race " ./test +} +data_race_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +int GlobalData; pthread_barrier_t barrier; +void *Thread(void *a) { pthread_barrier_wait(&barrier); GlobalData = 42; return 0; } +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + GlobalData = 43; + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: data race " ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case data_race + atf_add_test_case data_race_profile + atf_add_test_case data_race_pie + atf_add_test_case data_race_pic +} diff --git a/tests/usr.bin/cc/t_tsan_heap_use_after_free.sh b/tests/usr.bin/cc/t_tsan_heap_use_after_free.sh new file mode 100644 index 000000000000..dc28baa88107 --- /dev/null +++ b/tests/usr.bin/cc/t_tsan_heap_use_after_free.sh @@ -0,0 +1,216 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case heap_use_after_free +heap_use_after_free_head() { + atf_set "descr" "Test thread sanitizer for use-after-free condition" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case heap_use_after_free_profile +heap_use_after_free_profile_head() { + atf_set "descr" "Test thread sanitizer for use-after-free with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case heap_use_after_free_pic +heap_use_after_free_pic_head() { + atf_set "descr" "Test thread sanitizer for use-after-free with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case heap_use_after_free_pie +heap_use_after_free_pie_head() { + atf_set "descr" "Test thread sanitizer for use-after-free with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +heap_use_after_free_body(){ + cat > test.c << EOF +#include +#include + +int *ptr; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + *ptr = 42; + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + ptr = (int *)malloc(sizeof(int)); + pthread_create(&t, NULL, Thread, NULL); + free(ptr); + pthread_barrier_wait(&barrier); + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: heap-use-after-free" ./test +} + +heap_use_after_free_profile_body(){ + cat > test.c << EOF +#include +#include + +int *ptr; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + *ptr = 42; + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + ptr = (int *)malloc(sizeof(int)); + pthread_create(&t, NULL, Thread, NULL); + free(ptr); + pthread_barrier_wait(&barrier); + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: heap-use-after-free" ./test +} + +heap_use_after_free_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +#include + +int *ptr; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + *ptr = 42; + return 0; +} + +int help(int argc) { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + ptr = (int *)malloc(sizeof(int)); + pthread_create(&t, NULL, Thread, NULL); + free(ptr); + pthread_barrier_wait(&barrier); + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: heap-use-after-free" ./test +} +heap_use_after_free_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include + +int *ptr; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + *ptr = 42; + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + ptr = (int *)malloc(sizeof(int)); + pthread_create(&t, NULL, Thread, NULL); + free(ptr); + pthread_barrier_wait(&barrier); + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: heap-use-after-free" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case heap_use_after_free + atf_add_test_case heap_use_after_free_profile + atf_add_test_case heap_use_after_free_pie + atf_add_test_case heap_use_after_free_pic +} diff --git a/tests/usr.bin/cc/t_tsan_lock_order_inversion.sh b/tests/usr.bin/cc/t_tsan_lock_order_inversion.sh new file mode 100644 index 000000000000..6334a75b55c3 --- /dev/null +++ b/tests/usr.bin/cc/t_tsan_lock_order_inversion.sh @@ -0,0 +1,200 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case lock_order_inversion +lock_order_inversion_head() { + atf_set "descr" "Test thread sanitizer for lock order inversion condition" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case lock_order_inversion_profile +lock_order_inversion_profile_head() { + atf_set "descr" "Test thread sanitizer for lock order inversion with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case lock_order_inversion_pic +lock_order_inversion_pic_head() { + atf_set "descr" "Test thread sanitizer for lock order inversion with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case lock_order_inversion_pie +lock_order_inversion_pie_head() { + atf_set "descr" "Test thread sanitizer for lock order inversion with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +lock_order_inversion_body(){ + cat > test.c << EOF +#include + +pthread_mutex_t l1, l2; +int main() { + pthread_mutex_init(&l1, NULL); + pthread_mutex_init(&l2, NULL); + pthread_mutex_lock(&l2); + pthread_mutex_lock(&l1); + pthread_mutex_unlock(&l1); + pthread_mutex_unlock(&l2); + + pthread_mutex_lock(&l1); + pthread_mutex_lock(&l2); + pthread_mutex_unlock(&l2); + pthread_mutex_unlock(&l1); + return 0; +} +EOF + + cc -fsanitize=thread -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: lock-order-inversion" ./test +} + +lock_order_inversion_profile_body(){ + cat > test.c << EOF +#include + +pthread_mutex_t l1, l2; +int main() { + pthread_mutex_init(&l1, NULL); + pthread_mutex_init(&l2, NULL); + pthread_mutex_lock(&l2); + pthread_mutex_lock(&l1); + pthread_mutex_unlock(&l1); + pthread_mutex_unlock(&l2); + + pthread_mutex_lock(&l1); + pthread_mutex_lock(&l2); + pthread_mutex_unlock(&l2); + pthread_mutex_unlock(&l1); + return 0; +} +EOF + + cc -fsanitize=thread -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: lock-order-inversion" ./test +} + +lock_order_inversion_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include + +pthread_mutex_t l1, l2; +int help(int argc) { + pthread_mutex_init(&l1, NULL); + pthread_mutex_init(&l2, NULL); + pthread_mutex_lock(&l2); + pthread_mutex_lock(&l1); + pthread_mutex_unlock(&l1); + pthread_mutex_unlock(&l2); + + pthread_mutex_lock(&l1); + pthread_mutex_lock(&l2); + pthread_mutex_unlock(&l2); + pthread_mutex_unlock(&l1); + return 0; +} +EOF + + cc -fsanitize=thread -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: lock-order-inversion" ./test +} +lock_order_inversion_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include + +pthread_mutex_t l1, l2; +int main() { + pthread_mutex_init(&l1, NULL); + pthread_mutex_init(&l2, NULL); + pthread_mutex_lock(&l2); + pthread_mutex_lock(&l1); + pthread_mutex_unlock(&l1); + pthread_mutex_unlock(&l2); + + pthread_mutex_lock(&l1); + pthread_mutex_lock(&l2); + pthread_mutex_unlock(&l2); + pthread_mutex_unlock(&l1); + return 0; +} +EOF + + cc -fsanitize=thread -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: lock-order-inversion" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case lock_order_inversion + atf_add_test_case lock_order_inversion_profile + atf_add_test_case lock_order_inversion_pie + atf_add_test_case lock_order_inversion_pic +} diff --git a/tests/usr.bin/cc/t_tsan_locked_mutex_destroy.sh b/tests/usr.bin/cc/t_tsan_locked_mutex_destroy.sh new file mode 100644 index 000000000000..83b5ad5f448a --- /dev/null +++ b/tests/usr.bin/cc/t_tsan_locked_mutex_destroy.sh @@ -0,0 +1,216 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case locked_mutex_destroy +locked_mutex_destroy_head() { + atf_set "descr" "Test thread sanitizer for destroying locked mutex condition" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case locked_mutex_destroy_profile +locked_mutex_destroy_profile_head() { + atf_set "descr" "Test thread sanitizer for destroying locked mutex with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case locked_mutex_destroy_pic +locked_mutex_destroy_pic_head() { + atf_set "descr" "Test thread sanitizer for destroying locked mutex with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case locked_mutex_destroy_pie +locked_mutex_destroy_pie_head() { + atf_set "descr" "Test thread sanitizer for destroying locked mutex with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +locked_mutex_destroy_body(){ + cat > test.c << EOF +#include +#include + +pthread_mutex_t mutex; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_mutex_lock(&mutex); + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_mutex_init(&mutex, NULL); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + pthread_mutex_destroy(&mutex); + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test +} + +locked_mutex_destroy_profile_body(){ + cat > test.c << EOF +#include +#include + +pthread_mutex_t mutex; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_mutex_lock(&mutex); + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_mutex_init(&mutex, NULL); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + pthread_mutex_destroy(&mutex); + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test +} + +locked_mutex_destroy_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +#include + +pthread_mutex_t mutex; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_mutex_lock(&mutex); + pthread_barrier_wait(&barrier); + return 0; +} + +int help(int argc) { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_mutex_init(&mutex, NULL); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + pthread_mutex_destroy(&mutex); + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test +} +locked_mutex_destroy_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include + +pthread_mutex_t mutex; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_mutex_lock(&mutex); + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_mutex_init(&mutex, NULL); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + pthread_mutex_destroy(&mutex); + pthread_join(t, NULL); + return 0; +} +EOF + + cc -fsanitize=thread -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case locked_mutex_destroy + atf_add_test_case locked_mutex_destroy_profile + atf_add_test_case locked_mutex_destroy_pie + atf_add_test_case locked_mutex_destroy_pic +} diff --git a/tests/usr.bin/cc/t_tsan_signal_errno.sh b/tests/usr.bin/cc/t_tsan_signal_errno.sh new file mode 100644 index 000000000000..a13472d2ddfe --- /dev/null +++ b/tests/usr.bin/cc/t_tsan_signal_errno.sh @@ -0,0 +1,204 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case signal_errno +signal_errno_head() { + atf_set "descr" "Test thread sanitizer for errno modification in signal condition" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case signal_errno_profile +signal_errno_profile_head() { + atf_set "descr" "Test thread sanitizer for errno modification in signal with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case signal_errno_pic +signal_errno_pic_head() { + atf_set "descr" "Test thread sanitizer for errno modification in signal with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case signal_errno_pie +signal_errno_pie_head() { + atf_set "descr" "Test thread sanitizer for errno modification in signal with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +signal_errno_body(){ + cat > test.c << EOF +#include +#include +#include +#include + +pthread_t mainth; +static void MyHandler(int a, siginfo_t *s, void *c) { errno = 1; } +static void* sendsignal(void *p) { pthread_kill(mainth, SIGPROF); return NULL; } +int main() { + mainth = pthread_self(); + struct sigaction act = {}; + act.sa_sigaction = &MyHandler; + sigaction(SIGPROF, &act, 0); + pthread_t th; + pthread_create(&th, 0, sendsignal, 0); + pthread_join(th, 0); + return 0; +} +EOF + + cc -fsanitize=thread -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: signal handler spoils errno" ./test +} + +signal_errno_profile_body(){ + cat > test.c << EOF +#include +#include +#include +#include + +pthread_t mainth; +static void MyHandler(int a, siginfo_t *s, void *c) { errno = 1; } +static void* sendsignal(void *p) { pthread_kill(mainth, SIGPROF); return NULL; } +int main() { + mainth = pthread_self(); + struct sigaction act = {}; + act.sa_sigaction = &MyHandler; + sigaction(SIGPROF, &act, 0); + pthread_t th; + pthread_create(&th, 0, sendsignal, 0); + pthread_join(th, 0); + return 0; +} +EOF + + cc -fsanitize=thread -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: signal handler spoils errno" ./test +} + +signal_errno_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +#include +#include +#include + +pthread_t mainth; +static void MyHandler(int a, siginfo_t *s, void *c) { errno = 1; } +static void* sendsignal(void *p) { pthread_kill(mainth, SIGPROF); return NULL; } +int help(int argc) { + mainth = pthread_self(); + struct sigaction act = {}; + act.sa_sigaction = &MyHandler; + sigaction(SIGPROF, &act, 0); + pthread_t th; + pthread_create(&th, 0, sendsignal, 0); + pthread_join(th, 0); + return 0; +} +EOF + + cc -fsanitize=thread -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: signal handler spoils errno" ./test +} +signal_errno_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include +#include +#include + +pthread_t mainth; +static void MyHandler(int a, siginfo_t *s, void *c) { errno = 1; } +static void* sendsignal(void *p) { pthread_kill(mainth, SIGPROF); return NULL; } +int main() { + mainth = pthread_self(); + struct sigaction act = {}; + act.sa_sigaction = &MyHandler; + sigaction(SIGPROF, &act, 0); + pthread_t th; + pthread_create(&th, 0, sendsignal, 0); + pthread_join(th, 0); + return 0; +} +EOF + + cc -fsanitize=thread -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: signal handler spoils errno" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case signal_errno + atf_add_test_case signal_errno_profile + atf_add_test_case signal_errno_pie + atf_add_test_case signal_errno_pic +} diff --git a/tests/usr.bin/cc/t_tsan_thread_leak.sh b/tests/usr.bin/cc/t_tsan_thread_leak.sh new file mode 100644 index 000000000000..eeafa0bf739a --- /dev/null +++ b/tests/usr.bin/cc/t_tsan_thread_leak.sh @@ -0,0 +1,204 @@ +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Yang Zheng. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +test_target() +{ + SUPPORT='n' + if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \ + ! echo __clang__ | cc -E - | grep -q __clang__; then + # only clang with major version newer than 7 is supported + CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'` + if [ "$CLANG_MAJOR" -ge "7" ]; then + SUPPORT='y' + fi + fi +} + +atf_test_case thread_leak +thread_leak_head() { + atf_set "descr" "Test thread sanitizer for thread leak condition" + atf_set "require.progs" "cc paxctl" +} + +atf_test_case thread_leak_profile +thread_leak_profile_head() { + atf_set "descr" "Test thread sanitizer for thread leak with profiling option" + atf_set "require.progs" "cc paxctl" +} +atf_test_case thread_leak_pic +thread_leak_pic_head() { + atf_set "descr" "Test thread sanitizer for thread leak with position independent code (PIC) flag" + atf_set "require.progs" "cc paxctl" +} +atf_test_case thread_leak_pie +thread_leak_pie_head() { + atf_set "descr" "Test thread sanitizer for thread leak with position independent execution (PIE) flag" + atf_set "require.progs" "cc paxctl" +} + +thread_leak_body(){ + cat > test.c << EOF +#include +#include + +int GlobalData; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + sleep(1); + return 0; +} +EOF + + cc -fsanitize=thread -o test test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: thread leak" ./test +} + +thread_leak_profile_body(){ + cat > test.c << EOF +#include +#include + +int GlobalData; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + sleep(1); + return 0; +} +EOF + + cc -fsanitize=thread -o test -pg test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: thread leak" ./test +} + +thread_leak_pic_body(){ + cat > test.c << EOF +#include +#include +int help(int); +int main(int argc, char **argv) {return help(argc);} +EOF + + cat > pic.c << EOF +#include +#include + +int GlobalData; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + return 0; +} + +int help(int argc) { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + sleep(1); + return 0; +} +EOF + + cc -fsanitize=thread -fPIC -shared -o libtest.so pic.c + cc -o test test.c -fsanitize=thread -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: thread leak" ./test +} +thread_leak_pie_body(){ + + #check whether -pie flag is supported on this architecture + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include + +int GlobalData; +pthread_barrier_t barrier; +void *Thread(void *a) { + pthread_barrier_wait(&barrier); + return 0; +} + +int main() { + pthread_t t; + pthread_barrier_init(&barrier, NULL, 2); + pthread_create(&t, NULL, Thread, NULL); + pthread_barrier_wait(&barrier); + sleep(1); + return 0; +} +EOF + + cc -fsanitize=thread -o test -fpie -pie test.c + paxctl +a test + atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: thread leak" ./test +} + + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +atf_init_test_cases() +{ + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + atf_add_test_case thread_leak + atf_add_test_case thread_leak_profile + atf_add_test_case thread_leak_pie + atf_add_test_case thread_leak_pic +}