Skip to content

Commit 75e18d4

Browse files
committed
add cifuzz bazel example project
0 parents  commit 75e18d4

17 files changed

+3096
-0
lines changed

.bazelrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
coverage --java_runtime_version=remotejdk_11

.bazelversion

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7.3.1

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/.cifuzz-*/
2+
/bazel-*

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/bazel-*
2+
*_inputs
3+
.*_cifuzz_corpus/
4+
/.cifuzz-*/
5+
/.ijwb/
6+
/.clwb/

BUILD.bazel

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
load("@rules_cc//cc:defs.bzl", "cc_binary")
2+
3+
cc_binary(
4+
name = "main",
5+
srcs = ["main.cpp"],
6+
deps = ["//src:explore_me"],
7+
)

Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM ubuntu:22.04
2+
3+
WORKDIR /work
4+
5+
# curl needed to download cifuzz and bazelisk
6+
# git needed by bazel to clone external repositories
7+
# python3 needed by rules_fuzzing to prepare the corpus direcotry
8+
# lcov needed by cifuzz to parse coverage reports
9+
RUN apt update && apt install -y curl git python3 lcov
10+
11+
# Install bazelisk
12+
RUN curl https://github.com/bazelbuild/bazelisk/releases/download/v1.21.0/bazelisk-linux-amd64 -L -o /usr/bin/bazel && chmod +x /usr/bin/bazel
13+
14+
# Install latest version of cifuzz
15+
ARG CIFUZZ_DOWNLOAD_TOKEN
16+
RUN sh -c "$(curl -fsSL https://downloads.code-intelligence.com/assets/install-cifuzz.sh)" $CIFUZZ_DOWNLOAD_TOKEN && rm cifuzz_installer
17+
18+
# Copy example project
19+
COPY . .
20+
21+
# Build the project to populate the bazel cache
22+
# Warning: This will take some time and produce a large docker image.
23+
RUN bazel build //...

MODULE.bazel

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
## Chromium sysroot
2+
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
3+
4+
# This sysroot is used by github.com/vsco/bazel-toolchains.
5+
http_archive(
6+
name = "org_chromium_sysroot_linux_x64",
7+
build_file_content = """
8+
filegroup(
9+
name = "sysroot",
10+
srcs = glob(["*/**"]),
11+
visibility = ["//visibility:public"],
12+
)
13+
""",
14+
sha256 = "84656a6df544ecef62169cfe3ab6e41bb4346a62d3ba2a045dc5a0a2ecea94a3",
15+
urls = ["https://commondatastorage.googleapis.com/chrome-linux-sysroot/toolchain/2202c161310ffde63729f29d27fe7bb24a0bc540/debian_stretch_amd64_sysroot.tar.xz"],
16+
)
17+
18+
## LLVM toolchain
19+
bazel_dep(name = "toolchains_llvm", version = "v1.1.2")
20+
git_override(
21+
module_name = "toolchains_llvm",
22+
commit = "1cd9e36e498983f061aa239e18043cfd26c7ac28",
23+
remote = "https://github.com/bazel-contrib/toolchains_llvm",
24+
)
25+
26+
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm")
27+
llvm.toolchain(
28+
name = "llvm_toolchain",
29+
llvm_version = "15.0.6",
30+
)
31+
32+
llvm.sysroot(
33+
name = "llvm_toolchain",
34+
label = "@org_chromium_sysroot_linux_x64//:sysroot",
35+
targets = ["linux-x86_64"],
36+
)
37+
38+
use_repo(llvm, "llvm_toolchain")
39+
40+
register_toolchains("@llvm_toolchain//:all")
41+
42+
## Fuzzing rules
43+
bazel_dep(name = "rules_fuzzing", version = "0.5.2")
44+
non_module_dependencies = use_extension("@rules_fuzzing//fuzzing/private:extensions.bzl", "non_module_dependencies")
45+
use_repo(non_module_dependencies, "rules_fuzzing_oss_fuzz")

MODULE.bazel.lock

