Skip to content

Commit 09ec799

Browse files
Add support for honggfuzz in gcc mode
Adds the flag --@rules_fuzzing//fuzzing:compiler_type with possible configurations "cmake" and "gcc". This allows running honggfuzz with a gcc toolchain which can be useful for code bases that don't compile with clang or where no clang toolchain is available. Co-authored-by: Markus Zoppelt <markus.zoppelt@code-intelligence.com>
1 parent 48c7e37 commit 09ec799

File tree

7 files changed

+106
-38
lines changed

7 files changed

+106
-38
lines changed

.bazelrc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
# Force the use of Clang for all builds.
15+
# Set clang as the default compiler for most configurations.
1616
build --repo_env=CC=clang
1717

1818
# Needed for abseil-cpp until https://github.com/bazelbuild/bazel/pull/19794 is released.
@@ -74,6 +74,13 @@ build:ubsan-honggfuzz --//fuzzing:cc_engine=//fuzzing/engines:honggfuzz
7474
build:ubsan-honggfuzz --@rules_fuzzing//fuzzing:cc_engine_instrumentation=honggfuzz
7575
build:ubsan-honggfuzz --@rules_fuzzing//fuzzing:cc_engine_sanitizer=ubsan
7676

77+
# Honggfuzz + ASAN (GCC)
78+
build:asan-honggfuzz-gcc --//fuzzing:cc_engine=//fuzzing/engines:honggfuzz
79+
build:asan-honggfuzz-gcc --@rules_fuzzing//fuzzing:cc_engine_instrumentation=honggfuzz
80+
build:asan-honggfuzz-gcc --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan
81+
build:asan-honggfuzz-gcc --repo_env=CC=gcc
82+
build:asan-honggfuzz-gcc --@rules_fuzzing//fuzzing:compiler_type=gcc
83+
7784
# Replay + ASAN
7885
build:asan-replay --//fuzzing:cc_engine=//fuzzing/engines:replay
7986
build:asan-replay --@rules_fuzzing//fuzzing:cc_engine_instrumentation=none

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ This section will walk you through the steps to set up fuzzing in your Bazel pro
3535

3636
The fuzzing rules have been tested on Bazel 4.0.0 or later. Check your Bazel version by running `bazel --version`.
3737

38-
C++ fuzzing requires a Clang compiler. The libFuzzer engine requires at least Clang 6.0. In addition, the Honggfuzz engine requires the `libunwind-dev` and `libblocksruntime-dev` packages:
38+
The libFuzzer engine requires at least Clang 6.0. Honggfuzz works with both clang and gcc (8 or later) and requires the `libunwind-dev` and `libblocksruntime-dev` packages:
3939

4040
```sh
41-
$ sudo apt-get install clang libunwind-dev libblocksruntime-dev
41+
$ sudo apt-get install libunwind-dev libblocksruntime-dev
4242
```
4343

4444
Java fuzzing requires Clang and the LLD linker:

fuzzing/BUILD

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,22 @@ bool_flag(
7373
visibility = ["//visibility:public"],
7474
)
7575

