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.
This commit is contained in:
kamil 2019-08-18 20:15:58 +00:00
parent 14adb160be
commit f0720e6929
42 changed files with 7085 additions and 3 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.818 2019/07/28 13:49:23 christos Exp $
# $NetBSD: mi,v 1.819 2019/08/18 20:15:59 kamil Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -3840,6 +3840,26 @@
./usr/tests/usr.bin/c++/t_ubsan_int_neg_overflow tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_ubsan_int_sub_overflow tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_ubsan_vla_out_of_bounds tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_msan_allocated_memory tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_msan_check_mem tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_msan_free tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_msan_heap tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_msan_partial_poison tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_msan_poison tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_msan_realloc tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_msan_shadow tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_msan_stack tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_msan_unpoison tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_tsan_data_race tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_tsan_heap_use_after_free tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_tsan_lock_order_inversion tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_tsan_locked_mutex_destroy tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_tsan_signal_errno tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_tsan_thread_leak tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_tsan_vptr_race tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_fuzzer_oom tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_fuzzer_simple tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/c++/t_fuzzer_timeout tests-usr.bin-tests compattestfile,atf,cxx
./usr/tests/usr.bin/cc tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/Atffile tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua
@ -3856,6 +3876,25 @@
./usr/tests/usr.bin/cc/t_ubsan_int_neg_overflow tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_ubsan_int_sub_overflow tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_ubsan_vla_out_of_bounds tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_msan_allocated_memory tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_msan_check_mem tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_msan_free tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_msan_heap tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_msan_partial_poison tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_msan_poison tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_msan_realloc tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_msan_shadow tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_msan_stack tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_msan_unpoison tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_tsan_data_race tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_tsan_heap_use_after_free tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_tsan_lock_order_inversion tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_tsan_locked_mutex_destroy tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_tsan_signal_errno tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_tsan_thread_leak tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_fuzzer_oom tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_fuzzer_simple tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cc/t_fuzzer_timeout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cmp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cmp/Atffile tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/cmp/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.11 2019/01/29 20:07:03 mgorny Exp $
# $NetBSD: Makefile,v 1.12 2019/08/18 20:15:58 kamil Exp $
.include <bsd.own.mk>
@ -29,6 +29,29 @@ TESTS_SH+= t_hello
TESTS_SH+= t_pthread_once
TESTS_SH+= t_static_destructor
TESTS_SH+= t_fuzzer_oom
TESTS_SH+= t_fuzzer_simple
TESTS_SH+= t_fuzzer_timeout
TESTS_SH+= t_msan_allocated_memory
TESTS_SH+= t_msan_check_mem
TESTS_SH+= t_msan_free
TESTS_SH+= t_msan_heap
TESTS_SH+= t_msan_partial_poison
TESTS_SH+= t_msan_poison
TESTS_SH+= t_msan_realloc
TESTS_SH+= t_msan_shadow
TESTS_SH+= t_msan_stack
TESTS_SH+= t_msan_unpoison
TESTS_SH+= t_tsan_data_race
TESTS_SH+= t_tsan_heap_use_after_free
TESTS_SH+= t_tsan_lock_order_inversion
TESTS_SH+= t_tsan_locked_mutex_destroy
TESTS_SH+= t_tsan_signal_errno
TESTS_SH+= t_tsan_thread_leak
TESTS_SH+= t_tsan_vptr_race
.for test in ${ASAN_TESTS}
TESTS_SH_SRC_${test}= asan_common.subr ${test}.sh
.endfor

View File