Lines changed: 2767 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# cifuzz bazel example
2+
3+
This is a simple bazel based project, already configured with
4+
**cifuzz**. It should quickly produce a finding, but slow enough to
5+
see the progress of the fuzzer.
6+
7+
To start make sure you installed **cifuzz** according to the
8+
main [README](../../README.md).
9+
10+
You can start the fuzzing with
11+
12+
```bash
13+
cifuzz run //src:explore_me_fuzz_test
14+
```
15+
16+
## Create regression test
17+
18+
After you have discovered a finding, you may want to include this as
19+
part of a regression test. To replay findings from the
20+
`src/explore_me_fuzz_test_inputs` directory:
21+
22+
```bash
23+
bazel test --config=cifuzz-replay //src:explore_me_fuzz_test --test_output=streamed
24+
```
25+
26+
Note that this requires these lines in your `.bazelrc`:
27+
28+
```bash
29+
# Replay cifuzz findings (C/C++ only)
30+
build:cifuzz-replay --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan-ubsan
31+
build:cifuzz-replay --compilation_mode=opt
32+
build:cifuzz-replay --copt=-g
33+
build:cifuzz-replay --copt=-U_FORTIFY_SOURCE
34+
build:cifuzz-replay --test_env=UBSAN_OPTIONS=halt_on_error=1
35+
```
36+
37+
## C++ Toolchain
38+
39+
This project uses
40+
[toolchains_llvm](https://github.com/bazel-contrib/toolchains_llvm) to configure
41+
the cc toolchain used by bazel to compile fuzz tests. To ensure hermetic
42+
builds a [chromium sysroot](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/linux/sysroot.md)
43+
is used.
44+
45+
The toolchain can be tested using the provided `Dockerfile` which installs
46+
minimal dependencies to run this example project. Note, that no compiler and no
47+
C++ library headers are installed since they are provided with the cc toolchain.
48+
49+
Start by building the docker image
50+
51+
```
52+
export CIFUZZ_DOWNLOAD_TOKEN=<download token from https://downloads.code-intelligence.com>
53+
docker build --tag bazel-example --build-arg CIFUZZ_DOWNLOAD_TOKEN .
54+
```
55+
56+
Warning: Don't push this docker image to a public repository since it could leak
57+
your personal download token. This image is intended for local
58+
experimentation.
59+
Warning: This docker image can become quite large because it populates the bazel
60+
cache with all dependencies and the hermetic toolchain.
61+
62+
Run the docker image
63+
64+
```
65+
docker run --rm -it bazel-example
66+
```
67+
68+
Inside the docker image you need to set `CC` and `CXX` to the toolchain clang
69+
compiler. This can be done with the `set_env.sh` script:
70+
71+
```
72+
$ source set_env.sh
73+
$ $CC --version
74+
clang version 15.0.6
75+
Target: x86_64-unknown-linux-gnu
76+
Thread model: posix
77+
InstalledDir: /root/.cache/bazel/_bazel_root/1e0bb3bee2d09d2e4ad3523530d3b40c/execroot/_main/external/toolchains_llvm~~llvm~llvm_toolchain_llvm/bin
78+
```
79+
80+
Now you can run cifuzz commands on the example project. For `cifuzz run` and
81+
`cifuzz coverage` you should get output similar to this:
82+
83+
```
84+
$ cifuzz run
85+
🚀 Running //src:explore_me_fuzz_test_bin...
86+
✅ Building... Done.
87+
Log can be found here:
88+
/work/.cifuzz-build/logs/build-src_explore_me_fuzz_test.log
89+
✅ Initializing... Done.
90+
Fuzz testing will be performed for 10m. Use '--max-fuzzing-duration' to change the duration.
91+
✅ Testing code...
92+
34 Unique Test Cases and 2 Findings detected in 0s.
93+
94+
CRITICAL
95+
💥 NEW [quirky_okapi] heap_buffer_overflow in exploreMe (src/explore_me.cpp:18:11)
96+
LOW
97+
💥 NEW [stoic_jay] undefined behavior in exploreMe (src/explore_me.cpp:13:11)
98+
```
99+
100+
```
101+
$ cifuzz coverage --format lcov
102+
✅ Building //src:explore_me_fuzz_test_bin... Done.
103+
✅ Generating lcov report for //src:explore_me_fuzz_test_bin... Done.
104+
✅ Creating coverage report... Done.
105+
106+
File | Functions Hit/Found | Lines Hit/Found | Branches Hit/Found
107+
src/explore_me.cpp | 1 / 1 (100.0%) | 15 / 15 (100.0%) | 8 / 8 (100.0%)
108+
src/explore_me_fuzz_test.cpp | 2 / 2 (100.0%) | 8 / 8 (100.0%) | 0 / 0 (100.0%)
109+
| | |
110+
| Functions Hit/Found | Lines Hit/Found | Branches Hit/Found
111+
Total | 3 / 3 (100.0%) | 23 / 23 (100.0%) | 8 / 8 (100.0%)
112+
113+
LCOV report can be found here:
114+
--src:explore_me_fuzz_test_bin.lcov.info
115+
```

WORKSPACE

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2+
3+
http_archive(
4+
name = "cifuzz",
5+
sha256 = "1e01292189b0524d1f6114e0717d107474c289f78cbe7513e79fcaff8f0dee90",
6+
strip_prefix = "cifuzz-bazel-1.0.0",
7+
urls = ["https://github.com/CodeIntelligenceTesting/cifuzz-bazel/archive/refs/tags/v1.0.0.zip"],
8+
)
9+

0 commit comments

Comments
 (0)