Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add new ATF tests for Address Sanitzier (ASan)



details:   https://anonhg.NetBSD.org/src/rev/9724fef17341
branches:  trunk
changeset: 831538:9724fef17341
user:      kamil <kamil%NetBSD.org@localhost>
date:      Wed Apr 04 23:51:35 2018 +0000

description:
Add new ATF tests for Address Sanitzier (ASan)

Add new C and C++ tests:
 - t_asan_double_free
 - t_asan_global_buffer_overflow
 - t_asan_heap_overflow
 - t_asan_off_by_one
 - t_asan_uaf

Each tests checks:
 - regular build
 - 32-bit
 - PIC
 - PIE
 - profile

These tests require paxctl(8) to disable ASLR in order to work in a
predictable way. This is especially true for all !regular builds with
additional compiler flags.

There are no static variations of these tests as this mode is not supported
in upstream ASan.

Enable these tests on amd64 and i386.

Patch submitted by <Siddharth Muralee>
Additional polishing by myself.

diffstat:

 distrib/sets/lists/tests/mi                       |   12 +-
 tests/usr.bin/cc/Makefile                         |   10 +-
 tests/usr.bin/cc/t_asan_double_free.sh            |  211 +++++++++++++++++++
 tests/usr.bin/cc/t_asan_global_buffer_overflow.sh |  211 +++++++++++++++++++
 tests/usr.bin/cc/t_asan_heap_overflow.sh          |  212 ++++++++++++++++++++
 tests/usr.bin/cc/t_asan_off_by_one.sh             |  233 ++++++++++++++++++++++
 tests/usr.bin/cc/t_asan_uaf.sh                    |  205 +++++++++++++++++++
 7 files changed, 1091 insertions(+), 3 deletions(-)

diffs (truncated from 1146 to 300 lines):

diff -r 1c8c2272888b -r 9724fef17341 distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi       Wed Apr 04 22:52:58 2018 +0000
+++ b/distrib/sets/lists/tests/mi       Wed Apr 04 23:51:35 2018 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.779 2018/04/04 16:42:48 kamil Exp $
+# $NetBSD: mi,v 1.780 2018/04/04 23:51:35 kamil Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -3635,6 +3635,11 @@
 ./usr/tests/usr.bin/c++                                tests-usr.bin-tests     compattestfile,atf,cxx
 ./usr/tests/usr.bin/c++/Atffile                        tests-usr.bin-tests     compattestfile,atf,cxx
 ./usr/tests/usr.bin/c++/Kyuafile               tests-usr.bin-tests     compattestfile,atf,kyua,cxx
+./usr/tests/usr.bin/c++/t_asan_double_free     tests-usr.bin-tests     compattestfile,atf,cxx
+./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_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
 ./usr/tests/usr.bin/c++/t_cxxruntime           tests-usr.bin-tests     compattestfile,atf,cxx
@@ -3645,6 +3650,11 @@
 ./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
 ./usr/tests/usr.bin/cc/t_hello                 tests-usr.bin-tests     compattestfile,atf
+./usr/tests/usr.bin/cc/t_asan_double_free      tests-usr.bin-tests     compattestfile,atf
+./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_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
 ./usr/tests/usr.bin/cmp/Kyuafile               tests-usr.bin-tests     compattestfile,atf,kyua
diff -r 1c8c2272888b -r 9724fef17341 tests/usr.bin/cc/Makefile
--- a/tests/usr.bin/cc/Makefile Wed Apr 04 22:52:58 2018 +0000
+++ b/tests/usr.bin/cc/Makefile Wed Apr 04 23:51:35 2018 +0000
@@ -1,9 +1,15 @@
-# $NetBSD: Makefile,v 1.1 2012/03/17 17:15:29 jruoho Exp $
+# $NetBSD: Makefile,v 1.2 2018/04/04 23:51:35 kamil Exp $
 
 .include <bsd.own.mk>
 
 TESTSDIR=      ${TESTSBASE}/usr.bin/cc
 
-TESTS_SH=      t_hello
+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_uaf
+TESTS_SH+=     t_hello
 
 .include <bsd.test.mk>
diff -r 1c8c2272888b -r 9724fef17341 tests/usr.bin/cc/t_asan_double_free.sh
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/usr.bin/cc/t_asan_double_free.sh    Wed Apr 04 23:51:35 2018 +0000
@@ -0,0 +1,211 @@
+#      $NetBSD: t_asan_double_free.sh,v 1.1 2018/04/04 23:51:35 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 double_free
+double_free_head() {
+       atf_set "descr" "compile and run \"Double Free example\""
+       atf_set "require.progs" "cc 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" "cc 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" "cc 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" "cc 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" "cc 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.c << 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
+       cc -fsanitize=address -o test test.c
+       paxctl +a test
+       atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"double-free" ./test
+}
+
+double_free_profile_body() {
+       cat > test.c << 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
+       cc -fsanitize=address -o test -pg test.c
+       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.c << EOF
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdio.h>
+int foo(int);
+void main(int argc, char **argv) {foo(argc - 1); printf("CHECK\n"); exit(0);}
+EOF
+       cat > pic.c << 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); }
+EOF
+       cc -fsanitize=address -fPIC -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:"double-free" ./test
+}
+
+double_free_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 <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
+       cc -fsanitize=address -o test -fpie -pie test.c
+       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 ! 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 <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
+       cc -fsanitize=address -o df32 -m32 test.c
+       cc -fsanitize=address -o df64 test.c
+       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
+
+# and another test with profile 32bit binaries
+       cat > test.c << 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
+       cc -fsanitize=address -o test -pg -m32 test.c
+       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"
+}
+
+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.
+}
diff -r 1c8c2272888b -r 9724fef17341 tests/usr.bin/cc/t_asan_global_buffer_overflow.sh
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/usr.bin/cc/t_asan_global_buffer_overflow.sh Wed Apr 04 23:51:35 2018 +0000
@@ -0,0 +1,211 @@
+#      $NetBSD: t_asan_global_buffer_overflow.sh,v 1.1 2018/04/04 23:51:35 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



Home | Main Index | Thread Index | Old Index