@ -0,0 +1,166 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case oom
oom_head() {
atf_set "descr" "Test thread sanitizer for out-of-memory condition"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case oom_profile
oom_profile_head() {
atf_set "descr" "Test thread sanitizer for out-of-memory with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case oom_pic
oom_pic_head() {
atf_set "descr" "Test thread sanitizer for out-of-memory with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case oom_pie
oom_pie_head() {
atf_set "descr" "Test thread sanitizer for out-of-memory with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
oom_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,182 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case simple
simple_head() {
atf_set "descr" "Test thread sanitizer for error exit condition"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case simple_profile
simple_profile_head() {
atf_set "descr" "Test thread sanitizer for simple with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case simple_pic
simple_pic_head() {
atf_set "descr" "Test thread sanitizer for simple with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case simple_pie
simple_pie_head() {
atf_set "descr" "Test thread sanitizer for simple with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
simple_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,162 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case timeout
timeout_head() {
atf_set "descr" "Test thread sanitizer for timeout condition"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case timeout_profile
timeout_profile_head() {
atf_set "descr" "Test thread sanitizer for timeout with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case timeout_pic
timeout_pic_head() {
atf_set "descr" "Test thread sanitizer for timeout with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case timeout_pie
timeout_pie_head() {
atf_set "descr" "Test thread sanitizer for timeout with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
timeout_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,163 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case allocated_memory
allocated_memory_head() {
atf_set "descr" "Test memory sanitizer for __msan_allocated_memory interface"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case allocated_memory_profile
allocated_memory_profile_head() {
atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case allocated_memory_pic
allocated_memory_pic_head() {
atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case allocated_memory_pie
allocated_memory_pie_head() {
atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
allocated_memory_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,167 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case check_mem
check_mem_head() {
atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized interface"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case check_mem_profile
check_mem_profile_head() {
atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case check_mem_pic
check_mem_pic_head() {
atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case check_mem_pie
check_mem_pie_head() {
atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
check_mem_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,159 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case free
free_head() {
atf_set "descr" "Test memory sanitizer for use-after-free case"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case free_profile
free_profile_head() {
atf_set "descr" "Test memory sanitizer for use-after-free with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case free_pic
free_pic_head() {
atf_set "descr" "Test memory sanitizer for use-after-free with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case free_pie
free_pie_head() {
atf_set "descr" "Test memory sanitizer for use-after-free with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
free_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,139 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case heap
heap_head() {
atf_set "descr" "Test memory sanitizer for uninitialized heap value case"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case heap_profile
heap_profile_head() {
atf_set "descr" "Test memory sanitizer for uninitialized heap value with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case heap_pic
heap_pic_head() {
atf_set "descr" "Test memory sanitizer for uninitialized heap value with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case heap_pie
heap_pie_head() {
atf_set "descr" "Test memory sanitizer for uninitialized heap value with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
heap_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,171 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case partial_poison
partial_poison_head() {
atf_set "descr" "Test memory sanitizer for __msan_partial_poison interface"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case partial_poison_profile
partial_poison_profile_head() {
atf_set "descr" "Test memory sanitizer for __msan_partial_poison with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case partial_poison_pic
partial_poison_pic_head() {
atf_set "descr" "Test memory sanitizer for __msan_partial_poison with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case partial_poison_pie
partial_poison_pie_head() {
atf_set "descr" "Test memory sanitizer for __msan_partial_poison with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
partial_poison_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,167 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case poison
poison_head() {
atf_set "descr" "Test memory sanitizer for __msan_poison interface"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case poison_profile
poison_profile_head() {
atf_set "descr" "Test memory sanitizer for __msan_poison with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case poison_pic
poison_pic_head() {
atf_set "descr" "Test memory sanitizer for __msan_poison with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case poison_pie
poison_pie_head() {
atf_set "descr" "Test memory sanitizer for __msan_poison with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
poison_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,163 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case realloc
realloc_head() {
atf_set "descr" "Test memory sanitizer for realloc"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case realloc_profile
realloc_profile_head() {
atf_set "descr" "Test memory sanitizer for realloc with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case realloc_pic
realloc_pic_head() {
atf_set "descr" "Test memory sanitizer for realloc with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case realloc_pie
realloc_pie_head() {
atf_set "descr" "Test memory sanitizer for realloc with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
realloc_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,183 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case shadow
shadow_head() {
atf_set "descr" "Test memory sanitizer for shadow interface"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case shadow_profile
shadow_profile_head() {
atf_set "descr" "Test memory sanitizer for shadow with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case shadow_pic
shadow_pic_head() {
atf_set "descr" "Test memory sanitizer for shadow with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case shadow_pie
shadow_pie_head() {
atf_set "descr" "Test memory sanitizer for shadow with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
shadow_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,159 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case stack
stack_head() {
atf_set "descr" "Test memory sanitizer for free-stack-pointer case"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case stack_profile
stack_profile_head() {
atf_set "descr" "Test memory sanitizer for free-stack-pointer with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case stack_pic
stack_pic_head() {
atf_set "descr" "Test memory sanitizer for free-stack-pointer with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case stack_pie
stack_pie_head() {
atf_set "descr" "Test memory sanitizer for free-stack-pointer with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
stack_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,183 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case unpoison
unpoison_head() {
atf_set "descr" "Test memory sanitizer for __msan_unpoison interface"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case unpoison_profile
unpoison_profile_head() {
atf_set "descr" "Test memory sanitizer for __msan_unpoison with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case unpoison_pic
unpoison_pic_head() {
atf_set "descr" "Test memory sanitizer for __msan_unpoison with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case unpoison_pie
unpoison_pie_head() {
atf_set "descr" "Test memory sanitizer for __msan_unpoison with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
unpoison_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,180 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case data_race
data_race_head() {
atf_set "descr" "Test thread sanitizer for data race condition"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case data_race_profile
data_race_profile_head() {
atf_set "descr" "Test thread sanitizer for data race with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case data_race_pic
data_race_pic_head() {
atf_set "descr" "Test thread sanitizer for data race with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case data_race_pie
data_race_pie_head() {
atf_set "descr" "Test thread sanitizer for data race with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
data_race_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,216 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case heap_use_after_free
heap_use_after_free_head() {
atf_set "descr" "Test thread sanitizer for use-after-free condition"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case heap_use_after_free_profile
heap_use_after_free_profile_head() {
atf_set "descr" "Test thread sanitizer for use-after-free with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case heap_use_after_free_pic
heap_use_after_free_pic_head() {
atf_set "descr" "Test thread sanitizer for use-after-free with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case heap_use_after_free_pie
heap_use_after_free_pie_head() {
atf_set "descr" "Test thread sanitizer for use-after-free with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
heap_use_after_free_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,200 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case lock_order_inversion
lock_order_inversion_head() {
atf_set "descr" "Test thread sanitizer for lock order inversion condition"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case lock_order_inversion_profile
lock_order_inversion_profile_head() {
atf_set "descr" "Test thread sanitizer for lock order inversion with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case lock_order_inversion_pic
lock_order_inversion_pic_head() {
atf_set "descr" "Test thread sanitizer for lock order inversion with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case lock_order_inversion_pie
lock_order_inversion_pie_head() {
atf_set "descr" "Test thread sanitizer for lock order inversion with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
lock_order_inversion_body(){
cat > test.cc << EOF
#include <pthread.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"
}
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
}

View File

@ -0,0 +1,216 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case locked_mutex_destroy
locked_mutex_destroy_head() {
atf_set "descr" "Test thread sanitizer for destroying locked mutex condition"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case locked_mutex_destroy_profile
locked_mutex_destroy_profile_head() {
atf_set "descr" "Test thread sanitizer for destroying locked mutex with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case locked_mutex_destroy_pic
locked_mutex_destroy_pic_head() {
atf_set "descr" "Test thread sanitizer for destroying locked mutex with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case locked_mutex_destroy_pie
locked_mutex_destroy_pie_head() {
atf_set "descr" "Test thread sanitizer for destroying locked mutex with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
locked_mutex_destroy_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,204 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case signal_errno
signal_errno_head() {
atf_set "descr" "Test thread sanitizer for errno modification in signal condition"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case signal_errno_profile
signal_errno_profile_head() {
atf_set "descr" "Test thread sanitizer for errno modification in signal with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case signal_errno_pic
signal_errno_pic_head() {
atf_set "descr" "Test thread sanitizer for errno modification in signal with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case signal_errno_pie
signal_errno_pie_head() {
atf_set "descr" "Test thread sanitizer for errno modification in signal with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
signal_errno_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,204 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case thread_leak
thread_leak_head() {
atf_set "descr" "Test thread sanitizer for thread leak condition"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case thread_leak_profile
thread_leak_profile_head() {
atf_set "descr" "Test thread sanitizer for thread leak with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case thread_leak_pic
thread_leak_pic_head() {
atf_set "descr" "Test thread sanitizer for thread leak with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case thread_leak_pie
thread_leak_pie_head() {
atf_set "descr" "Test thread sanitizer for thread leak with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
thread_leak_body(){
cat > test.cc << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,228 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v c++ >/dev/null 2>&1 && \
! echo __clang__ | c++ -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | c++ -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case vptr_race
vptr_race_head() {
atf_set "descr" "Test thread sanitizer for vptr race condition"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case vptr_race_profile
vptr_race_profile_head() {
atf_set "descr" "Test thread sanitizer for vptr race with profiling option"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case vptr_race_pic
vptr_race_pic_head() {
atf_set "descr" "Test thread sanitizer for vptr race with position independent code (PIC) flag"
atf_set "require.progs" "c++ paxctl"
}
atf_test_case vptr_race_pie
vptr_race_pie_head() {
atf_set "descr" "Test thread sanitizer for vptr race with position independent execution (PIE) flag"
atf_set "require.progs" "c++ paxctl"
}
vptr_race_body(){
cat > test.cc << EOF
#include <pthread.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"
}
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
}

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.7 2019/02/09 00:12:14 mrg Exp $
# $NetBSD: Makefile,v 1.8 2019/08/18 20:15:58 kamil Exp $
.include <bsd.own.mk>
@ -25,6 +25,28 @@ TESTS_SH+= $(UBSAN_TESTS)
TESTS_SH+= t_hello
TESTS_SH+= t_libgomp
TESTS_SH+= t_fuzzer_oom
TESTS_SH+= t_fuzzer_simple
TESTS_SH+= t_fuzzer_timeout
TESTS_SH+= t_msan_allocated_memory
TESTS_SH+= t_msan_check_mem
TESTS_SH+= t_msan_free
TESTS_SH+= t_msan_heap
TESTS_SH+= t_msan_partial_poison
TESTS_SH+= t_msan_poison
TESTS_SH+= t_msan_realloc
TESTS_SH+= t_msan_shadow
TESTS_SH+= t_msan_stack
TESTS_SH+= t_msan_unpoison
TESTS_SH+= t_tsan_data_race
TESTS_SH+= t_tsan_heap_use_after_free
TESTS_SH+= t_tsan_lock_order_inversion
TESTS_SH+= t_tsan_locked_mutex_destroy
TESTS_SH+= t_tsan_signal_errno
TESTS_SH+= t_tsan_thread_leak
.for test in ${ASAN_TESTS}
TESTS_SH_SRC_${test}= asan_common.subr ${test}.sh
.endfor

View File

@ -0,0 +1,166 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case oom
oom_head() {
atf_set "descr" "Test thread sanitizer for out-of-memory condition"
atf_set "require.progs" "cc paxctl"
}
atf_test_case oom_profile
oom_profile_head() {
atf_set "descr" "Test thread sanitizer for out-of-memory with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case oom_pic
oom_pic_head() {
atf_set "descr" "Test thread sanitizer for out-of-memory with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case oom_pie
oom_pie_head() {
atf_set "descr" "Test thread sanitizer for out-of-memory with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
oom_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,182 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case simple
simple_head() {
atf_set "descr" "Test thread sanitizer for error exit condition"
atf_set "require.progs" "cc paxctl"
}
atf_test_case simple_profile
simple_profile_head() {
atf_set "descr" "Test thread sanitizer for simple with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case simple_pic
simple_pic_head() {
atf_set "descr" "Test thread sanitizer for simple with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case simple_pie
simple_pie_head() {
atf_set "descr" "Test thread sanitizer for simple with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
simple_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,162 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case timeout
timeout_head() {
atf_set "descr" "Test thread sanitizer for timeout condition"
atf_set "require.progs" "cc paxctl"
}
atf_test_case timeout_profile
timeout_profile_head() {
atf_set "descr" "Test thread sanitizer for timeout with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case timeout_pic
timeout_pic_head() {
atf_set "descr" "Test thread sanitizer for timeout with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case timeout_pie
timeout_pie_head() {
atf_set "descr" "Test thread sanitizer for timeout with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
timeout_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,164 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case allocated_memory
allocated_memory_head() {
atf_set "descr" "Test memory sanitizer for __msan_allocated_memory interface"
atf_set "require.progs" "cc paxctl"
}
atf_test_case allocated_memory_profile
allocated_memory_profile_head() {
atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case allocated_memory_pic
allocated_memory_pic_head() {
atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case allocated_memory_pie
allocated_memory_pie_head() {
atf_set "descr" "Test memory sanitizer for __msan_allocated_memory with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
allocated_memory_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,168 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case check_mem
check_mem_head() {
atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized interface"
atf_set "require.progs" "cc paxctl"
}
atf_test_case check_mem_profile
check_mem_profile_head() {
atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case check_mem_pic
check_mem_pic_head() {
atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case check_mem_pie
check_mem_pie_head() {
atf_set "descr" "Test memory sanitizer for __msan_check_mem_is_initialized with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
check_mem_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,159 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case free
free_head() {
atf_set "descr" "Test memory sanitizer for use-after-free case"
atf_set "require.progs" "cc paxctl"
}
atf_test_case free_profile
free_profile_head() {
atf_set "descr" "Test memory sanitizer for use-after-free with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case free_pic
free_pic_head() {
atf_set "descr" "Test memory sanitizer for use-after-free with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case free_pie
free_pie_head() {
atf_set "descr" "Test memory sanitizer for use-after-free with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
free_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,139 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case heap
heap_head() {
atf_set "descr" "Test memory sanitizer for uninitialized heap value case"
atf_set "require.progs" "cc paxctl"
}
atf_test_case heap_profile
heap_profile_head() {
atf_set "descr" "Test memory sanitizer for uninitialized heap value with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case heap_pic
heap_pic_head() {
atf_set "descr" "Test memory sanitizer for uninitialized heap value with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case heap_pie
heap_pie_head() {
atf_set "descr" "Test memory sanitizer for uninitialized heap value with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
heap_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,171 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case partial_poison
partial_poison_head() {
atf_set "descr" "Test memory sanitizer for __msan_partial_poison interface"
atf_set "require.progs" "cc paxctl"
}
atf_test_case partial_poison_profile
partial_poison_profile_head() {
atf_set "descr" "Test memory sanitizer for __msan_partial_poison with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case partial_poison_pic
partial_poison_pic_head() {
atf_set "descr" "Test memory sanitizer for __msan_partial_poison with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case partial_poison_pie
partial_poison_pie_head() {
atf_set "descr" "Test memory sanitizer for __msan_partial_poison with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
partial_poison_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,167 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case poison
poison_head() {
atf_set "descr" "Test memory sanitizer for __msan_poison interface"
atf_set "require.progs" "cc paxctl"
}
atf_test_case poison_profile
poison_profile_head() {
atf_set "descr" "Test memory sanitizer for __msan_poison with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case poison_pic
poison_pic_head() {
atf_set "descr" "Test memory sanitizer for __msan_poison with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case poison_pie
poison_pie_head() {
atf_set "descr" "Test memory sanitizer for __msan_poison with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
poison_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,163 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case realloc
realloc_head() {
atf_set "descr" "Test memory sanitizer for realloc"
atf_set "require.progs" "cc paxctl"
}
atf_test_case realloc_profile
realloc_profile_head() {
atf_set "descr" "Test memory sanitizer for realloc with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case realloc_pic
realloc_pic_head() {
atf_set "descr" "Test memory sanitizer for realloc with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case realloc_pie
realloc_pie_head() {
atf_set "descr" "Test memory sanitizer for realloc with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
realloc_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,183 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case shadow
shadow_head() {
atf_set "descr" "Test memory sanitizer for shadow interface"
atf_set "require.progs" "cc paxctl"
}
atf_test_case shadow_profile
shadow_profile_head() {
atf_set "descr" "Test memory sanitizer for shadow with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case shadow_pic
shadow_pic_head() {
atf_set "descr" "Test memory sanitizer for shadow with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case shadow_pie
shadow_pie_head() {
atf_set "descr" "Test memory sanitizer for shadow with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
shadow_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,159 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case stack
stack_head() {
atf_set "descr" "Test memory sanitizer for free-stack-pointer case"
atf_set "require.progs" "cc paxctl"
}
atf_test_case stack_profile
stack_profile_head() {
atf_set "descr" "Test memory sanitizer for free-stack-pointer with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case stack_pic
stack_pic_head() {
atf_set "descr" "Test memory sanitizer for free-stack-pointer with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case stack_pie
stack_pie_head() {
atf_set "descr" "Test memory sanitizer for free-stack-pointer with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
stack_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,183 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case unpoison
unpoison_head() {
atf_set "descr" "Test memory sanitizer for __msan_unpoison interface"
atf_set "require.progs" "cc paxctl"
}
atf_test_case unpoison_profile
unpoison_profile_head() {
atf_set "descr" "Test memory sanitizer for __msan_unpoison with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case unpoison_pic
unpoison_pic_head() {
atf_set "descr" "Test memory sanitizer for __msan_unpoison with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case unpoison_pie
unpoison_pie_head() {
atf_set "descr" "Test memory sanitizer for __msan_unpoison with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
unpoison_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,180 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case data_race
data_race_head() {
atf_set "descr" "Test thread sanitizer for data race condition"
atf_set "require.progs" "cc paxctl"
}
atf_test_case data_race_profile
data_race_profile_head() {
atf_set "descr" "Test thread sanitizer for data race with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case data_race_pic
data_race_pic_head() {
atf_set "descr" "Test thread sanitizer for data race with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case data_race_pie
data_race_pie_head() {
atf_set "descr" "Test thread sanitizer for data race with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
data_race_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,216 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case heap_use_after_free
heap_use_after_free_head() {
atf_set "descr" "Test thread sanitizer for use-after-free condition"
atf_set "require.progs" "cc paxctl"
}
atf_test_case heap_use_after_free_profile
heap_use_after_free_profile_head() {
atf_set "descr" "Test thread sanitizer for use-after-free with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case heap_use_after_free_pic
heap_use_after_free_pic_head() {
atf_set "descr" "Test thread sanitizer for use-after-free with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case heap_use_after_free_pie
heap_use_after_free_pie_head() {
atf_set "descr" "Test thread sanitizer for use-after-free with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
heap_use_after_free_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,200 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case lock_order_inversion
lock_order_inversion_head() {
atf_set "descr" "Test thread sanitizer for lock order inversion condition"
atf_set "require.progs" "cc paxctl"
}
atf_test_case lock_order_inversion_profile
lock_order_inversion_profile_head() {
atf_set "descr" "Test thread sanitizer for lock order inversion with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case lock_order_inversion_pic
lock_order_inversion_pic_head() {
atf_set "descr" "Test thread sanitizer for lock order inversion with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case lock_order_inversion_pie
lock_order_inversion_pie_head() {
atf_set "descr" "Test thread sanitizer for lock order inversion with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
lock_order_inversion_body(){
cat > test.c << EOF
#include <pthread.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"
}
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
}

View File

@ -0,0 +1,216 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case locked_mutex_destroy
locked_mutex_destroy_head() {
atf_set "descr" "Test thread sanitizer for destroying locked mutex condition"
atf_set "require.progs" "cc paxctl"
}
atf_test_case locked_mutex_destroy_profile
locked_mutex_destroy_profile_head() {
atf_set "descr" "Test thread sanitizer for destroying locked mutex with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case locked_mutex_destroy_pic
locked_mutex_destroy_pic_head() {
atf_set "descr" "Test thread sanitizer for destroying locked mutex with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case locked_mutex_destroy_pie
locked_mutex_destroy_pie_head() {
atf_set "descr" "Test thread sanitizer for destroying locked mutex with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
locked_mutex_destroy_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,204 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case signal_errno
signal_errno_head() {
atf_set "descr" "Test thread sanitizer for errno modification in signal condition"
atf_set "require.progs" "cc paxctl"
}
atf_test_case signal_errno_profile
signal_errno_profile_head() {
atf_set "descr" "Test thread sanitizer for errno modification in signal with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case signal_errno_pic
signal_errno_pic_head() {
atf_set "descr" "Test thread sanitizer for errno modification in signal with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case signal_errno_pie
signal_errno_pie_head() {
atf_set "descr" "Test thread sanitizer for errno modification in signal with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
signal_errno_body(){
cat > test.c << EOF
#include <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"
}
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
}

View File

@ -0,0 +1,204 @@
# Copyright (c) 2018 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Yang Zheng.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
test_target()
{
SUPPORT='n'
if uname -m | grep -q "amd64" && command -v cc >/dev/null 2>&1 && \
! echo __clang__ | cc -E - | grep -q __clang__; then
# only clang with major version newer than 7 is supported
CLANG_MAJOR=`echo __clang_major__ | cc -E - | grep -o '^[[:digit:]]'`
if [ "$CLANG_MAJOR" -ge "7" ]; then
SUPPORT='y'
fi
fi
}
atf_test_case thread_leak
thread_leak_head() {
atf_set "descr" "Test thread sanitizer for thread leak condition"
atf_set "require.progs" "cc paxctl"
}
atf_test_case thread_leak_profile
thread_leak_profile_head() {
atf_set "descr" "Test thread sanitizer for thread leak with profiling option"
atf_set "require.progs" "cc paxctl"
}
atf_test_case thread_leak_pic
thread_leak_pic_head() {
atf_set "descr" "Test thread sanitizer for thread leak with position independent code (PIC) flag"
atf_set "require.progs" "cc paxctl"
}
atf_test_case thread_leak_pie
thread_leak_pie_head() {
atf_set "descr" "Test thread sanitizer for thread leak with position independent execution (PIE) flag"
atf_set "require.progs" "cc paxctl"
}
thread_leak_body(){
cat > test.c << EOF
#include <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"
}
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
}