aboutsummaryrefslogtreecommitdiffhomepage
path: root/projects/testing-native-go-fuzzing/build.sh
blob: ffd1cb6b5dee392f226539eff19ee8ffa8033918 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/bin/bash -eu
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################

cd $SRC
# Build main binary
git clone https://github.com/AdamKorcz/go-118-fuzz-build
cd go-118-fuzz-build
go build

# Build addimport binary
cd addimport
go build

cd $SRC/vitess

# Remove existing non-native fuzzers to not deal with them
rm go/vt/vtgate/vindexes/fuzz.go

# backup vtctl_fuzzer.go
cp go/test/fuzzing/vtctl_fuzzer.go /tmp/
rm -r go/test/fuzzing/*

mv $SRC/parser_fuzzer_test.go $SRC/vitess/go/test/fuzzing/
mv $SRC/ast_fuzzer_test.go $SRC/vitess/go/test/fuzzing/
mv $SRC/tablet_manager_fuzzer_test.go $SRC/vitess/go/test/fuzzing/


# Disable logging for mysql conn
# This affects the mysql fuzzers
sed -i '/log.Errorf/c\\/\/log.Errorf' $SRC/vitess/go/mysql/conn.go
sed -i '/log.Warningf/c\\/\/log.Warningf' $SRC/vitess/go/vt/sqlparser/parser.go

mv ./go/vt/vttablet/tabletmanager/vreplication/framework_test.go \
   ./go/vt/vttablet/tabletmanager/vreplication/framework_fuzz.go

#consistent_lookup_test.go is needed for loggingVCursor
mv ./go/vt/vtgate/vindexes/consistent_lookup_test.go \
   ./go/vt/vtgate/vindexes/consistent_lookup_test_fuzz.go

# fake_vcursor_test.go is needed for loggingVCursor
mv ./go/vt/vtgate/engine/fake_vcursor_test.go \
    ./go/vt/vtgate/engine/fake_vcursor.go

# plan_test.go is needed for vschemaWrapper
mv ./go/vt/vtgate/planbuilder/plan_test.go \
    ./go/vt/vtgate/planbuilder/plan_test_fuzz.go

# tabletserver fuzzer
mv ./go/vt/vttablet/tabletserver/testutils_test.go \
   ./go/vt/vttablet/tabletserver/testutils_fuzz.go

# collation fuzzer
mv ./go/mysql/collations/uca_test.go \
   ./go/mysql/collations/uca_test_fuzz.go

mv $SRC/vitess/go/vt/vtgate/grpcvtgateconn/suite_test.go \
	   $SRC/vitess/go/vt/vtgate/grpcvtgateconn/suite_test_fuzz.go
mv $SRC/vitess/go/vt/vtgate/grpcvtgateconn/fuzz_flaky_test.go \
	   $SRC/vitess/go/vt/vtgate/grpcvtgateconn/fuzz.go

# build_go_fuzz_harness rewrites a copy of the 
# fuzzer to allow for libFuzzer instrumentation
function rewrite_go_fuzz_harness() {
	fuzzer_filename=$1

        # Create a copy of the fuzzer to not modify the existing fuzzer
        cp $fuzzer_filename "${fuzzer_filename}"_fuzz_.go
	mv $fuzzer_filename /tmp/

        # replace *testing.F with *go118fuzzbuildutils.F
        echo "replacing *testing.F"
        sed -i 's/f \*testing\.F/f \*go118fuzzbuildutils\.F/g' "${fuzzer_filename}"_fuzz_.go

        # import https://github.com/AdamKorcz/go-118-fuzz-build
        # This changes the line numbers from the original fuzzer
	$SRC/go-118-fuzz-build/addimport/addimport -path "${fuzzer_filename}"_fuzz_.go
}

function compile_native_go_fuzzer() {
	fuzzer=$1
	function=$2
	path=$3
	tags="-tags gofuzz"

	if [[ $SANITIZER = *coverage* ]]; then
		echo "here we perform coverage build"
		fuzzed_package=`go list $tags -f '{{.Name}}' $path`
		abspath=`go list $tags -f {{.Dir}} $path`
		cd $abspath
		cp $SRC/native_ossfuzz_coverage_runnger.go ./"${function,,}"_test.go
		sed -i -e 's/FuzzFunction/'$function'/' ./"${function,,}"_test.go
		sed -i -e 's/mypackagebeingfuzzed/'$fuzzed_package'/' ./"${function,,}"_test.go
		sed -i -e 's/TestFuzzCorpus/Test'$function'Corpus/' ./"${function,,}"_test.go

		# The repo is the module path/name, which is already created above in case it doesn't exist,
		# but not always the same as the module path. This is necessary to handle SIV properly.
		fuzzed_repo=$(go list $tags -f {{.Module}} "$path")
		abspath_repo=`go list -m $tags -f {{.Dir}} $fuzzed_repo || go list $tags -f {{.Dir}} $fuzzed_repo`
		# give equivalence to absolute paths in another file, as go test -cover uses golangish pkg.Dir
		echo "s=$fuzzed_repo"="$abspath_repo"= > $OUT/$fuzzer.gocovpath
		ls
		gotip test -run Test${function}Corpus -v $tags -coverpkg $fuzzed_repo/... -c -o $OUT/$fuzzer $path
		
		rm ./"${function,,}"_test.go
	else
	        $SRC/go-118-fuzz-build/go-118-fuzz-build -o $fuzzer.a -func $function $abs_file_dir
        	$CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
	fi
}

# build_go_fuzzer will be the api used by users
# The api is now placed in this build script
# but will be moved to the base image once it
# has reached sufficient maturity.
function build_go_fuzzer () {
        path=$1
        function=$2
	fuzzer=$3
        tags="-tags gofuzz"

        # Get absolute path
        abs_file_dir=$(go list $tags -f {{.Dir}} $path)

        # TODO: Get rid of "-r" flag here
        fuzzer_filename=$(grep -r -l  -s "$function" "${abs_file_dir}")
	
	# test if file contains a line with "func $function" and "testing.F"
	if [ $(grep -r "func $function" $fuzzer_filename | grep "testing.F" | wc -l) -eq 1 ]
	then
		# we are dealing with a native harness

	        # Install more dependencies
		gotip get github.com/AdamKorcz/go-118-fuzz-build/utils
		gotip get google.golang.org/grpc/internal/channelz@v1.39.0
	
		echo "Native harness"
		rewrite_go_fuzz_harness $fuzzer_filename
		compile_native_go_fuzzer $fuzzer $function $abs_file_dir
		# clean up
		rm "${fuzzer_filename}_fuzz_.go"
		mv /tmp/$(basename $fuzzer_filename) $fuzzer_filename
	else
		# we are dealing with a go-fuzz harness
		echo "go-fuzz harness"
		compile_go_fuzzer $path $function $fuzzer $tags
	fi
	
}

# build native fuzzers
build_go_fuzzer vitess.io/vitess/go/test/fuzzing FuzzTabletManager_ExecuteFetchAsDba fuzz_tablet_manager_execute_fetch_as_dba
build_go_fuzzer vitess.io/vitess/go/test/fuzzing FuzzParser parser_fuzzer
build_go_fuzzer vitess.io/vitess/go/test/fuzzing FuzzIsDML is_dml_fuzzer
build_go_fuzzer vitess.io/vitess/go/test/fuzzing FuzzNormalizer normalizer_fuzzer
build_go_fuzzer vitess.io/vitess/go/test/fuzzing FuzzNodeFormat normalizer_fuzzer
build_go_fuzzer vitess.io/vitess/go/test/fuzzing FuzzSplitStatementToPieces fuzz_split_statement_to_pieces
build_go_fuzzer vitess.io/vitess/go/test/fuzzing FuzzEqualsSQLNode fuzz_equals_sql_node

# Delete all the native fuzzers before building the go-fuzz fuzzer(s)
# this will not be necessary when Go 1.18 is released. The reason this
# is needed is because go114-fuzz-build calls "go" instead of "gotip",
# and an error will be thrown because testing.F is not recognized.
rm $SRC/vitess/go/test/fuzzing/*_test.go

# build go-fuzz fuzzers
mv /tmp/vtctl_fuzzer.go $SRC/vitess/go/test/fuzzing/
build_go_fuzzer vitess.io/vitess/go/test/fuzzing Fuzz vtctl_fuzzer