t_asan_global_buffer_overflow.sh revision 1.2
1#	$NetBSD: t_asan_global_buffer_overflow.sh,v 1.2 2018/07/16 07:25:58 kamil Exp $
2#
3# Copyright (c) 2018 The NetBSD Foundation, Inc.
4# All rights reserved.
5#
6# This code is derived from software contributed to The NetBSD Foundation
7# by Siddharth Muralee.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions
11# are met:
12# 1. Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14# 2. Redistributions in binary form must reproduce the above copyright
15#    notice, this list of conditions and the following disclaimer in the
16#    documentation and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29#
30
31SUPPORT='n'
32test_target() {
33	if uname -m | grep -q "amd64"; then
34		SUPPORT='y'
35	fi
36
37	if uname -m | grep -q "i386"; then
38		SUPPORT='y'
39	fi
40}
41
42atf_test_case global_buffer_overflow
43global_buffer_overflow_head() {
44	atf_set "descr" "compile and run \"Global Buffer Overflow example\""
45	atf_set "require.progs" "cc paxctl"
46}
47
48atf_test_case global_buffer_overflow_profile
49global_buffer_overflow_profile_head() {
50	atf_set "descr" "compile and run \"Global Buffer Overflow example\" with profiling option"
51	atf_set "require.progs" "cc paxctl"
52}
53
54atf_test_case global_buffer_overflow_pic
55global_buffer_overflow_pic_head() {
56	atf_set "descr" "compile and run PIC \"Global Buffer Overflow example\""
57	atf_set "require.progs" "cc paxctl"
58}
59
60atf_test_case global_buffer_overflow_pie
61global_buffer_overflow_pie_head() {
62	atf_set "descr" "compile and run position independent (PIE) \"Global Buffer Overflow example\""
63	atf_set "require.progs" "cc paxctl"
64}
65
66atf_test_case global_buffer_overflow32
67global_buffer_overflow32_head() {
68	atf_set "descr" "compile and run \"Global Buffer Overflow example\" for/in netbsd32 emulation"
69	atf_set "require.progs" "cc paxctl file diff cat"
70}
71
72atf_test_case target_not_supported
73target_not_supported_head()
74{
75	atf_set "descr" "Test forced skip"
76}
77
78global_buffer_overflow_body() {
79	cat > test.c << EOF
80#include <stdio.h>
81#include <stdlib.h>
82int arr[5] = {-1};
83void foo(int index) { arr[index] = 0; }
84void main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);}
85EOF
86	cc -fsanitize=address -o test test.c
87	paxctl -a test
88	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./test
89}
90
91global_buffer_overflow_profile_body() {
92	cat > test.c << EOF
93#include <stdio.h>
94#include <stdlib.h>
95int arr[5] = {-1};
96void foo(int index) { arr[index] = 0; }
97void main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);}
98EOF
99	cc -fsanitize=address -o test -pg test.c
100	paxctl +a test
101	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./test
102}
103
104global_buffer_overflow_pic_body() {
105	cat > test.c << EOF
106#include <stdio.h>
107#include <stdlib.h>
108void foo(int);
109void main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);}
110EOF
111	cat > pic.c << EOF
112#include <stdio.h>
113#include <stdlib.h>
114int arr[5] = {-1};
115void foo(int index) { arr[index] = 0; }
116EOF
117
118	cc -fPIC -fsanitize=address -shared -o libtest.so pic.c
119	cc -o test test.c -fsanitize=address -L. -ltest
120	paxctl +a test
121
122	export LD_LIBRARY_PATH=.
123	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./test
124}
125
126global_buffer_overflow_pie_body() {
127	# check whether this arch supports -pice
128	if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then
129		atf_set_skip "cc -pie not supported on this architecture"
130	fi
131	cat > test.c << EOF
132#include <stdio.h>
133#include <stdlib.h>
134int arr[5] = {-1};
135void foo(int index) { arr[index] = 0; }
136void main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);}
137EOF
138	cc -fsanitize=address -fpie -pie -o test test.c
139	paxctl +a test
140	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./test
141}
142
143global_buffer_overflow32_body() {
144	# check whether this arch is 64bit
145	if ! cc -dM -E - < /dev/null | fgrep -q _LP64; then
146		atf_skip "this is not a 64 bit architecture"
147	fi
148	if ! cc -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
149		atf_skip "cc -m32 not supported on this architecture"
150	else
151		if fgrep -q _LP64 ./def32; then
152		atf_fail "cc -m32 does not generate netbsd32 binaries"
153	fi
154fi
155
156	cat > test.c << EOF
157#include <stdio.h>
158#include <stdlib.h>
159int arr[5] = {-1};
160void foo(int index) { arr[index] = 0; }
161void main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);}
162EOF
163	cc -fsanitize=address -o gbof32 -m32 test.c
164	cc -fsanitize=address -o gbof64 test.c
165	file -b ./gbof32 > ./ftype32
166	file -b ./gbof64 > ./ftype64
167	if diff ./ftype32 ./ftype64 >/dev/null; then
168		atf_fail "generated binaries do not differ"
169	fi
170	echo "32bit binaries on this platform are:"
171	cat ./ftype32
172	echo "While native (64bit) binaries are:"
173	cat ./ftype64
174	paxctl +a gbof32
175	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./gbof32
176
177# and another test with profile 32bit binaries
178	cat > test.c << EOF
179#include <stdio.h>
180#include <stdlib.h>
181int arr[5] = {-1};
182void foo(int index) { arr[index] = 0; }
183void main(int argc, char **argv) {foo(argc + 5); printf("CHECK\n"); exit(0);}
184EOF
185	cc -o test -m32 -fsanitize=address -pg test.c
186	paxctl +a test
187	atf_check -s not-exit:0 -o not-match:"CHECK\n" -e match:"global-buffer-overflow" ./test
188}
189
190target_not_supported_body()
191{
192	atf_skip "Target is not supported"
193}
194
195atf_init_test_cases()
196{
197	test_target
198	test $SUPPORT = 'n' && {
199		atf_add_test_case target_not_supported
200		return 0
201	}
202
203	atf_add_test_case global_buffer_overflow
204#	atf_add_test_case global_buffer_overflow_profile
205	atf_add_test_case global_buffer_overflow_pic
206	atf_add_test_case global_buffer_overflow_pie
207#	atf_add_test_case global_buffer_overflow32
208	# static option not supported
209	# -static and -fsanitize=address can't be used together for compilation
210	# (gcc version  5.4.0 and clang 7.1) tested on April 2nd 2018.
211}
212