t_asan_heap_overflow.sh revision 1.1
11.1Skamil#	$NetBSD: t_asan_heap_overflow.sh,v 1.1 2018/04/04 23:53:26 kamil Exp $
21.1Skamil#
31.1Skamil# Copyright (c) 2018 The NetBSD Foundation, Inc.
41.1Skamil# All rights reserved.
51.1Skamil#
61.1Skamil# This code is derived from software contributed to The NetBSD Foundation
71.1Skamil# by Siddharth Muralee.
81.1Skamil#
91.1Skamil# Redistribution and use in source and binary forms, with or without
101.1Skamil# modification, are permitted provided that the following conditions
111.1Skamil# are met:
121.1Skamil# 1. Redistributions of source code must retain the above copyright
131.1Skamil#    notice, this list of conditions and the following disclaimer.
141.1Skamil# 2. Redistributions in binary form must reproduce the above copyright
151.1Skamil#    notice, this list of conditions and the following disclaimer in the
161.1Skamil#    documentation and/or other materials provided with the distribution.
171.1Skamil#
181.1Skamil# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
191.1Skamil# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
201.1Skamil# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
211.1Skamil# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
221.1Skamil# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
231.1Skamil# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
241.1Skamil# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
251.1Skamil# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
261.1Skamil# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
271.1Skamil# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
281.1Skamil# POSSIBILITY OF SUCH DAMAGE.
291.1Skamil#
301.1Skamil
311.1SkamilSUPPORT='n'
321.1Skamiltest_target() {
331.1Skamil	if uname -m | grep -q "amd64"; then
341.1Skamil		SUPPORT='y'
351.1Skamil	fi
361.1Skamil
371.1Skamil	if uname -m | grep -q "i386"; then
381.1Skamil		SUPPORT='y'
391.1Skamil	fi
401.1Skamil}
411.1Skamil
421.1Skamilatf_test_case heap_overflow
431.1Skamilheap_overflow_head() {
441.1Skamil	atf_set "descr" "compile and run \"Heap Overflow example\""
451.1Skamil	atf_set "require.progs" "c++ paxctl"
461.1Skamil}
471.1Skamil
481.1Skamilatf_test_case heap_overflow_profile
491.1Skamilheap_overflow_profile_head() {
501.1Skamil	atf_set "descr" "compile and run \"Heap Overflow example\" with profiling option"
511.1Skamil	atf_set "require.progs" "c++ paxctl"
521.1Skamil}
531.1Skamil
541.1Skamilatf_test_case heap_overflow_pic
551.1Skamilheap_overflow_pic_head() {
561.1Skamil	atf_set "descr" "compile and run PIC \"Heap Overflow example\""
571.1Skamil	atf_set "require.progs" "c++ paxctl"
581.1Skamil}
591.1Skamil
601.1Skamilatf_test_case heap_overflow_pie
611.1Skamilheap_overflow_pie_head() {
621.1Skamil	atf_set "descr" "compile and run position independent (PIE) \"Heap Overflow example\""
631.1Skamil	atf_set "require.progs" "c++ paxctl"
641.1Skamil}
651.1Skamil
661.1Skamilatf_test_case heap_overflow32
671.1Skamilheap_overflow32_head() {
681.1Skamil	atf_set "descr" "compile and run \"Heap Overflow example\" for/in netbsd32 emulation"
691.1Skamil	atf_set "require.progs" "c++ paxctl file diff cat"
701.1Skamil}
711.1Skamil
721.1Skamilatf_test_case target_not_supported
731.1Skamiltarget_not_supported_head()
741.1Skamil{
751.1Skamil	atf_set "descr" "Test forced skip"
761.1Skamil}
771.1Skamil
781.1Skamilheap_overflow_body() {
791.1Skamil	cat > test.cpp << EOF
801.1Skamil#include <stdio.h>
811.1Skamil#include <stdlib.h>
821.1Skamil#include <string.h>
831.1Skamilint foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;}
841.1Skamilint main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);}
851.1SkamilEOF
861.1Skamil	c++ -fsanitize=address -o test test.cpp
871.1Skamil	paxctl -a test
881.1Skamil	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./test
891.1Skamil}
901.1Skamil
911.1Skamilheap_overflow_profile_body() {
921.1Skamil	cat > test.cpp << EOF
931.1Skamil#include <stdio.h>
941.1Skamil#include <stdlib.h>
951.1Skamil#include <string.h>
961.1Skamilint foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;}
971.1Skamilint main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);}
981.1SkamilEOF
991.1Skamil	c++ -fsanitize=address -o test -pg test.cpp
1001.1Skamil	paxctl +a test
1011.1Skamil	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./test
1021.1Skamil}
1031.1Skamil
1041.1Skamilheap_overflow_pic_body() {
1051.1Skamil	cat > test.cpp << EOF
1061.1Skamil#include <stdio.h>
1071.1Skamil#include <stdlib.h>
1081.1Skamil#include <string.h>
1091.1Skamilint foo(int);
1101.1Skamilint main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);}
1111.1SkamilEOF
1121.1Skamil	cat > pic.cpp << EOF
1131.1Skamil#include <stdio.h>
1141.1Skamil#include <stdlib.h>
1151.1Skamil#include <string.h>
1161.1Skamilint foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;}
1171.1SkamilEOF
1181.1Skamil
1191.1Skamil	c++ -fPIC -fsanitize=address -shared -o libtest.so pic.cpp
1201.1Skamil	c++ -o test test.cpp -fsanitize=address -L. -ltest
1211.1Skamil	paxctl +a test
1221.1Skamil
1231.1Skamil	export LD_LIBRARY_PATH=.
1241.1Skamil	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./test
1251.1Skamil}
1261.1Skamil
1271.1Skamilheap_overflow_pie_body() {
1281.1Skamil	# check whether this arch supports -pice
1291.1Skamil	if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then
1301.1Skamil		atf_set_skip "c++ -pie not supported on this architecture"
1311.1Skamil	fi
1321.1Skamil	cat > test.cpp << EOF
1331.1Skamil#include <stdio.h>
1341.1Skamil#include <stdlib.h>
1351.1Skamil#include <string.h>
1361.1Skamilint foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;}
1371.1Skamilint main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);}
1381.1SkamilEOF
1391.1Skamil	c++ -fsanitize=address -fpie -pie -o test test.cpp
1401.1Skamil	paxctl +a test
1411.1Skamil	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./test
1421.1Skamil}
1431.1Skamil
1441.1Skamilheap_overflow32_body() {
1451.1Skamil	# check whether this arch is 64bit
1461.1Skamil	if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
1471.1Skamil		atf_skip "this is not a 64 bit architecture"
1481.1Skamil	fi
1491.1Skamil	if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
1501.1Skamil		atf_skip "c++ -m32 not supported on this architecture"
1511.1Skamil	else
1521.1Skamil		if fgrep -q _LP64 ./def32; then
1531.1Skamil		atf_fail "c++ -m32 does not generate netbsd32 binaries"
1541.1Skamil	fi
1551.1Skamilfi
1561.1Skamil
1571.1Skamil	cat > test.cpp << EOF
1581.1Skamil#include <stdio.h>
1591.1Skamil#include <stdlib.h>
1601.1Skamil#include <string.h>
1611.1Skamilint foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;}
1621.1Skamilint main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);}
1631.1SkamilEOF
1641.1Skamil	c++ -fsanitize=address -o ho32 -m32 test.cpp
1651.1Skamil	c++ -fsanitize=address -o ho64 test.cpp
1661.1Skamil	file -b ./ho32 > ./ftype32
1671.1Skamil	file -b ./ho64 > ./ftype64
1681.1Skamil	if diff ./ftype32 ./ftype64 >/dev/null; then
1691.1Skamil		atf_fail "generated binaries do not differ"
1701.1Skamil	fi
1711.1Skamil	echo "32bit binaries on this platform are:"
1721.1Skamil	cat ./ftype32
1731.1Skamil	echo "While native (64bit) binaries are:"
1741.1Skamil	cat ./ftype64
1751.1Skamil	paxctl +a ho32
1761.1Skamil	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./ho32
1771.1Skamil
1781.1Skamil# and another test with profile 32bit binaries
1791.1Skamil	cat > test.cpp << EOF
1801.1Skamil#include <stdio.h>
1811.1Skamil#include <stdlib.h>
1821.1Skamil#include <string.h>
1831.1Skamilint foo(int index) { int *x = (int *)malloc(20); int res = x[index * 4]; free(x); return res;}
1841.1Skamilint main(int argc, char **argv) {foo(argc + 19); printf("CHECK\n"); exit(0);}
1851.1SkamilEOF
1861.1Skamil	c++ -o test -m32 -fsanitize=address -pg test.cpp
1871.1Skamil	paxctl +a test
1881.1Skamil	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"heap-buffer-overflow" ./test
1891.1Skamil}
1901.1Skamil
1911.1Skamiltarget_not_supported_body()
1921.1Skamil{
1931.1Skamil	atf_skip "Target is not supported"
1941.1Skamil}
1951.1Skamil
1961.1Skamilatf_init_test_cases()
1971.1Skamil{
1981.1Skamil	test_target
1991.1Skamil	test $SUPPORT = 'n' && {
2001.1Skamil		atf_add_test_case target_not_supported
2011.1Skamil		return 0
2021.1Skamil	}
2031.1Skamil
2041.1Skamil	atf_add_test_case heap_overflow
2051.1Skamil	atf_add_test_case heap_overflow_profile
2061.1Skamil	atf_add_test_case heap_overflow_pic
2071.1Skamil	atf_add_test_case heap_overflow_pie
2081.1Skamil	atf_add_test_case heap_overflow32
2091.1Skamil	# static option not supported
2101.1Skamil	# -static and -fsanitize=address can't be used together for compilation
2111.1Skamil	# (gcc version  5.4.0 and clang 7.1) tested on April 2nd 2018.
2121.1Skamil}
213