Module Name: src Committed By: kamil Date: Wed Apr 11 03:25:25 UTC 2018
Modified Files: src/distrib/sets/lists/tests: mi src/tests/usr.bin/c++: Makefile src/tests/usr.bin/cc: Makefile Added Files: src/tests/usr.bin/c++: t_asan_poison.sh src/tests/usr.bin/cc: t_asan_poison.sh Log Message: Import new C and C++ ATF tests for ASan Add new tests: - tests/usr.bin/cc/t_asan_poison.sh - tests/usr.bin/c++/t_asan_poison.sh These tests verify the following build options: - regular - profile - pic - pie - compat32 - (static unsupported) These tests verify whether ASan code can include compiler and sanitizer specific header: <sanitizer/asan_interface.h>. The testing code checks the ASAN_POISON_MEMORY_REGION() functionality, poisoning valid memory and asserting that it triggers expected failure. Patch submitted by <Siddharth Muralee> To generate a diff of this commit: cvs rdiff -u -r1.780 -r1.781 src/distrib/sets/lists/tests/mi cvs rdiff -u -r1.7 -r1.8 src/tests/usr.bin/c++/Makefile cvs rdiff -u -r0 -r1.1 src/tests/usr.bin/c++/t_asan_poison.sh cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/cc/Makefile cvs rdiff -u -r0 -r1.1 src/tests/usr.bin/cc/t_asan_poison.sh Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/tests/mi diff -u src/distrib/sets/lists/tests/mi:1.780 src/distrib/sets/lists/tests/mi:1.781 --- src/distrib/sets/lists/tests/mi:1.780 Wed Apr 4 23:51:35 2018 +++ src/distrib/sets/lists/tests/mi Wed Apr 11 03:25:25 2018 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.780 2018/04/04 23:51:35 kamil Exp $ +# $NetBSD: mi,v 1.781 2018/04/11 03:25:25 kamil Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -3639,6 +3639,7 @@ ./usr/tests/usr.bin/c++/t_asan_global_buffer_overflow tests-usr.bin-tests compattestfile,atf,cxx ./usr/tests/usr.bin/c++/t_asan_heap_overflow tests-usr.bin-tests compattestfile,atf,cxx ./usr/tests/usr.bin/c++/t_asan_off_by_one tests-usr.bin-tests compattestfile,atf,cxx +./usr/tests/usr.bin/c++/t_asan_poison tests-usr.bin-tests compattestfile,atf,cxx ./usr/tests/usr.bin/c++/t_asan_uaf tests-usr.bin-tests compattestfile,atf,cxx ./usr/tests/usr.bin/c++/t_call_once tests-usr.bin-tests compattestfile,atf,cxx ./usr/tests/usr.bin/c++/t_call_once2 tests-usr.bin-tests compattestfile,atf,cxx @@ -3654,6 +3655,7 @@ ./usr/tests/usr.bin/cc/t_asan_global_buffer_overflow tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/cc/t_asan_heap_overflow tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/cc/t_asan_off_by_one tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/cc/t_asan_poison tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/cc/t_asan_uaf 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 Index: src/tests/usr.bin/c++/Makefile diff -u src/tests/usr.bin/c++/Makefile:1.7 src/tests/usr.bin/c++/Makefile:1.8 --- src/tests/usr.bin/c++/Makefile:1.7 Wed Apr 4 23:53:26 2018 +++ src/tests/usr.bin/c++/Makefile Wed Apr 11 03:25:25 2018 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.7 2018/04/04 23:53:26 kamil Exp $ +# $NetBSD: Makefile,v 1.8 2018/04/11 03:25:25 kamil Exp $ .include <bsd.own.mk> @@ -9,6 +9,7 @@ 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+= t_call_once TESTS_SH+= t_call_once2 Index: src/tests/usr.bin/cc/Makefile diff -u src/tests/usr.bin/cc/Makefile:1.2 src/tests/usr.bin/cc/Makefile:1.3 --- src/tests/usr.bin/cc/Makefile:1.2 Wed Apr 4 23:51:35 2018 +++ src/tests/usr.bin/cc/Makefile Wed Apr 11 03:25:25 2018 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.2 2018/04/04 23:51:35 kamil Exp $ +# $NetBSD: Makefile,v 1.3 2018/04/11 03:25:25 kamil Exp $ .include <bsd.own.mk> @@ -9,6 +9,7 @@ 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+= t_hello Added files: Index: src/tests/usr.bin/c++/t_asan_poison.sh diff -u /dev/null src/tests/usr.bin/c++/t_asan_poison.sh:1.1 --- /dev/null Wed Apr 11 03:25:25 2018 +++ src/tests/usr.bin/c++/t_asan_poison.sh Wed Apr 11 03:25:25 2018 @@ -0,0 +1,277 @@ +# $NetBSD: t_asan_poison.sh,v 1.1 2018/04/11 03:25:25 kamil Exp $ +# +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Siddharth Muralee. +# +# 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 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 +#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> +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 -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 + + 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" +} + +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. +} Index: src/tests/usr.bin/cc/t_asan_poison.sh diff -u /dev/null src/tests/usr.bin/cc/t_asan_poison.sh:1.1 --- /dev/null Wed Apr 11 03:25:25 2018 +++ src/tests/usr.bin/cc/t_asan_poison.sh Wed Apr 11 03:25:25 2018 @@ -0,0 +1,277 @@ +# $NetBSD: t_asan_poison.sh,v 1.1 2018/04/11 03:25:25 kamil Exp $ +# +# Copyright (c) 2018 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Siddharth Muralee. +# +# 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 poison +poison_head() { + atf_set "descr" "compile and run \"Use after Poison example\"" + atf_set "require.progs" "cc 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" "cc paxctl" +} + +atf_test_case poison_pic +poison_pic_head() { + atf_set "descr" "compile and run PIC \"Use after Poison example\"" + atf_set "require.progs" "cc 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" "cc 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" "cc 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 + cc -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 + cc -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 +#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 + + cc -fPIC -fsanitize=address -shared -o libtest.so pic.c + cc -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 ! 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/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 + cc -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 ! cc -dM -E - < /dev/null | fgrep -q _LP64; then + atf_skip "this is not a 64 bit architecture" + fi + if ! cc -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then + atf_skip "cc -m32 not supported on this architecture" + else + if fgrep -q _LP64 ./def32; then + atf_fail "cc -m32 does not generate netbsd32 binaries" + fi +fi + + 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 + cc -fsanitize=address -o psn32 -m32 test.c + cc -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 + cc -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" +} + +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. +}