Skip to content

Commit 6a3e53a

Browse files
committed
add 9 usual fuzzers
1 parent aff1970 commit 6a3e53a

File tree

145 files changed

+6760
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

145 files changed

+6760
-0
lines changed

fuzzers/afl_t0/builder.Dockerfile

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
ARG parent_image
16+
FROM $parent_image
17+
18+
# Download and compile AFL v2.57b.
19+
# Set AFL_NO_X86 to skip flaky tests.
20+
RUN git clone \
21+
--depth 1 \
22+
--branch v2.57b \
23+
https://github.com/google/AFL.git /afl && \
24+
cd /afl && \
25+
CFLAGS= CXXFLAGS= AFL_NO_X86=1 make
26+
27+
# Use afl_driver.cpp from LLVM as our fuzzing library.
28+
RUN apt-get update && \
29+
apt-get install wget -y && \
30+
wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/afl_driver.cpp && \
31+
clang -Wno-pointer-sign -c /afl/llvm_mode/afl-llvm-rt.o.c -I/afl && \
32+
clang++ -stdlib=libc++ -std=c++11 -O2 -c /afl/afl_driver.cpp && \
33+
ar r /libAFL.a *.o

fuzzers/afl_t0/fuzzer.py

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""Integration code for AFL fuzzer."""
15+
16+
import json
17+
import os
18+
import shutil
19+
import subprocess
20+
21+
from fuzzers import utils
22+
23+
24+
def prepare_build_environment():
25+
"""Set environment variables used to build targets for AFL-based
26+
fuzzers."""
27+
cflags = ['-fsanitize-coverage=trace-pc-guard']
28+
utils.append_flags('CFLAGS', cflags)
29+
utils.append_flags('CXXFLAGS', cflags)
30+
31+
os.environ['CC'] = 'clang'
32+
os.environ['CXX'] = 'clang++'
33+
os.environ['FUZZER_LIB'] = '/libAFL.a'
34+
35+
36+
def build():
37+
"""Build benchmark."""
38+
prepare_build_environment()
39+
40+
utils.build_benchmark()
41+
42+
print('[post_build] Copying afl-fuzz to $OUT directory')
43+
# Copy out the afl-fuzz binary as a build artifact.
44+
shutil.copy('/afl/afl-fuzz', os.environ['OUT'])
45+
46+
47+
def get_stats(output_corpus, fuzzer_log): # pylint: disable=unused-argument
48+
"""Gets fuzzer stats for AFL."""
49+
# Get a dictionary containing the stats AFL reports.
50+
stats_file = os.path.join(output_corpus, 'fuzzer_stats')
51+
if not os.path.exists(stats_file):
52+
print('Can\'t find fuzzer_stats')
53+
return '{}'
54+
with open(stats_file, encoding='utf-8') as file_handle:
55+
stats_file_lines = file_handle.read().splitlines()
56+
stats_file_dict = {}
57+
for stats_line in stats_file_lines:
58+
key, value = stats_line.split(': ')
59+
stats_file_dict[key.strip()] = value.strip()
60+
61+
# Report to FuzzBench the stats it accepts.
62+
stats = {'execs_per_sec': float(stats_file_dict['execs_per_sec'])}
63+
return json.dumps(stats)
64+
65+
66+
def prepare_fuzz_environment(input_corpus):
67+
"""Prepare to fuzz with AFL or another AFL-based fuzzer."""
68+
# Tell AFL to not use its terminal UI so we get usable logs.
69+
os.environ['AFL_NO_UI'] = '1'
70+
# Skip AFL's CPU frequency check (fails on Docker).
71+
os.environ['AFL_SKIP_CPUFREQ'] = '1'
72+
# No need to bind affinity to one core, Docker enforces 1 core usage.
73+
os.environ['AFL_NO_AFFINITY'] = '1'
74+
# AFL will abort on startup if the core pattern sends notifications to
75+
# external programs. We don't care about this.
76+
os.environ['AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES'] = '1'
77+
# Don't exit when crashes are found. This can happen when corpus from
78+
# OSS-Fuzz is used.
79+
os.environ['AFL_SKIP_CRASHES'] = '1'
80+
# Shuffle the queue
81+
os.environ['AFL_SHUFFLE_QUEUE'] = '1'
82+
83+
# AFL needs at least one non-empty seed to start.
84+
utils.create_seed_file_for_empty_corpus(input_corpus)
85+
86+
87+
def check_skip_det_compatible(additional_flags):
88+
""" Checks if additional flags are compatible with '-d' option"""
89+
# AFL refuses to take in '-d' with '-M' or '-S' options for parallel mode.
90+
# (cf. https://github.com/google/AFL/blob/8da80951/afl-fuzz.c#L7477)
91+
if '-M' in additional_flags or '-S' in additional_flags:
92+
return False
93+
return True
94+
95+
96+
def run_afl_fuzz(input_corpus,
97+
output_corpus,
98+
target_binary,
99+
additional_flags=None,
100+
hide_output=False):
101+
"""Run afl-fuzz."""
102+
# Spawn the afl fuzzing process.
103+
print('[run_afl_fuzz] Running target with afl-fuzz')
104+
command = [
105+
'./afl-fuzz',
106+
'-i',
107+
input_corpus,
108+
'-o',
109+
output_corpus,
110+
# Use no memory limit as ASAN doesn't play nicely with one.
111+
'-m',
112+
'none',
113+
'-t',
114+
'1000+', # Use same default 1 sec timeout, but add '+' to skip hangs.
115+
]
116+
# Use '-d' to skip deterministic mode, as long as it it compatible with
117+
# additional flags.
118+
if not additional_flags or check_skip_det_compatible(additional_flags):
119+
command.append('-d')
120+
if additional_flags:
121+
command.extend(additional_flags)
122+
dictionary_path = utils.get_dictionary_path(target_binary)
123+
if dictionary_path:
124+
command.extend(['-x', dictionary_path])
125+
command += [
126+
'--',
127+
target_binary,
128+
# Pass INT_MAX to afl the maximize the number of persistent loops it
129+
# performs.
130+
'2147483647'
131+
]
132+
print('[run_afl_fuzz] Running command: ' + ' '.join(command))
133+
output_stream = subprocess.DEVNULL if hide_output else None
134+
subprocess.check_call(command, stdout=output_stream, stderr=output_stream)
135+
136+
137+
def fuzz(input_corpus, output_corpus, target_binary):
138+
"""Run afl-fuzz on target."""
139+
prepare_fuzz_environment(input_corpus)
140+
141+
run_afl_fuzz(input_corpus, output_corpus, target_binary)

fuzzers/afl_t0/runner.Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
FROM gcr.io/fuzzbench/base-image

fuzzers/afl_t1/builder.Dockerfile

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
ARG parent_image
16+
FROM $parent_image
17+
18+
# Download and compile AFL v2.57b.
19+
# Set AFL_NO_X86 to skip flaky tests.
20+
RUN git clone \
21+
--depth 1 \
22+
--branch v2.57b \
23+
https://github.com/google/AFL.git /afl && \
24+
cd /afl && \
25+
CFLAGS= CXXFLAGS= AFL_NO_X86=1 make
26+
27+
# Use afl_driver.cpp from LLVM as our fuzzing library.
28+
RUN apt-get update && \
29+
apt-get install wget -y && \
30+
wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/afl_driver.cpp && \
31+
clang -Wno-pointer-sign -c /afl/llvm_mode/afl-llvm-rt.o.c -I/afl && \
32+
clang++ -stdlib=libc++ -std=c++11 -O2 -c /afl/afl_driver.cpp && \
33+
ar r /libAFL.a *.o

fuzzers/afl_t1/fuzzer.py

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""Integration code for AFL fuzzer."""
15+
16+
import json
17+
import os
18+
import shutil
19+
import subprocess
20+
21+
from fuzzers import utils
22+
23+
24+
def prepare_build_environment():
25+
"""Set environment variables used to build targets for AFL-based
26+
fuzzers."""
27+
cflags = ['-fsanitize-coverage=trace-pc-guard']
28+
utils.append_flags('CFLAGS', cflags)
29+
utils.append_flags('CXXFLAGS', cflags)
30+
31+
os.environ['CC'] = 'clang'
32+
os.environ['CXX'] = 'clang++'
33+
os.environ['FUZZER_LIB'] = '/libAFL.a'
34+
35+
36+
def build():
37+
"""Build benchmark."""
38+
prepare_build_environment()
39+
40+
utils.build_benchmark()
41+
42+
print('[post_build] Copying afl-fuzz to $OUT directory')
43+
# Copy out the afl-fuzz binary as a build artifact.
44+
shutil.copy('/afl/afl-fuzz', os.environ['OUT'])
45+
46+
47+
def get_stats(output_corpus, fuzzer_log): # pylint: disable=unused-argument
48+
"""Gets fuzzer stats for AFL."""
49+
# Get a dictionary containing the stats AFL reports.
50+
stats_file = os.path.join(output_corpus, 'fuzzer_stats')
51+
if not os.path.exists(stats_file):
52+
print('Can\'t find fuzzer_stats')
53+
return '{}'
54+
with open(stats_file, encoding='utf-8') as file_handle:
55+
stats_file_lines = file_handle.read().splitlines()
56+
stats_file_dict = {}
57+
for stats_line in stats_file_lines:
58+
key, value = stats_line.split(': ')
59+
stats_file_dict[key.strip()] = value.strip()
60+
61+
# Report to FuzzBench the stats it accepts.
62+
stats = {'execs_per_sec': float(stats_file_dict['execs_per_sec'])}
63+
return json.dumps(stats)
64+
65+
66+
def prepare_fuzz_environment(input_corpus):
67+
"""Prepare to fuzz with AFL or another AFL-based fuzzer."""
68+
# Tell AFL to not use its terminal UI so we get usable logs.
69+
os.environ['AFL_NO_UI'] = '1'
70+
# Skip AFL's CPU frequency check (fails on Docker).
71+
os.environ['AFL_SKIP_CPUFREQ'] = '1'
72+
# No need to bind affinity to one core, Docker enforces 1 core usage.
73+
os.environ['AFL_NO_AFFINITY'] = '1'
74+
# AFL will abort on startup if the core pattern sends notifications to
75+
# external programs. We don't care about this.
76+
os.environ['AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES'] = '1'
77+
# Don't exit when crashes are found. This can happen when corpus from
78+
# OSS-Fuzz is used.
79+
os.environ['AFL_SKIP_CRASHES'] = '1'
80+
# Shuffle the queue
81+
os.environ['AFL_SHUFFLE_QUEUE'] = '1'
82+
83+
# AFL needs at least one non-empty seed to start.
84+
utils.create_seed_file_for_empty_corpus(input_corpus)
85+
86+
87+
def check_skip_det_compatible(additional_flags):
88+
""" Checks if additional flags are compatible with '-d' option"""
89+
# AFL refuses to take in '-d' with '-M' or '-S' options for parallel mode.
90+
# (cf. https://github.com/google/AFL/blob/8da80951/afl-fuzz.c#L7477)
91+
if '-M' in additional_flags or '-S' in additional_flags:
92+
return False
93+
return True
94+
95+
96+
def run_afl_fuzz(input_corpus,
97+
output_corpus,
98+
target_binary,
99+
additional_flags=None,
100+
hide_output=False):
101+
"""Run afl-fuzz."""
102+
# Spawn the afl fuzzing process.
103+
print('[run_afl_fuzz] Running target with afl-fuzz')
104+
command = [
105+
'./afl-fuzz',
106+
'-i',
107+
input_corpus,
108+
'-o',
109+
output_corpus,
110+
# Use no memory limit as ASAN doesn't play nicely with one.
111+
'-m',
112+
'none',
113+
'-t',
114+
'1000+', # Use same default 1 sec timeout, but add '+' to skip hangs.
115+
]
116+
# Use '-d' to skip deterministic mode, as long as it it compatible with
117+
# additional flags.
118+
if not additional_flags or check_skip_det_compatible(additional_flags):
119+
command.append('-d')
120+
if additional_flags:
121+
command.extend(additional_flags)
122+
dictionary_path = utils.get_dictionary_path(target_binary)
123+
if dictionary_path:
124+
command.extend(['-x', dictionary_path])
125+
command += [
126+
'--',
127+
target_binary,
128+
# Pass INT_MAX to afl the maximize the number of persistent loops it
129+
# performs.
130+
'2147483647'
131+
]
132+
print('[run_afl_fuzz] Running command: ' + ' '.join(command))
133+
output_stream = subprocess.DEVNULL if hide_output else None
134+
subprocess.check_call(command, stdout=output_stream, stderr=output_stream)
135+
136+
137+
def fuzz(input_corpus, output_corpus, target_binary):
138+
"""Run afl-fuzz on target."""
139+
prepare_fuzz_environment(input_corpus)
140+
141+
run_afl_fuzz(input_corpus, output_corpus, target_binary)

fuzzers/afl_t1/runner.Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
FROM gcr.io/fuzzbench/base-image

0 commit comments

Comments
 (0)