76+
string_flag(
77+
name = "compiler_type",
78+
build_setting_default = "clang",
79+
values = [
80+
"clang",
81+
"gcc",
82+
],
83+
visibility = ["//visibility:public"],
84+
)
85+
86+
config_setting(
87+
name = "is_gcc",
88+
flag_values = {":compiler_type": "gcc"},
89+
visibility = ["//visibility:public"],
90+
)
91+
7692
exports_files([
7793
"cc_defs.bzl",
7894
"java_defs.bzl",

fuzzing/instrum_opts.bzl

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,35 @@ load(
2929
"oss_fuzz_opts",
3030
)
3131

32-
# Fuzz test binary instrumentation configurations.
32+
# Fuzz test binary instrumentation configurations by compiler type.
3333
instrum_configs = {
34-
"none": instrum_opts.make(),
35-
"libfuzzer": instrum_defaults.libfuzzer,
36-
"jazzer": instrum_defaults.jazzer,
37-
"honggfuzz": instrum_defaults.honggfuzz,
38-
"oss-fuzz": oss_fuzz_opts,
34+
"clang": {
35+
"none": instrum_opts.make(),
36+
"libfuzzer": instrum_defaults.libfuzzer,
37+
"jazzer": instrum_defaults.jazzer,
38+
"honggfuzz": instrum_defaults.honggfuzz_clang,
39+
"oss-fuzz": oss_fuzz_opts,
40+
},
41+
"gcc": {
42+
"none": instrum_opts.make(),
43+
"honggfuzz": instrum_defaults.honggfuzz_gcc,
44+
},
3945
}
4046

41-
# Sanitizer configurations.
47+
# Sanitizer configurations by compiler type.
4248
sanitizer_configs = {
43-
"none": instrum_opts.make(),
44-
"asan": instrum_defaults.asan,
45-
"msan": instrum_defaults.msan,
46-
"msan-origin-tracking": instrum_defaults.msan_origin_tracking,
47-
"ubsan": instrum_defaults.ubsan,
48-
"asan-ubsan": instrum_opts.merge(instrum_defaults.asan, instrum_defaults.ubsan),
49+
"clang": {
50+
"none": instrum_opts.make(),
51+
"asan": instrum_defaults.asan,
52+
"msan": instrum_defaults.msan,
53+
"msan-origin-tracking": instrum_defaults.msan_origin_tracking,
54+
"ubsan": instrum_defaults.ubsan_clang,
55+
"asan-ubsan": instrum_opts.merge(instrum_defaults.asan, instrum_defaults.ubsan_clang),
56+
},
57+
"gcc": {
58+
"none": instrum_opts.make(),
59+
"asan": instrum_defaults.asan,
60+
"ubsan": instrum_defaults.ubsan_gcc,
61+
"asan-ubsan": instrum_opts.merge(instrum_defaults.asan, instrum_defaults.ubsan_gcc),
62+
},
4963
}

fuzzing/private/binary.bzl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,23 @@ def _fuzzing_binary_transition_impl(settings, _attr):
5454
cxxopts = settings["//command_line_option:cxxopt"],
5555
linkopts = settings["//command_line_option:linkopt"],
5656
)
57+
compiler_type = settings["@rules_fuzzing//fuzzing:compiler_type"]
5758

5859
is_fuzzing_build_mode = settings["@rules_fuzzing//fuzzing:cc_fuzzing_build_mode"]
5960
if is_fuzzing_build_mode:
6061
opts = instrum_opts.merge(opts, instrum_defaults.fuzzing_build)
6162

6263
instrum_config = settings["@rules_fuzzing//fuzzing:cc_engine_instrumentation"]
63-
if instrum_config in instrum_configs:
64-
opts = instrum_opts.merge(opts, instrum_configs[instrum_config])
64+
if instrum_config in instrum_configs[compiler_type]:
65+
opts = instrum_opts.merge(opts, instrum_configs[compiler_type][instrum_config])
6566
else:
66-
fail("unsupported engine instrumentation '%s'" % instrum_config)
67+
fail("unsupported engine instrumentation '%s' for compiler '%s'" % (instrum_config, compiler_type))
6768

6869
sanitizer_config = settings["@rules_fuzzing//fuzzing:cc_engine_sanitizer"]
69-
if sanitizer_config in sanitizer_configs:
70-
opts = instrum_opts.merge(opts, sanitizer_configs[sanitizer_config])
70+
if sanitizer_config in sanitizer_configs[compiler_type]:
71+
opts = instrum_opts.merge(opts, sanitizer_configs[compiler_type][sanitizer_config])
7172
else:
72-
fail("unsupported sanitizer '%s'" % sanitizer_config)
73+
fail("unsupported sanitizer '%s' for compiler '%s'" % (sanitizer_config, compiler_type))
7374

7475
return {
7576
"//command_line_option:copt": opts.copts,
@@ -87,6 +88,7 @@ fuzzing_binary_transition = transition(
8788
"@rules_fuzzing//fuzzing:cc_engine_instrumentation",
8889
"@rules_fuzzing//fuzzing:cc_engine_sanitizer",
8990
"@rules_fuzzing//fuzzing:cc_fuzzing_build_mode",
91+
"@rules_fuzzing//fuzzing:compiler_type",
9092
"//command_line_option:copt",
9193
"//command_line_option:conlyopt",
9294
"//command_line_option:cxxopt",

fuzzing/private/instrum_opts.bzl

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ instrum_defaults = struct(
9191
),
9292
# Reflects the set of options at
9393
# https://github.com/google/honggfuzz/blob/master/hfuzz_cc/hfuzz-cc.c
94-
honggfuzz = _make_opts(
94+
honggfuzz_clang = _make_opts(
9595
copts = [
9696
"-mllvm",
9797
"-inline-threshold=2000",
@@ -105,6 +105,16 @@ instrum_defaults = struct(
105105
"-fno-sanitize=fuzzer",
106106
],
107107
),
108+
honggfuzz_gcc = _make_opts(
109+
copts = [
110+
"-finline-limit=1000",
111+
"-fsanitize-coverage=trace-pc,trace-cmp",
112+
"-fno-builtin",
113+
"-fno-omit-frame-pointer",
114+
"-D__NO_STRING_INLINES",
115+
],
116+
linkopts = [],
117+
),
108118
asan = _make_opts(
109119
copts = ["-fsanitize=address"],
110120
linkopts = ["-fsanitize=address"],
@@ -120,7 +130,7 @@ instrum_defaults = struct(
120130
],
121131
linkopts = ["-fsanitize=memory"],
122132
),
123-
ubsan = _make_opts(
133+
ubsan_clang = _make_opts(
124134
copts = [
125135
"-fsanitize=undefined",
126136
],
@@ -133,4 +143,12 @@ instrum_defaults = struct(
133143
"-fsanitize-link-c++-runtime",
134144
],
135145
),
146+
ubsan_gcc = _make_opts(
147+
copts = [
148+
"-fsanitize=undefined",
149+
],
150+
linkopts = [
151+
"-fsanitize=undefined",
152+
],
153+
),
136154
)

honggfuzz.BUILD

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,31 @@ COMMON_COPTS = [
3434
"-Wall",
3535
"-Wextra",
3636
"-Werror",
37-
"-Wno-override-init",
38-
"-Wno-initializer-overrides",
39-
"-Wno-gnu-empty-initializer",
40-
"-Wno-format-pedantic",
41-
"-Wno-gnu-statement-expression",
42-
"-mllvm",
43-
"-inline-threshold=2000",
44-
"-fblocks",
45-
46-
# Do not instrument Honggfuzz itself, in order to avoid recursive
47-
# instrumentation calls that would crash the fuzz test binary.
48-
"-fsanitize-coverage=0",
49-
"-fno-sanitize=all",
50-
]
37+
] + select({
38+
"@rules_fuzzing//fuzzing:is_gcc": [
39+
"-Wno-override-init",
40+
"-Wno-format-truncation",
41+
# Do not instrument Honggfuzz itself, in order to avoid recursive
42+
# instrumentation calls that would crash the fuzz test binary.
43+
"-fno-sanitize-coverage=trace-pc,trace-cmp",
44+
"-fno-sanitize=all",
45+
],
46+
# Default to clang compiler flags
47+
"//conditions:default": [
48+
"-mllvm",
49+
"-inline-threshold=2000",
50+
"-fblocks",
51+
"-Wno-override-init",
52+
"-Wno-initializer-overrides",
53+
"-Wno-gnu-empty-initializer",
54+
"-Wno-format-pedantic",
55+
"-Wno-gnu-statement-expression",
56+
# Do not instrument Honggfuzz itself, in order to avoid recursive
57+
# instrumentation calls that would crash the fuzz test binary.
58+
"-fsanitize-coverage=0",
59+
"-fno-sanitize=all",
60+
],
61+
})
5162

5263
LIBRARY_COPTS = [
5364
"-fno-stack-protector",

0 commit comments

Comments
 (0)