Module Name: src Committed By: mgorny Date: Tue Jan 29 20:02:34 UTC 2019
Modified Files: src/tests/usr.bin/c++: Makefile t_asan_double_free.sh t_asan_global_buffer_overflow.sh t_asan_heap_overflow.sh t_asan_off_by_one.sh t_asan_poison.sh t_asan_uaf.sh Added Files: src/tests/usr.bin/c++: asan_common.subr Log Message: Move common ASAN test case code into asan_common.subr Reviewed by <kamil> To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/tests/usr.bin/c++/Makefile cvs rdiff -u -r0 -r1.1 src/tests/usr.bin/c++/asan_common.subr cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/c++/t_asan_double_free.sh \ src/tests/usr.bin/c++/t_asan_global_buffer_overflow.sh \ src/tests/usr.bin/c++/t_asan_heap_overflow.sh \ src/tests/usr.bin/c++/t_asan_off_by_one.sh \ src/tests/usr.bin/c++/t_asan_poison.sh \ src/tests/usr.bin/c++/t_asan_uaf.sh Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/usr.bin/c++/Makefile diff -u src/tests/usr.bin/c++/Makefile:1.9 src/tests/usr.bin/c++/Makefile:1.10 --- src/tests/usr.bin/c++/Makefile:1.9 Wed May 2 18:46:05 2018 +++ src/tests/usr.bin/c++/Makefile Tue Jan 29 20:02:34 2019 @@ -1,16 +1,19 @@ -# $NetBSD: Makefile,v 1.9 2018/05/02 18:46:05 kamil Exp $ +# $NetBSD: Makefile,v 1.10 2019/01/29 20:02:34 mgorny Exp $ .include <bsd.own.mk> TESTSDIR= ${TESTSBASE}/usr.bin/c++ +ASAN_TESTS= # +ASAN_TESTS+= t_asan_double_free +ASAN_TESTS+= t_asan_global_buffer_overflow +ASAN_TESTS+= t_asan_heap_overflow +ASAN_TESTS+= t_asan_off_by_one +ASAN_TESTS+= t_asan_poison +ASAN_TESTS+= t_asan_uaf + TESTS_SH= # -TESTS_SH+= t_asan_double_free -TESTS_SH+= t_asan_global_buffer_overflow -TESTS_SH+= t_asan_heap_overflow -TESTS_SH+= t_asan_off_by_one -TESTS_SH+= t_asan_poison -TESTS_SH+= t_asan_uaf +TESTS_SH+= $(ASAN_TESTS) TESTS_SH+= t_ubsan_int_add_overflow TESTS_SH+= t_ubsan_int_sub_overflow TESTS_SH+= t_ubsan_int_neg_overflow @@ -23,4 +26,8 @@ TESTS_SH+= t_hello TESTS_SH+= t_pthread_once TESTS_SH+= t_static_destructor +.for test in ${ASAN_TESTS} +TESTS_SH_SRC_${test}= asan_common.subr ${test}.sh +.endfor + .include <bsd.test.mk> Index: src/tests/usr.bin/c++/t_asan_double_free.sh diff -u src/tests/usr.bin/c++/t_asan_double_free.sh:1.2 src/tests/usr.bin/c++/t_asan_double_free.sh:1.3 --- src/tests/usr.bin/c++/t_asan_double_free.sh:1.2 Mon Jul 16 07:27:26 2018 +++ src/tests/usr.bin/c++/t_asan_double_free.sh Tue Jan 29 20:02:34 2019 @@ -1,6 +1,6 @@ -# $NetBSD: t_asan_double_free.sh,v 1.2 2018/07/16 07:27:26 kamil Exp $ +# $NetBSD: t_asan_double_free.sh,v 1.3 2019/01/29 20:02:34 mgorny Exp $ # -# Copyright (c) 2018 The NetBSD Foundation, Inc. +# Copyright (c) 2018, 2019 The NetBSD Foundation, Inc. # All rights reserved. # # This code is derived from software contributed to The NetBSD Foundation @@ -28,185 +28,22 @@ # POSSIBILITY OF SUCH DAMAGE. # -SUPPORT='n' -test_target() { - if uname -m | grep -q "amd64"; then - SUPPORT='y' - fi - - if uname -m | grep -q "i386"; then - SUPPORT='y' - fi -} - -atf_test_case double_free -double_free_head() { - atf_set "descr" "compile and run \"Double Free example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case double_free_profile -double_free_profile_head() { - atf_set "descr" "compile and run \"Double Free example\" with profiling option" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case double_free_pic -double_free_pic_head() { - atf_set "descr" "compile and run PIC \"Double Free example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case double_free_pie -double_free_pie_head() { - atf_set "descr" "compile and run position independent (PIE) \"Double Free example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case double_free32 -double_free32_head() { - atf_set "descr" "compile and run \"Double Free example\" for/in netbsd32 emulation" - atf_set "require.progs" "c++ paxctl file diff cat" -} - -atf_test_case target_not_supported -target_not_supported_head() -{ - atf_set "descr" "Test forced skip" -} - -double_free_body() { - cat > test.cpp << EOF +ASAN_CODE=' #include <stdlib.h> #include <string.h> #include <stdio.h> +void foo(int); +#ifndef PIC_MAIN void foo(int index) { char *x = (char*)malloc(10 * sizeof(char)); memset(x, 0, 10); free(x); free(x - index); } +#endif +#ifndef PIC_FOO int main(int argc, char **argv) { foo(argc - 1); printf("CHECK\n"); exit(0); } -EOF - c++ -fsanitize=address -o test test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"double-free" ./test -} +#endif +' -double_free_profile_body() { - cat > test.cpp << EOF -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -void foo(int index) { char *x = (char*)malloc(10 * sizeof(char)); memset(x, 0, 10); free(x); free(x - index); } -int main(int argc, char **argv) { foo(argc - 1); printf("CHECK\n"); exit(0); } -EOF - c++ -fsanitize=address -o test -pg test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"double-free" ./test -} - -double_free_pic_body() { - cat > test.cpp << EOF -#include <stdlib.h> -#include <stdio.h> -#include <stdio.h> -int foo(int); -int main(int argc, char **argv) {foo(argc - 1); printf("CHECK\n"); exit(0);} -EOF - cat > pic.cpp << EOF -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -int foo(int index) { char *x = (char*)malloc(10 * sizeof(char)); memset(x, 0, 10); free(x); free(x - index); } -EOF - c++ -fsanitize=address -fPIC -shared -o libtest.so pic.cpp - c++ -o test test.cpp -fsanitize=address -L. -ltest - paxctl +a test - - export LD_LIBRARY_PATH=. - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"double-free" ./test -} - -double_free_pie_body() { - # check whether this arch supports -pice - 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.cpp << EOF -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -void foo(int index) { char *x = (char*)malloc(10 * sizeof(char)); memset(x, 0, 10); free(x); free(x - index); } -int main(int argc, char **argv) { foo(argc - 1); printf("CHECK\n"); exit(0); } -EOF - c++ -fsanitize=address -o test -fpie -pie test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"double-free" ./test -} - -double_free32_body() { - # check whether this arch is 64bit - if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then - atf_skip "this is not a 64 bit architecture" - fi - if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then - atf_skip "c++ -m32 not supported on this architecture" - else - if fgrep -q _LP64 ./def32; then - atf_fail "c++ -m32 does not generate netbsd32 binaries" - fi -fi - - cat > test.cpp << EOF -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -void foo(int index) { char *x = (char*)malloc(10 * sizeof(char)); memset(x, 0, 10); free(x); free(x - index); } -int main(int argc, char **argv) { foo(argc - 1); printf("CHECK\n"); exit(0); } -EOF - c++ -fsanitize=address -o df32 -m32 test.cpp - c++ -fsanitize=address -o df64 test.cpp - file -b ./df32 > ./ftype32 - file -b ./df64 > ./ftype64 - if diff ./ftype32 ./ftype64 >/dev/null; then - atf_fail "generated binaries do not differ" - fi - echo "32bit binaries on this platform are:" - cat ./ftype32 - echo "While native (64bit) binaries are:" - cat ./ftype64 - paxctl +a df32 - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"double-free" ./df32 - -# do another test with static 32bit binaries -# and another test with profile 32bit binaries - cat > test.cpp << EOF -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -void foo(int index) { char *x = (char*)malloc(10 * sizeof(char)); memset(x, 0, 10); free(x); free(x - index); } -int main(int argc, char **argv) { foo(argc - 1); printf("CHECK\n"); exit(0); } -EOF - c++ -fsanitize=address -o test -pg -m32 test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"double-free" ./test -} - -target_not_supported_body() -{ - atf_skip "Target is not supported" -} +asan_test_case double_free "Double Free example" double-free atf_init_test_cases() { - test_target - test $SUPPORT = 'n' && { - atf_add_test_case target_not_supported - return 0 - } - - atf_add_test_case double_free -# atf_add_test_case double_free_profile - atf_add_test_case double_free_pic - atf_add_test_case double_free_pie -# atf_add_test_case double_free32 - # static option not supported - # -static and -fsanitize=address can't be used together for compilation - # (gcc version 5.4.0 and clang 7.1) tested on April 2nd 2018. + asan_add_test_cases double_free } Index: src/tests/usr.bin/c++/t_asan_global_buffer_overflow.sh diff -u src/tests/usr.bin/c++/t_asan_global_buffer_overflow.sh:1.2 src/tests/usr.bin/c++/t_asan_global_buffer_overflow.sh:1.3 --- src/tests/usr.bin/c++/t_asan_global_buffer_overflow.sh:1.2 Mon Jul 16 07:27:26 2018 +++ src/tests/usr.bin/c++/t_asan_global_buffer_overflow.sh Tue Jan 29 20:02:34 2019 @@ -1,6 +1,6 @@ -# $NetBSD: t_asan_global_buffer_overflow.sh,v 1.2 2018/07/16 07:27:26 kamil Exp $ +# $NetBSD: t_asan_global_buffer_overflow.sh,v 1.3 2019/01/29 20:02:34 mgorny Exp $ # -# Copyright (c) 2018 The NetBSD Foundation, Inc. +# Copyright (c) 2018, 2019 The NetBSD Foundation, Inc. # All rights reserved. # # This code is derived from software contributed to The NetBSD Foundation @@ -28,184 +28,23 @@ # POSSIBILITY OF SUCH DAMAGE. # -SUPPORT='n' -test_target() { - if uname -m | grep -q "amd64"; then - SUPPORT='y' - fi - - if uname -m | grep -q "i386"; then - SUPPORT='y' - fi -} - -atf_test_case global_buffer_overflow -global_buffer_overflow_head() { - atf_set "descr" "compile and run \"Global Buffer Overflow example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case global_buffer_overflow_profile -global_buffer_overflow_profile_head() { - atf_set "descr" "compile and run \"Global Buffer Overflow example\" with profiling option" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case global_buffer_overflow_pic -global_buffer_overflow_pic_head() { - atf_set "descr" "compile and run PIC \"Global Buffer Overflow example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case global_buffer_overflow_pie -global_buffer_overflow_pie_head() { - atf_set "descr" "compile and run position independent (PIE) \"Global Buffer Overflow example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case global_buffer_overflow32 -global_buffer_overflow32_head() { - atf_set "descr" "compile and run \"Global Buffer Overflow example\" for/in netbsd32 emulation" - atf_set "require.progs" "c++ paxctl file diff cat" -} - -atf_test_case target_not_supported -target_not_supported_head() -{ - atf_set "descr" "Test forced skip" -} - -global_buffer_overflow_body() { - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int arr[5] = {-1}; -int foo(int index) { arr[index] = 0; } -int main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o test test.cpp - paxctl -a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./test -} - -global_buffer_overflow_profile_body() { - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int arr[5] = {-1}; -int foo(int index) { arr[index] = 0; } -int main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o test -pg test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./test -} - -global_buffer_overflow_pic_body() { - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int foo(int); -int main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);} -EOF - cat > pic.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int arr[5] = {-1}; -int foo(int index) { arr[index] = 0; } -EOF - - c++ -fPIC -fsanitize=address -shared -o libtest.so pic.cpp - c++ -o test test.cpp -fsanitize=address -L. -ltest - paxctl +a test - - export LD_LIBRARY_PATH=. - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./test -} - -global_buffer_overflow_pie_body() { - # check whether this arch supports -pice - 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.cpp << EOF +ASAN_CODE=' #include <stdio.h> #include <stdlib.h> int arr[5] = {-1}; -int foo(int index) { arr[index] = 0; } +void foo(int); +#ifndef PIC_MAIN +void foo(int index) { arr[index] = 0; } +#endif +#ifndef PIC_FOO int main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -fpie -pie -o test test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./test -} +#endif +' -global_buffer_overflow32_body() { - # check whether this arch is 64bit - if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then - atf_skip "this is not a 64 bit architecture" - fi - if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then - atf_skip "c++ -m32 not supported on this architecture" - else - if fgrep -q _LP64 ./def32; then - atf_fail "c++ -m32 does not generate netbsd32 binaries" - fi -fi - - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int arr[5] = {-1}; -int foo(int index) { arr[index] = 0; } -int main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o gbof32 -m32 test.cpp - c++ -fsanitize=address -o gbof64 test.cpp - file -b ./gbof32 > ./ftype32 - file -b ./gbof64 > ./ftype64 - if diff ./ftype32 ./ftype64 >/dev/null; then - atf_fail "generated binaries do not differ" - fi - echo "32bit binaries on this platform are:" - cat ./ftype32 - echo "While native (64bit) binaries are:" - cat ./ftype64 - paxctl +a gbof32 - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./gbof32 - -# and another test with profile 32bit binaries - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int arr[5] = {-1}; -int foo(int index) { arr[index] = 0; } -int main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);} -EOF - c++ -o test -m32 -fsanitize=address -pg test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./test -} - -target_not_supported_body() -{ - atf_skip "Target is not supported" -} +asan_test_case global_buffer_overflow "Global Buffer Overflow example" \ + global-buffer-overflow atf_init_test_cases() { - test_target - test $SUPPORT = 'n' && { - atf_add_test_case target_not_supported - return 0 - } - - atf_add_test_case global_buffer_overflow -# atf_add_test_case global_buffer_overflow_profile - atf_add_test_case global_buffer_overflow_pic - atf_add_test_case global_buffer_overflow_pie -# atf_add_test_case global_buffer_overflow32 - # static option not supported - # -static and -fsanitize=address can't be used together for compilation - # (gcc version 5.4.0 and clang 7.1) tested on April 2nd 2018. + asan_add_test_cases global_buffer_overflow } Index: src/tests/usr.bin/c++/t_asan_heap_overflow.sh diff -u src/tests/usr.bin/c++/t_asan_heap_overflow.sh:1.2 src/tests/usr.bin/c++/t_asan_heap_overflow.sh:1.3 --- src/tests/usr.bin/c++/t_asan_heap_overflow.sh:1.2 Mon Jul 16 07:27:26 2018 +++ src/tests/usr.bin/c++/t_asan_heap_overflow.sh Tue Jan 29 20:02:34 2019 @@ -1,6 +1,6 @@ -# $NetBSD: t_asan_heap_overflow.sh,v 1.2 2018/07/16 07:27:26 kamil Exp $ +# $NetBSD: t_asan_heap_overflow.sh,v 1.3 2019/01/29 20:02:34 mgorny Exp $ # -# Copyright (c) 2018 The NetBSD Foundation, Inc. +# Copyright (c) 2018, 2019 The NetBSD Foundation, Inc. # All rights reserved. # # This code is derived from software contributed to The NetBSD Foundation @@ -28,185 +28,22 @@ # POSSIBILITY OF SUCH DAMAGE. # -SUPPORT='n' -test_target() { - if uname -m | grep -q "amd64"; then - SUPPORT='y' - fi - - if uname -m | grep -q "i386"; then - SUPPORT='y' - fi -} - -atf_test_case heap_overflow -heap_overflow_head() { - atf_set "descr" "compile and run \"Heap Overflow example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case heap_overflow_profile -heap_overflow_profile_head() { - atf_set "descr" "compile and run \"Heap Overflow example\" with profiling option" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case heap_overflow_pic -heap_overflow_pic_head() { - atf_set "descr" "compile and run PIC \"Heap Overflow example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case heap_overflow_pie -heap_overflow_pie_head() { - atf_set "descr" "compile and run position independent (PIE) \"Heap Overflow example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case heap_overflow32 -heap_overflow32_head() { - atf_set "descr" "compile and run \"Heap Overflow example\" for/in netbsd32 emulation" - atf_set "require.progs" "c++ paxctl file diff cat" -} - -atf_test_case target_not_supported -target_not_supported_head() -{ - atf_set "descr" "Test forced skip" -} - -heap_overflow_body() { - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -int foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;} -int main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o test test.cpp - paxctl -a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./test -} - -heap_overflow_profile_body() { - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -int foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;} -int main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o test -pg test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./test -} - -heap_overflow_pic_body() { - cat > test.cpp << EOF +ASAN_CODE=' #include <stdio.h> #include <stdlib.h> #include <string.h> int foo(int); -int main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);} -EOF - cat > pic.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -int foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;} -EOF - - c++ -fPIC -fsanitize=address -shared -o libtest.so pic.cpp - c++ -o test test.cpp -fsanitize=address -L. -ltest - paxctl +a test - - export LD_LIBRARY_PATH=. - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./test -} - -heap_overflow_pie_body() { - # check whether this arch supports -pice - 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.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -int foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;} -int main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -fpie -pie -o test test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./test -} - -heap_overflow32_body() { - # check whether this arch is 64bit - if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then - atf_skip "this is not a 64 bit architecture" - fi - if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then - atf_skip "c++ -m32 not supported on this architecture" - else - if fgrep -q _LP64 ./def32; then - atf_fail "c++ -m32 does not generate netbsd32 binaries" - fi -fi - - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -#include <string.h> +#ifndef PIC_MAIN int foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;} +#endif +#ifndef PIC_FOO int main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o ho32 -m32 test.cpp - c++ -fsanitize=address -o ho64 test.cpp - file -b ./ho32 > ./ftype32 - file -b ./ho64 > ./ftype64 - if diff ./ftype32 ./ftype64 >/dev/null; then - atf_fail "generated binaries do not differ" - fi - echo "32bit binaries on this platform are:" - cat ./ftype32 - echo "While native (64bit) binaries are:" - cat ./ftype64 - paxctl +a ho32 - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./ho32 +#endif +' -# and another test with profile 32bit binaries - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -int foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;} -int main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);} -EOF - c++ -o test -m32 -fsanitize=address -pg test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./test -} - -target_not_supported_body() -{ - atf_skip "Target is not supported" -} +asan_test_case heap_overflow "Heap Overflow example" heap-buffer-overflow atf_init_test_cases() { - test_target - test $SUPPORT = 'n' && { - atf_add_test_case target_not_supported - return 0 - } - - atf_add_test_case heap_overflow -# atf_add_test_case heap_overflow_profile - atf_add_test_case heap_overflow_pic - atf_add_test_case heap_overflow_pie -# atf_add_test_case heap_overflow32 - # static option not supported - # -static and -fsanitize=address can't be used together for compilation - # (gcc version 5.4.0 and clang 7.1) tested on April 2nd 2018. + asan_add_test_cases heap_overflow } Index: src/tests/usr.bin/c++/t_asan_off_by_one.sh diff -u src/tests/usr.bin/c++/t_asan_off_by_one.sh:1.2 src/tests/usr.bin/c++/t_asan_off_by_one.sh:1.3 --- src/tests/usr.bin/c++/t_asan_off_by_one.sh:1.2 Mon Jul 16 07:27:26 2018 +++ src/tests/usr.bin/c++/t_asan_off_by_one.sh Tue Jan 29 20:02:34 2019 @@ -1,6 +1,6 @@ -# $NetBSD: t_asan_off_by_one.sh,v 1.2 2018/07/16 07:27:26 kamil Exp $ +# $NetBSD: t_asan_off_by_one.sh,v 1.3 2019/01/29 20:02:34 mgorny Exp $ # -# Copyright (c) 2018 The NetBSD Foundation, Inc. +# Copyright (c) 2018, 2019 The NetBSD Foundation, Inc. # All rights reserved. # # This code is derived from software contributed to The NetBSD Foundation @@ -28,206 +28,26 @@ # POSSIBILITY OF SUCH DAMAGE. # -SUPPORT='n' -test_target() { - if uname -m | grep -q "amd64"; then - SUPPORT='y' - fi - - if uname -m | grep -q "i386"; then - SUPPORT='y' - fi -} - -atf_test_case off_by_one -off_by_one_head() { - atf_set "descr" "compile and run \"Off by one example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case off_by_one_profile -off_by_one_profile_head() { - atf_set "descr" "compile and run \"Off by one example\" with profiling option" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case off_by_one_pic -off_by_one_pic_head() { - atf_set "descr" "compile and run PIC \"Off by one example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case off_by_one_pie -off_by_one_pie_head() { - atf_set "descr" "compile and run position independent (PIE) \"Off by one example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case off_by_one32 -off_by_one32_head() { - atf_set "descr" "compile and run \"Off by one example\" for/in netbsd32 emulation" - atf_set "require.progs" "c++ paxctl file diff cat" -} - -atf_test_case target_not_supported -target_not_supported_head() -{ - atf_set "descr" "Test forced skip" -} - -off_by_one_body() { - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int foo() { - int arr[5]; - for (int i = 0; i <= 5 ; i++) { - arr[i] = 0; - } -} -int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o test test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"stack-buffer-overflow" ./test -} - -off_by_one_profile_body() { - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int foo() { - int arr[5]; - for (int i = 0; i <= 5 ; i++) { - arr[i] = 0; - } -} -int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o test -pg test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"stack-buffer-overflow" ./test -} - -off_by_one_pic_body() { - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int foo(); -int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - cat > pic.cpp << EOF +ASAN_CODE=' #include <stdio.h> #include <stdlib.h> -int foo() { - int arr[5]; - for (int i = 0; i <= 5 ; i++) { - arr[i] = 0; - } -} -EOF - c++ -fPIC -fsanitize=address -shared -o libtest.so pic.cpp - c++ -o test test.cpp -fsanitize=address -L. -ltest - - export LD_LIBRARY_PATH=. - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"stack-buffer-overflow" ./test -} - -off_by_one_pie_body() { - # check whether this arch supports -pice - 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.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int foo() { +void foo(); +#ifndef PIC_MAIN +void foo() { int arr[5]; for (int i = 0; i <= 5 ; i++) { arr[i] = 0; } } +#endif +#ifndef PIC_FOO int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o test -fpie -pie test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"stack-buffer-overflow" ./test -} +#endif +' -off_by_one32_body() { - # check whether this arch is 64bit - if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then - atf_skip "this is not a 64 bit architecture" - fi - if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then - atf_skip "c++ -m32 not supported on this architecture" - else - if fgrep -q _LP64 ./def32; then - atf_fail "c++ -m32 does not generate netbsd32 binaries" - fi -fi - - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int foo() { - int arr[5]; - for (int i = 0; i <= 5 ; i++) { - arr[i] = 0; - } -} -int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o obo32 -m32 test.cpp - c++ -fsanitize=address -o obo64 test.cpp - file -b ./obo32 > ./ftype32 - file -b ./obo64 > ./ftype64 - if diff ./ftype32 ./ftype64 >/dev/null; then - atf_fail "generated binaries do not differ" - fi - echo "32bit binaries on this platform are:" - cat ./ftype32 - echo "While native (64bit) binaries are:" - cat ./ftype64 - paxctl +a obo32 - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"stack-buffer-overflow" ./obo32 - -# and another test with profile 32bit binaries - cat > test.cpp << EOF -#include <stdio.h> -#include <stdlib.h> -int foo() { - int arr[5]; - for (int i = 0; i <= 5 ; i++) { - arr[i] = 0; - } -} -int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o test -pg test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"stack-buffer-overflow" ./test -} - -target_not_supported_body() -{ - atf_skip "Target is not supported" -} +asan_test_case off_by_one "Off by one example" stack-buffer-overflow atf_init_test_cases() { - test_target - test $SUPPORT = 'n' && { - atf_add_test_case target_not_supported - return 0 - } - - atf_add_test_case off_by_one -# atf_add_test_case off_by_one_profile - atf_add_test_case off_by_one_pic - atf_add_test_case off_by_one_pie -# atf_add_test_case off_by_one32 - # static option not supported - # -static and -fsanitize=address can't be used together for compilation - # (gcc version 5.4.0 and clang 7.1) tested on April 2nd 2018. + asan_add_test_cases off_by_one } Index: src/tests/usr.bin/c++/t_asan_poison.sh diff -u src/tests/usr.bin/c++/t_asan_poison.sh:1.2 src/tests/usr.bin/c++/t_asan_poison.sh:1.3 --- src/tests/usr.bin/c++/t_asan_poison.sh:1.2 Mon Jul 16 07:27:26 2018 +++ src/tests/usr.bin/c++/t_asan_poison.sh Tue Jan 29 20:02:34 2019 @@ -1,6 +1,6 @@ -# $NetBSD: t_asan_poison.sh,v 1.2 2018/07/16 07:27:26 kamil Exp $ +# $NetBSD: t_asan_poison.sh,v 1.3 2019/01/29 20:02:34 mgorny Exp $ # -# Copyright (c) 2018 The NetBSD Foundation, Inc. +# Copyright (c) 2018, 2019 The NetBSD Foundation, Inc. # All rights reserved. # # This code is derived from software contributed to The NetBSD Foundation @@ -28,143 +28,12 @@ # POSSIBILITY OF SUCH DAMAGE. # -SUPPORT='n' -test_target() { - if uname -m | grep -q "amd64"; then - SUPPORT='y' - fi - - if uname -m | grep -q "i386"; then - SUPPORT='y' - fi -} - -atf_test_case poison -poison_head() { - atf_set "descr" "compile and run \"Use after Poison example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case poison_profile -poison_profile_head() { - atf_set "descr" "compile and run \"Use after Poison example\" with profiling option" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case poison_pic -poison_pic_head() { - atf_set "descr" "compile and run PIC \"Use after Poison example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case poison_pie -poison_pie_head() { - atf_set "descr" "compile and run position independent (PIE) \"Use after Poison example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case poison32 -poison32_head() { - atf_set "descr" "compile and run \"Use after Poison example\" for/in netbsd32 emulation" - atf_set "require.progs" "c++ paxctl file diff cat" -} - -atf_test_case target_not_supported -target_not_supported_head() -{ - atf_set "descr" "Test forced skip" -} - -poison_body() { - cat > test.c << EOF -#include <stdio.h> -#include <stdlib.h> -#include <sanitizer/asan_interface.h> -int foo() { - int p = 2; - int *a; - ASAN_POISON_MEMORY_REGION(&p, sizeof(int)); - a=&p; - printf("%d", *a); -} - -int main() { - foo(); - printf("CHECK\n"); - exit(0); -} -EOF - c++ -fsanitize=address -o test test.c - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"use-after-poison" ./test -} - -poison_profile_body() { - cat > test.c << EOF -#include <stdio.h> -#include <stdlib.h> -#include <sanitizer/asan_interface.h> -int foo() { - int p = 2; - int *a; - ASAN_POISON_MEMORY_REGION(&p, sizeof(int)); - a=&p; - printf("%d", *a); -} - -int main() { - foo(); - printf("CHECK\n"); - exit(0); -} -EOF - c++ -fsanitize=address -o test -pg test.c - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"use-after-poison" ./test -} - -poison_pic_body() { - cat > test.c << EOF +ASAN_CODE=' #include <stdio.h> #include <stdlib.h> #include <sanitizer/asan_interface.h> int foo(); -int main() { - foo(); - printf("CHECK\n"); - exit(0); -} -EOF - cat > pic.c << EOF -#include <stdio.h> -#include <stdlib.h> -#include <sanitizer/asan_interface.h> -int foo() { - int p = 2; - int *a; - ASAN_POISON_MEMORY_REGION(&p, sizeof(int)); - a=&p; - printf("%d", *a); -} -EOF - - c++ -fPIC -fsanitize=address -shared -o libtest.so pic.c - c++ -o test test.c -fsanitize=address -L. -ltest - paxctl +a test - - export LD_LIBRARY_PATH=. - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"use-after-poison" ./test -} - -poison_pie_body() { - # check whether this arch supports -pice - 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.c << EOF -#include <stdio.h> -#include <stdlib.h> -#include <sanitizer/asan_interface.h> +#ifndef PIC_MAIN int foo() { int p = 2; int *a; @@ -172,106 +41,20 @@ int foo() { a=&p; printf("%d", *a); } +#endif +#ifndef PIC_FOO int main() { foo(); printf("CHECK\n"); exit(0); } -EOF - c++ -fsanitize=address -fpie -pie -o test test.c - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"use-after-poison" ./test -} - -poison32_body() { - # check whether this arch is 64bit - if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then - atf_skip "this is not a 64 bit architecture" - fi - if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then - atf_skip "c++ -m32 not supported on this architecture" - else - if fgrep -q _LP64 ./def32; then - atf_fail "c++ -m32 does not generate netbsd32 binaries" - fi -fi +#endif +' - cat > test.c << EOF -#include <stdio.h> -#include <stdlib.h> -#include <sanitizer/asan_interface.h> -int foo() { - int p = 2; - int *a; - ASAN_POISON_MEMORY_REGION(&p, sizeof(int)); - a=&p; - printf("%d", *a); -} - -int main() { - foo(); - printf("CHECK\n"); - exit(0); -} -EOF - c++ -fsanitize=address -o psn32 -m32 test.c - c++ -fsanitize=address -o psn64 test.c - file -b ./psn32 > ./ftype32 - file -b ./psn64 > ./ftype64 - if diff ./ftype32 ./ftype64 >/dev/null; then - atf_fail "generated binaries do not differ" - fi - echo "32bit binaries on this platform are:" - cat ./ftype32 - echo "While native (64bit) binaries are:" - cat ./ftype64 - paxctl +a psn32 - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"use-after-poison" ./psn32 - -# and another test with profile 32bit binaries - cat > test.c << EOF -#include <stdio.h> -#include <stdlib.h> -#include <sanitizer/asan_interface.h> -int foo() { - int p = 2; - int *a; - ASAN_POISON_MEMORY_REGION(&p, sizeof(int)); - a=&p; - printf("%d", *a); -} - -int main() { - foo(); - printf("CHECK\n"); - exit(0); -} -EOF - c++ -o test -m32 -fsanitize=address -pg test.c - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"use-after-poison" ./test -} - -target_not_supported_body() -{ - atf_skip "Target is not supported" -} +asan_test_case poison 'Use after Poison example' use-after-poison 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_pic - atf_add_test_case poison_pie -# atf_add_test_case poison32 - # static option not supported - # -static and -fsanitize=address can't be used together for compilation - # (gcc version 5.4.0 and clang 7.1) tested on April 2nd 2018. + asan_add_test_cases poison } Index: src/tests/usr.bin/c++/t_asan_uaf.sh diff -u src/tests/usr.bin/c++/t_asan_uaf.sh:1.2 src/tests/usr.bin/c++/t_asan_uaf.sh:1.3 --- src/tests/usr.bin/c++/t_asan_uaf.sh:1.2 Mon Jul 16 07:27:26 2018 +++ src/tests/usr.bin/c++/t_asan_uaf.sh Tue Jan 29 20:02:34 2019 @@ -1,6 +1,6 @@ -# $NetBSD: t_asan_uaf.sh,v 1.2 2018/07/16 07:27:26 kamil Exp $ +# $NetBSD: t_asan_uaf.sh,v 1.3 2019/01/29 20:02:34 mgorny Exp $ # -# Copyright (c) 2018 The NetBSD Foundation, Inc. +# Copyright (c) 2018, 2019 The NetBSD Foundation, Inc. # All rights reserved. # # This code is derived from software contributed to The NetBSD Foundation @@ -28,178 +28,21 @@ # POSSIBILITY OF SUCH DAMAGE. # -SUPPORT='n' -test_target() { - if uname -m | grep -q "amd64"; then - SUPPORT='y' - fi - - if uname -m | grep -q "i386"; then - SUPPORT='y' - fi -} - -atf_test_case uaf -uaf_head() { - atf_set "descr" "compile and run \"Use After Free example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case uaf_profile -uaf_profile_head() { - atf_set "descr" "compile and run \"Use After Free example\" with profiling option" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case uaf_pic -uaf_pic_head() { - atf_set "descr" "compile and run PIC \"Use After Free example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case uaf_pie -uaf_pie_head() { - atf_set "descr" "compile and run position independent (PIE) \"Use After Free example\"" - atf_set "require.progs" "c++ paxctl" -} - -atf_test_case uaf32 -uaf32_head() { - atf_set "descr" "compile and run \"Use After Free example\" for/in netbsd32 emulation" - atf_set "require.progs" "c++ paxctl file diff cat" -} - -atf_test_case target_not_supported -target_not_supported_head() -{ - atf_set "descr" "Test forced skip" -} - -uaf_body() { - cat > test.cpp << EOF -#include <stdlib.h> -#include <stdio.h> -int foo() {int *x = (int *)malloc(10 * sizeof(int)); free(x); return x[0];} -int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o test test.cpp - paxctl -a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-use-after-free" ./test -} - -uaf_profile_body() { - cat > test.cpp << EOF -#include <stdlib.h> -#include <stdio.h> -int foo() {int *x = (int *)malloc(10 * sizeof(int)); free(x); return x[0];} -int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o test -pg test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-use-after-free" ./test -} - -uaf_pic_body() { - cat > test.cpp << EOF +ASAN_CODE=' #include <stdlib.h> #include <stdio.h> int foo(); -int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - cat > pic.cpp << EOF -#include <stdlib.h> -#include <stdio.h> -int foo() {int *x = (int *)malloc(10 * sizeof(int)); free(x); return x[0];} -EOF - - c++ -fPIC -fsanitize=address -shared -o libtest.so pic.cpp - c++ -o test test.cpp -fsanitize=address -L. -ltest - paxctl +a test - - export LD_LIBRARY_PATH=. - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-use-after-free" ./test -} - -uaf_pie_body() { - # check whether this arch supports -pice - 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.cpp << EOF -#include <stdlib.h> -#include <stdio.h> +#ifndef PIC_MAIN int foo() {int *x = (int *)malloc(10 * sizeof(int)); free(x); return x[0];} +#endif +#ifndef PIC_FOO int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -fpie -pie -o test test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-use-after-free" ./test -} +#endif +' -uaf32_body() { - # check whether this arch is 64bit - if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then - atf_skip "this is not a 64 bit architecture" - fi - if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then - atf_skip "c++ -m32 not supported on this architecture" - else - if fgrep -q _LP64 ./def32; then - atf_fail "c++ -m32 does not generate netbsd32 binaries" - fi -fi - - cat > test.cpp << EOF -#include <stdlib.h> -#include <stdio.h> -int foo() {int *x = (int *)malloc(10 * sizeof(int)); free(x); return x[0];} -int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - c++ -fsanitize=address -o uaf32 -m32 test.cpp - c++ -fsanitize=address -o uaf64 test.cpp - file -b ./uaf32 > ./ftype32 - file -b ./uaf64 > ./ftype64 - if diff ./ftype32 ./ftype64 >/dev/null; then - atf_fail "generated binaries do not differ" - fi - echo "32bit binaries on this platform are:" - cat ./ftype32 - echo "While native (64bit) binaries are:" - cat ./ftype64 - paxctl +a uaf32 - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-use-after-free" ./uaf32 - -# and another test with profile 32bit binaries - cat > test.cpp << EOF -#include <stdlib.h> -#include <stdio.h> -int foo() {int *x = (int *)malloc(10 * sizeof(int)); free(x); return x[0];} -int main() {foo(); printf("CHECK\n"); exit(0);} -EOF - c++ -o test -m32 -fsanitize=address -pg test.cpp - paxctl +a test - atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-use-after-free" ./test -} - -target_not_supported_body() -{ - atf_skip "Target is not supported" -} +asan_test_case uaf "Use After Free example" heap-use-after-free atf_init_test_cases() { - test_target - test $SUPPORT = 'n' && { - atf_add_test_case target_not_supported - return 0 - } - - atf_add_test_case uaf -# atf_add_test_case uaf_profile - atf_add_test_case uaf_pic - atf_add_test_case uaf_pie -# atf_add_test_case uaf32 - # static option not supported - # -static and -fsanitize=address can't be used together for compilation - # (gcc version 5.4.0 and clang 7.1) tested on April 2nd 2018. + asan_add_test_cases uaf } Added files: Index: src/tests/usr.bin/c++/asan_common.subr diff -u /dev/null src/tests/usr.bin/c++/asan_common.subr:1.1 --- /dev/null Tue Jan 29 20:02:34 2019 +++ src/tests/usr.bin/c++/asan_common.subr Tue Jan 29 20:02:34 2019 @@ -0,0 +1,168 @@ +# $NetBSD: asan_common.subr,v 1.1 2019/01/29 20:02:34 mgorny Exp $ +# +# Copyright (c) 2018, 2019 The NetBSD Foundation, Inc. +# All rights reserved. +# +# 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. +# + +SUPPORT='n' +test_target() { + if uname -m | grep -q "amd64"; then + SUPPORT='y' + fi + + if uname -m | grep -q "i386"; then + SUPPORT='y' + fi +} + +atf_test_case target_not_supported +target_not_supported_head() +{ + atf_set "descr" "Test forced skip" +} + +target_not_supported_body() +{ + atf_skip "Target is not supported" +} + +# Add a new test case, with head & body. +# asan_test_case <test-name> <description> <check-output> +asan_test_case() { + atf_test_case "$1" + eval "$1_head() { + atf_set 'descr' 'compile and run \"$2\"' + atf_set 'require.progs' 'c++ paxctl' + }" + + atf_test_case "$1_profile" + eval "$1_head() { + atf_set 'descr' 'compile and run \"$2\" with profiling option' + atf_set 'require.progs' 'c++ paxctl' + }" + + atf_test_case "$1_pic" + eval "$1_head() { + atf_set 'descr' 'compile and run PIC \"$2\"' + atf_set 'require.progs' 'c++ paxctl' + }" + + atf_test_case "$1_pie" + eval "$1_head() { + atf_set 'descr' 'compile and run position independent (PIE) \"$2\"' + atf_set 'require.progs' 'c++ paxctl' + }" + + atf_test_case "${1}32" + eval "$1_head() { + atf_set 'descr' 'compile and run \"$2\" for/in netbsd32 emulation' + atf_set 'require.progs' 'c++ paxctl file diff cat' + }" + + eval "$1_body() { + echo \"\$ASAN_CODE\" > test.cpp + c++ -fsanitize=address -o test test.cpp + paxctl +a test + atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./test + } + + $1_profile_body() { + echo \"\$ASAN_CODE\" > test.cpp + c++ -fsanitize=address -o test -pg test.cpp + paxctl +a test + atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./test + } + + $1_pic_body() { + echo \"\$ASAN_CODE\" > test.cpp + c++ -DPIC_FOO -fsanitize=address -fPIC -shared -o libtest.so test.cpp + c++ -DPIC_MAIN -o test test.cpp -fsanitize=address -L. -ltest + paxctl +a test + + export LD_LIBRARY_PATH=. + atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./test + } + + $1_pie_body() { + # check whether this arch supports -pice + if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_set_skip 'c++ -pie not supported on this architecture' + fi + echo \"\$ASAN_CODE\" > test.cpp + c++ -fsanitize=address -o test -fpie -pie test.cpp + paxctl +a test + atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./test + } + + ${1}32_body() { + # check whether this arch is 64bit + if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then + atf_skip 'this is not a 64 bit architecture' + fi + if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then + atf_skip 'c++ -m32 not supported on this architecture' + else + if fgrep -q _LP64 ./def32; then + atf_fail 'c++ -m32 does not generate netbsd32 binaries' + fi + fi + + echo \"\$ASAN_CODE\" > test.cpp + c++ -fsanitize=address -o df32 -m32 test.cpp + c++ -fsanitize=address -o df64 test.cpp + file -b ./df32 > ./ftype32 + file -b ./df64 > ./ftype64 + if diff ./ftype32 ./ftype64 >/dev/null; then + atf_fail 'generated binaries do not differ' + fi + echo '32bit binaries on this platform are:' + cat ./ftype32 + echo 'While native (64bit) binaries are:' + cat ./ftype64 + paxctl +a df32 + atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./df32 + +# and another test with profile 32bit binaries + c++ -fsanitize=address -o test -pg -m32 test.cpp + paxctl +a test + atf_check -s not-exit:0 -o not-match:'CHECK\n' -e match:'$3' ./test + }" +} + +asan_add_test_cases() { + test_target + test $SUPPORT = 'n' && { + atf_add_test_case target_not_supported + return 0 + } + + atf_add_test_case "$1" +# atf_add_test_case "$1_profile" + atf_add_test_case "$1_pic" + atf_add_test_case "$1_pie" +# atf_add_test_case "${1}32" + # static option not supported + # -static and -fsanitize=address can't be used together for compilation + # (gcc version 5.4.0 and clang 7.1) tested on April 2nd 2018. +}