1# $NetBSD: asan_common.subr,v 1.2 2019/01/29 20:07:03 mgorny Exp $ 2# 3# Copyright (c) 2018, 2019 The NetBSD Foundation, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27 28SUPPORT='n' 29test_target() { 30 if uname -m | grep -q "amd64"; then 31 SUPPORT='y' 32 fi 33 34 if uname -m | grep -q "i386"; then 35 SUPPORT='y' 36 fi 37} 38 39atf_test_case target_not_supported 40target_not_supported_head() 41{ 42 atf_set "descr" "Test forced skip" 43} 44 45target_not_supported_body() 46{ 47 atf_skip "Target is not supported" 48} 49 50# Add a new test case, with head & body. 51# asan_test_case <test-name> <description> <check-output> 52asan_test_case() { 53 atf_test_case "$1" 54 eval "$1_head() { 55 atf_set 'descr' 'compile and run \"$2\"' 56 atf_set 'require.progs' 'c++ paxctl' 57 }" 58 59 atf_test_case "$1_profile" 60 eval "$1_head() { 61 atf_set 'descr' 'compile and run \"$2\" with profiling option' 62 atf_set 'require.progs' 'c++ paxctl' 63 }" 64 65 atf_test_case "$1_pic" 66 eval "$1_head() { 67 atf_set 'descr' 'compile and run PIC \"$2\"' 68 atf_set 'require.progs' 'c++ paxctl' 69 }" 70 71 atf_test_case "$1_pie" 72 eval "$1_head() { 73 atf_set 'descr' 'compile and run position independent (PIE) \"$2\"' 74 atf_set 'require.progs' 'c++ paxctl' 75 }" 76 77 atf_test_case "${1}32" 78 eval "$1_head() { 79 atf_set 'descr' 'compile and run \"$2\" for/in netbsd32 emulation' 80 atf_set 'require.progs' 'c++ paxctl file diff cat' 81 }" 82 83 eval "$1_body() { 84 echo \"\$ASAN_CODE\" > test.cpp 85 c++ -fsanitize=address -o test test.cpp 86 paxctl +a test 87 atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./test 88 } 89 90 $1_profile_body() { 91 echo \"\$ASAN_CODE\" > test.cpp 92 c++ -fsanitize=address -o test -pg test.cpp 93 paxctl +a test 94 atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./test 95 } 96 97 $1_pic_body() { 98 echo \"\$ASAN_CODE\" > test.cpp 99 c++ -DPIC_FOO -fsanitize=address -fPIC -shared -o libtest.so test.cpp 100 c++ -DPIC_MAIN -o test test.cpp -fsanitize=address -L. -ltest 101 paxctl +a test 102 103 export LD_LIBRARY_PATH=. 104 atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./test 105 } 106 107 $1_pie_body() { 108 # check whether this arch supports -pice 109 if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then 110 atf_set_skip 'c++ -pie not supported on this architecture' 111 fi 112 echo \"\$ASAN_CODE\" > test.cpp 113 c++ -fsanitize=address -o test -fpie -pie test.cpp 114 paxctl +a test 115 atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./test 116 } 117 118 ${1}32_body() { 119 # check whether this arch is 64bit 120 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 121 atf_skip 'this is not a 64 bit architecture' 122 fi 123 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 124 atf_skip 'c++ -m32 not supported on this architecture' 125 else 126 if fgrep -q _LP64 ./def32; then 127 atf_fail 'c++ -m32 does not generate netbsd32 binaries' 128 fi 129 fi 130 131 echo \"\$ASAN_CODE\" > test.cpp 132 c++ -fsanitize=address -o df32 -m32 test.cpp 133 c++ -fsanitize=address -o df64 test.cpp 134 file -b ./df32 > ./ftype32 135 file -b ./df64 > ./ftype64 136 if diff ./ftype32 ./ftype64 >/dev/null; then 137 atf_fail 'generated binaries do not differ' 138 fi 139 echo '32bit binaries on this platform are:' 140 cat ./ftype32 141 echo 'While native (64bit) binaries are:' 142 cat ./ftype64 143 paxctl +a df32 144 atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./df32 145 146# and another test with profile 32bit binaries 147 c++ -fsanitize=address -o test -pg -m32 test.cpp 148 paxctl +a test 149 atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./test 150 }" 151} 152 153asan_add_test_cases() { 154 test_target 155 test $SUPPORT = 'n' && { 156 atf_add_test_case target_not_supported 157 return 0 158 } 159 160 atf_add_test_case "$1" 161# atf_add_test_case "$1_profile" 162 atf_add_test_case "$1_pic" 163 atf_add_test_case "$1_pie" 164# atf_add_test_case "${1}32" 165 # static option not supported 166 # -static and -fsanitize=address can't be used together for compilation 167 # (gcc version 5.4.0 and clang 7.1) tested on April 2nd 2018. 168} 169