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:
parent
14adb160be
commit
f0720e6929
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue