Thu Aug 29 16:45:26 2019 UTC ()
Pull up following revision(s) (requested by kamil in ticket #120):

	tests/usr.bin/cc/t_msan_poison.sh: revision 1.1
	tests/usr.bin/cc/t_msan_allocated_memory.sh: revision 1.2
	tests/usr.bin/cc/t_msan_poison.sh: revision 1.2
	tests/usr.bin/c++/t_fuzzer_oom.sh: revision 1.1
	tests/usr.bin/cc/t_tsan_signal_errno.sh: revision 1.1
	tests/usr.bin/c++/t_fuzzer_simple.sh: revision 1.1
	tests/usr.bin/c++/t_fuzzer_oom.sh: revision 1.2
	tests/usr.bin/cc/t_tsan_signal_errno.sh: revision 1.2
	tests/usr.bin/cc/t_tsan_heap_use_after_free.sh: revision 1.1
	tests/usr.bin/c++/t_fuzzer_simple.sh: revision 1.2
	tests/usr.bin/cc/t_tsan_heap_use_after_free.sh: revision 1.2
	tests/usr.bin/c++/t_tsan_thread_leak.sh: revision 1.1
	tests/usr.bin/c++/t_tsan_thread_leak.sh: revision 1.2
	tests/usr.bin/cc/t_fuzzer_oom.sh: revision 1.1
	distrib/sets/lists/tests/mi: revision 1.819
	tests/usr.bin/cc/t_fuzzer_oom.sh: revision 1.2
	tests/usr.bin/cc/t_fuzzer_timeout.sh: revision 1.1
	tests/usr.bin/cc/t_msan_unpoison.sh: revision 1.1
	tests/usr.bin/cc/t_fuzzer_timeout.sh: revision 1.2
	tests/usr.bin/cc/t_msan_unpoison.sh: revision 1.2
	tests/usr.bin/c++/t_msan_heap.sh: revision 1.1
	tests/usr.bin/cc/t_tsan_locked_mutex_destroy.sh: revision 1.1
	tests/usr.bin/c++/t_msan_heap.sh: revision 1.2
	tests/usr.bin/cc/t_tsan_locked_mutex_destroy.sh: revision 1.2
	tests/usr.bin/cc/Makefile: revision 1.8
	tests/usr.bin/c++/t_msan_free.sh: revision 1.1
	tests/usr.bin/c++/t_msan_unpoison.sh: revision 1.1
	tests/usr.bin/c++/t_msan_free.sh: revision 1.2
	tests/usr.bin/c++/t_msan_unpoison.sh: revision 1.2
	tests/usr.bin/c++/t_tsan_heap_use_after_free.sh: revision 1.1
	tests/usr.bin/cc/t_tsan_lock_order_inversion.sh: revision 1.1
	tests/usr.bin/c++/t_tsan_heap_use_after_free.sh: revision 1.2
	tests/usr.bin/c++/t_msan_poison.sh: revision 1.1
	tests/usr.bin/c++/t_msan_partial_poison.sh: revision 1.1
	tests/usr.bin/cc/t_tsan_lock_order_inversion.sh: revision 1.2
	tests/usr.bin/c++/t_msan_poison.sh: revision 1.2
	tests/usr.bin/c++/t_msan_partial_poison.sh: revision 1.2
	tests/usr.bin/c++/t_msan_realloc.sh: revision 1.1
	tests/usr.bin/cc/t_msan_shadow.sh: revision 1.1
	tests/usr.bin/cc/t_msan_partial_poison.sh: revision 1.1
	tests/usr.bin/c++/t_msan_realloc.sh: revision 1.2
	tests/usr.bin/c++/t_msan_allocated_memory.sh: revision 1.1
	tests/usr.bin/cc/t_msan_shadow.sh: revision 1.2
	tests/usr.bin/cc/t_msan_partial_poison.sh: revision 1.2
	tests/usr.bin/c++/t_msan_allocated_memory.sh: revision 1.2
	tests/usr.bin/cc/t_msan_free.sh: revision 1.1
	tests/usr.bin/cc/t_msan_free.sh: revision 1.2
	tests/usr.bin/c++/t_tsan_locked_mutex_destroy.sh: revision 1.1
	tests/usr.bin/c++/t_fuzzer_timeout.sh: revision 1.1
	tests/usr.bin/cc/t_msan_heap.sh: revision 1.1
	tests/usr.bin/c++/t_tsan_locked_mutex_destroy.sh: revision 1.2
	tests/usr.bin/c++/t_fuzzer_timeout.sh: revision 1.2
	tests/usr.bin/cc/t_tsan_thread_leak.sh: revision 1.1
	tests/usr.bin/cc/t_msan_heap.sh: revision 1.2
	tests/usr.bin/cc/t_tsan_thread_leak.sh: revision 1.2
	tests/usr.bin/cc/t_tsan_data_race.sh: revision 1.1
	tests/usr.bin/cc/t_tsan_data_race.sh: revision 1.2
	tests/usr.bin/c++/t_tsan_lock_order_inversion.sh: revision 1.1
	tests/usr.bin/c++/t_tsan_signal_errno.sh: revision 1.1
	tests/usr.bin/c++/t_tsan_lock_order_inversion.sh: revision 1.2
	tests/usr.bin/c++/Makefile: revision 1.12
	tests/usr.bin/c++/t_tsan_signal_errno.sh: revision 1.2
	tests/usr.bin/cc/t_msan_check_mem.sh: revision 1.1
	tests/usr.bin/cc/t_msan_check_mem.sh: revision 1.2
	tests/usr.bin/cc/t_msan_realloc.sh: revision 1.1
	tests/usr.bin/c++/t_tsan_vptr_race.sh: revision 1.1
	tests/usr.bin/cc/t_msan_realloc.sh: revision 1.2
	tests/usr.bin/c++/t_tsan_vptr_race.sh: revision 1.2
	tests/usr.bin/c++/t_msan_shadow.sh: revision 1.1
	tests/usr.bin/c++/t_msan_shadow.sh: revision 1.2
	tests/usr.bin/c++/t_msan_stack.sh: revision 1.1
	tests/usr.bin/c++/t_tsan_data_race.sh: revision 1.1
	tests/usr.bin/c++/t_msan_stack.sh: revision 1.2
	tests/usr.bin/cc/t_fuzzer_simple.sh: revision 1.1
	tests/usr.bin/c++/t_tsan_data_race.sh: revision 1.2
	tests/usr.bin/cc/t_fuzzer_simple.sh: revision 1.2
	tests/usr.bin/c++/t_msan_check_mem.sh: revision 1.1
	tests/usr.bin/cc/t_msan_stack.sh: revision 1.1
	tests/usr.bin/c++/t_msan_check_mem.sh: revision 1.2
	tests/usr.bin/cc/t_msan_stack.sh: revision 1.2
	tests/usr.bin/cc/t_msan_allocated_memory.sh: revision 1.1

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.

 -

Define target_not_supported_body() in TSan, MSan and libFuzzer tests


(martin)
diff -r1.818 -r1.818.2.1 src/distrib/sets/lists/tests/mi
diff -r1.11 -r1.11.2.1 src/tests/usr.bin/c++/Makefile
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_fuzzer_oom.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_fuzzer_simple.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_fuzzer_timeout.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_msan_allocated_memory.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_msan_check_mem.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_msan_free.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_msan_heap.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_msan_partial_poison.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_msan_poison.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_msan_realloc.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_msan_shadow.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_msan_stack.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_msan_unpoison.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_tsan_data_race.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_tsan_heap_use_after_free.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_tsan_lock_order_inversion.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_tsan_locked_mutex_destroy.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_tsan_signal_errno.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_tsan_thread_leak.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/c++/t_tsan_vptr_race.sh
diff -r1.7 -r1.7.2.1 src/tests/usr.bin/cc/Makefile
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_fuzzer_oom.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_fuzzer_simple.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_fuzzer_timeout.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_msan_allocated_memory.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_msan_check_mem.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_msan_free.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_msan_heap.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_msan_partial_poison.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_msan_poison.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_msan_realloc.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_msan_shadow.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_msan_stack.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_msan_unpoison.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_tsan_data_race.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_tsan_heap_use_after_free.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_tsan_lock_order_inversion.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_tsan_locked_mutex_destroy.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_tsan_signal_errno.sh
diff -r0 -r1.2.2.2 src/tests/usr.bin/cc/t_tsan_thread_leak.sh

cvs diff -r1.818 -r1.818.2.1 src/distrib/sets/lists/tests/mi (expand / switch to context diff)
--- src/distrib/sets/lists/tests/mi 2019/07/28 13:49:23 1.818
+++ src/distrib/sets/lists/tests/mi 2019/08/29 16:45:26 1.818.2.1
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.818 2019/07/28 13:49:23 christos Exp $
+# $NetBSD: mi,v 1.818.2.1 2019/08/29 16:45:26 martin 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

cvs diff -r1.11 -r1.11.2.1 src/tests/usr.bin/c++/Makefile (expand / switch to context diff)
--- src/tests/usr.bin/c++/Makefile 2019/01/29 20:07:03 1.11
+++ src/tests/usr.bin/c++/Makefile 2019/08/29 16:45:26 1.11.2.1
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.11 2019/01/29 20:07:03 mgorny Exp $
+# $NetBSD: Makefile,v 1.11.2.1 2019/08/29 16:45:26 martin Exp $
 
 .include <bsd.own.mk>
 
@@ -28,6 +28,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

File Added: src/tests/usr.bin/c++/t_fuzzer_oom.sh
# 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 <stddef.h>
#include <stdint.h>
#include <stdlib.h>

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 <stddef.h>
#include <stdint.h>
#include <stdlib.h>

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 <stddef.h>
#include <stdint.h>
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 <stddef.h>
#include <stdint.h>
#include <stdlib.h>

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 <stddef.h>
#include <stdint.h>
#include <stdlib.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_fuzzer_simple.sh
# 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 <stdlib.h>
#include <stdio.h>
#include <stdint.h>

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 <stdlib.h>
#include <stdio.h>
#include <stdint.h>

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 <stddef.h>
#include <stdint.h>
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 <stdlib.h>
#include <stdio.h>
#include <stdint.h>

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 <stdlib.h>
#include <stdio.h>
#include <stdint.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_fuzzer_timeout.sh
# 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 <stddef.h>
#include <stdint.h>

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 <stddef.h>
#include <stdint.h>

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 <stddef.h>
#include <stdint.h>
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 <stddef.h>
#include <stdint.h>

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 <stddef.h>
#include <stdint.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_msan_allocated_memory.sh
# 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 <stdio.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <stdio.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <sanitizer/msan_interface.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_msan_check_mem.sh
# 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 <sanitizer/msan_interface.h>
#include <stdlib.h>

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 <sanitizer/msan_interface.h>
#include <stdlib.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <sanitizer/msan_interface.h>
#include <stdlib.h>

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 <sanitizer/msan_interface.h>
#include <stdlib.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_msan_free.sh
# 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 <stdlib.h>
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 <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <stdlib.h>
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 <stdlib.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_msan_heap.sh
# 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 <stdlib.h>
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 <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <stdlib.h>
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 <stdlib.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_msan_partial_poison.sh
# 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 <stdint.h>
#include <sanitizer/msan_interface.h>

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 <stdint.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <stdint.h>
#include <sanitizer/msan_interface.h>

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 <stdint.h>
#include <sanitizer/msan_interface.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_msan_poison.sh
# 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 <sanitizer/msan_interface.h>

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 <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <sanitizer/msan_interface.h>

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 <sanitizer/msan_interface.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_msan_realloc.sh
# 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 <stdlib.h>
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 <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <stdlib.h>
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 <stdlib.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_msan_shadow.sh
# 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 <stdio.h>
#include <stdlib.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <stdio.h>
#include <stdlib.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
#include <sanitizer/msan_interface.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_msan_stack.sh
# 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 <stdlib.h>
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 <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <stdlib.h>
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 <stdlib.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_msan_unpoison.sh
# 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 <sanitizer/msan_interface.h>

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 <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <sanitizer/msan_interface.h>

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 <sanitizer/msan_interface.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_tsan_data_race.sh
# 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 <pthread.h>
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 <pthread.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <pthread.h>
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 <pthread.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_tsan_heap_use_after_free.sh
# 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 <pthread.h>
#include <stdlib.h>

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 <pthread.h>
#include <stdlib.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <pthread.h>
#include <stdlib.h>

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 <pthread.h>
#include <stdlib.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_tsan_lock_order_inversion.sh
# 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.h>

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.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <pthread.h>

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.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_tsan_locked_mutex_destroy.sh
# 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 <pthread.h>
#include <stdlib.h>

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 <pthread.h>
#include <stdlib.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <pthread.h>
#include <stdlib.h>

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 <pthread.h>
#include <stdlib.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_tsan_signal_errno.sh
# 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 <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>

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 <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>

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 <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_tsan_thread_leak.sh
# 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 <pthread.h>
#include <unistd.h>

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 <pthread.h>
#include <unistd.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <pthread.h>
#include <unistd.h>

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 <pthread.h>
#include <unistd.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/c++/t_tsan_vptr_race.sh
# 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.h>
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.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.cc << EOF
#include <pthread.h>
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.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

cvs diff -r1.7 -r1.7.2.1 src/tests/usr.bin/cc/Makefile (expand / switch to context diff)
--- src/tests/usr.bin/cc/Makefile 2019/02/09 00:12:14 1.7
+++ src/tests/usr.bin/cc/Makefile 2019/08/29 16:45:25 1.7.2.1
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.7 2019/02/09 00:12:14 mrg Exp $
+# $NetBSD: Makefile,v 1.7.2.1 2019/08/29 16:45:25 martin Exp $
 
 .include <bsd.own.mk>
 
@@ -24,6 +24,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

File Added: src/tests/usr.bin/cc/t_fuzzer_oom.sh
# 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 <stddef.h>
#include <stdint.h>
#include <stdlib.h>

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 <stddef.h>
#include <stdint.h>
#include <stdlib.h>

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 <stddef.h>
#include <stdint.h>
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 <stddef.h>
#include <stdint.h>
#include <stdlib.h>

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 <stddef.h>
#include <stdint.h>
#include <stdlib.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_fuzzer_simple.sh
# 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 <stdlib.h>
#include <stdio.h>
#include <stdint.h>

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 <stdlib.h>
#include <stdio.h>
#include <stdint.h>

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 <stddef.h>
#include <stdint.h>
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 <stdlib.h>
#include <stdio.h>
#include <stdint.h>

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 <stdlib.h>
#include <stdio.h>
#include <stdint.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_fuzzer_timeout.sh
# 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 <stddef.h>
#include <stdint.h>

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 <stddef.h>
#include <stdint.h>

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 <stddef.h>
#include <stdint.h>
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 <stddef.h>
#include <stdint.h>

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 <stddef.h>
#include <stdint.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_msan_allocated_memory.sh
# 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 <stdio.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <stdio.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <sanitizer/msan_interface.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_msan_check_mem.sh
# 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 <sanitizer/msan_interface.h>
#include <stdlib.h>

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 <sanitizer/msan_interface.h>
#include <stdlib.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <sanitizer/msan_interface.h>
#include <stdlib.h>

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 <sanitizer/msan_interface.h>
#include <stdlib.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_msan_free.sh
# 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 <stdlib.h>
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 <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <stdlib.h>
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 <stdlib.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_msan_heap.sh
# 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 <stdlib.h>
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 <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <stdlib.h>
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 <stdlib.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_msan_partial_poison.sh
# 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 <stdint.h>
#include <sanitizer/msan_interface.h>

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 <stdint.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <stdint.h>
#include <sanitizer/msan_interface.h>

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 <stdint.h>
#include <sanitizer/msan_interface.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_msan_poison.sh
# 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 <sanitizer/msan_interface.h>

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 <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <sanitizer/msan_interface.h>

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 <sanitizer/msan_interface.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_msan_realloc.sh
# 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 <stdlib.h>
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 <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <stdlib.h>
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 <stdlib.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_msan_shadow.sh
# 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 <stdio.h>
#include <stdlib.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <stdio.h>
#include <stdlib.h>
#include <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
#include <sanitizer/msan_interface.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_msan_stack.sh
# 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 <stdlib.h>
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 <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <stdlib.h>
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 <stdlib.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_msan_unpoison.sh
# 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 <sanitizer/msan_interface.h>

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 <sanitizer/msan_interface.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <sanitizer/msan_interface.h>

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 <sanitizer/msan_interface.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_tsan_data_race.sh
# 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 <pthread.h>
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 <pthread.h>
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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <pthread.h>
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 <pthread.h>
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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_tsan_heap_use_after_free.sh
# 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 <pthread.h>
#include <stdlib.h>

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 <pthread.h>
#include <stdlib.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <pthread.h>
#include <stdlib.h>

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 <pthread.h>
#include <stdlib.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_tsan_lock_order_inversion.sh
# 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.h>

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.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <pthread.h>

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.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_tsan_locked_mutex_destroy.sh
# 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 <pthread.h>
#include <stdlib.h>

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 <pthread.h>
#include <stdlib.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <pthread.h>
#include <stdlib.h>

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 <pthread.h>
#include <stdlib.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_tsan_signal_errno.sh
# 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 <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>

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 <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>

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 <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}

File Added: src/tests/usr.bin/cc/t_tsan_thread_leak.sh
# 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 <pthread.h>
#include <unistd.h>

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 <pthread.h>
#include <unistd.h>

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 <stdio.h>
#include <stdlib.h>
int help(int);
int main(int argc, char **argv) {return help(argc);}
EOF

	cat > pic.c << EOF
#include <pthread.h>
#include <unistd.h>

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 <pthread.h>
#include <unistd.h>

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"
}

target_not_supported_body()
{
	atf_skip "Target is not supported"
}

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
}