diff options
| author | kamil <kamil@NetBSD.org> | 2018-04-11 03:25:25 +0000 |
|---|---|---|
| committer | kamil <kamil@NetBSD.org> | 2018-04-11 03:25:25 +0000 |
| commit | b7ff57c5dfb2cc126d10e20e06fe3f5da941accd (patch) | |
| tree | 525cefc995d670e5c92f473b1f8c7a0cdc2313d0 /tests/usr.bin/c++ | |
| parent | cbe20adf7c92bd71bc524c74516aed06e948469e (diff) | |
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>
Diffstat (limited to 'tests/usr.bin/c++')
| -rw-r--r-- | tests/usr.bin/c++/Makefile | 3 | ||||
| -rw-r--r-- | tests/usr.bin/c++/t_asan_poison.sh | 277 |
2 files changed, 279 insertions, 1 deletions
diff --git a/tests/usr.bin/c++/Makefile b/tests/usr.bin/c++/Makefile index e1dd0472c31..e88cae7bad6 100644 --- a/tests/usr.bin/c++/Makefile +++ b/tests/usr.bin/c++/Makefile @@ -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 diff --git a/tests/usr.bin/c++/t_asan_poison.sh b/tests/usr.bin/c++/t_asan_poison.sh new file mode 100644 index 00000000000..b54eda23e38 --- /dev/null +++ b/tests/usr.bin/c++/t_asan_poison.sh @@ -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. +} |
