Skip to content

Commit 29d0df1

Browse files
committed
feat: add cifuzz example projects
1 parent 6e34311 commit 29d0df1

File tree

161 files changed

+15611
-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.

161 files changed

+15611
-0
lines changed

Diff for: example-projects/advanced-setup/bazel/.bazelrc

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Force the use of Clang for all builds.
2+
build --repo_env=CC=clang
3+
build --repo_env=CXX=clang++
4+
5+
build --cxxopt=-std=c++14
6+
7+
# Replay cifuzz findings (C/C++ only)
8+
build:cifuzz-replay --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan-ubsan
9+
build:cifuzz-replay --compilation_mode=opt
10+
build:cifuzz-replay --copt=-g
11+
build:cifuzz-replay --copt=-U_FORTIFY_SOURCE
12+
build:cifuzz-replay --test_env=UBSAN_OPTIONS=halt_on_error=1
13+
14+
# Coverage with Replay (C/C++ only)
15+
coverage --@rules_fuzzing//fuzzing:cc_engine=@rules_fuzzing//fuzzing/engines:replay
16+
coverage --@rules_fuzzing//fuzzing:cc_engine_instrumentation=none
17+
coverage --@rules_fuzzing//fuzzing:cc_engine_sanitizer=none
18+
coverage --instrument_test_targets
19+
coverage --repo_env=BAZEL_USE_LLVM_NATIVE_COVERAGE=1
20+
coverage --repo_env=GCOV=llvm-profdata
21+
coverage --repo_env=BAZEL_LLVM_COV=llvm-cov
22+
coverage --combined_report=lcov
23+
coverage --experimental_use_llvm_covmap
24+
coverage --experimental_generate_llvm_lcov

Diff for: example-projects/advanced-setup/bazel/.gitignore

+6
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/

Diff for: example-projects/advanced-setup/bazel/README.md

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
## Project Description
2+
3+
This is an extended example Bazel project with multiple packages and
4+
two fuzztests `main/tests:explore_me_fuzz_test` and `fuzztests:test_me_fuzz_test`.
5+
6+
The `explore_me_fuzz_test` is defined in the same package as the source
7+
code and `test_me_fuzz_test` is located in a separated package.
8+
9+
## Run
10+
11+
### Heap Buffer Overflow and Undefined Behaviour
12+
13+
```
14+
cifuzz run main/tests:explore_me_fuzz_test
15+
```
16+
17+
### Heap Use After Free
18+
19+
```
20+
cifuzz run fuzztests:test_me_fuzz_test
21+
```
22+
23+
## Bundle
24+
25+
### explore_me_fuzz_test
26+
27+
```
28+
cifuzz bundle main/tests:explore_me_fuzz_test
29+
```
30+
31+
Should include one fuzz test with two targets to cover fuzzing and coverage builds.
32+
33+
```
34+
...
35+
target: main/tests/explore_me_fuzz_test
36+
path: libfuzzer/address+undefined/main/tests/explore_me_fuzz_test/bin/explore_me_fuzz_test
37+
...
38+
target: main/tests/explore_me_fuzz_test
39+
path: replayer/coverage/main/tests/explore_me_fuzz_test/bin/explore_me_fuzz_test
40+
```
41+
42+
### test_me_fuzz_test
43+
44+
```
45+
cifuzz bundle
46+
```
47+
48+
Should include one fuzz test with two targets to cover fuzzing and coverage builds.
49+
50+
```
51+
...
52+
target: fuzztests/test_me_fuzz_test
53+
path: libfuzzer/address+undefined/fuzztests/test_me_fuzz_test/bin/test_me_fuzz_test
54+
...
55+
target: fuzztests/test_me_fuzz_test
56+
path: replayer/coverage/fuzztests/test_me_fuzz_test/bin/test_me_fuzz_test
57+
...
58+
```
59+
60+
## Coverage
61+
62+
### explore_me_fuzz_test
63+
64+
```
65+
cifuzz coverage main/tests:explore_me_fuzz_test
66+
```
67+
68+
```
69+
File | Functions Hit/Found | Lines Hit/Found | Branches Hit/Found
70+
main/src/explore_me.cpp | 1 / 1 (100.0%) | 15 / 15 (100.0%) | 8 / 8 (100.0%)
71+
main/tests/explore_me_fuzz_test.cpp | 2 / 2 (100.0%) | 8 / 8 (100.0%) | 0 / 0 (100.0%)
72+
| | |
73+
| Functions Hit/Found | Lines Hit/Found | Branches Hit/Found
74+
Total | 3 / 3 | 23 / 23 | 8 / 8
75+
```
76+
77+
### test_me_fuzz_test
78+
79+
```
80+
cifuzz coverage fuzztests:test_me_fuzz_test
81+
```
82+
83+
```
84+
File | Functions Hit/Found | Lines Hit/Found | Branches Hit/Found
85+
fuzztests/test_me_fuzz_test.cpp | 2 / 2 (100.0%) | 6 / 6 (100.0%) | 0 / 0 (100.0%)
86+
| | |
87+
| Functions Hit/Found | Lines Hit/Found | Branches Hit/Found
88+
Total | 2 / 2 | 6 / 6 | 0 / 0
89+
```

Diff for: example-projects/advanced-setup/bazel/WORKSPACE

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
2+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
3+
4+
http_archive(
5+
name = "rules_fuzzing",
6+
sha256 = "ff52ef4845ab00e95d29c02a9e32e9eff4e0a4c9c8a6bcf8407a2f19eb3f9190",
7+
strip_prefix = "rules_fuzzing-0.4.1",
8+
urls = ["https://github.com/bazelbuild/rules_fuzzing/releases/download/v0.4.1/rules_fuzzing-0.4.1.zip"],
9+
)
10+
11+
load("@rules_fuzzing//fuzzing:repositories.bzl", "rules_fuzzing_dependencies")
12+
13+
rules_fuzzing_dependencies()
14+
15+
load("@rules_fuzzing//fuzzing:init.bzl", "rules_fuzzing_init")
16+
17+
rules_fuzzing_init()
18+
19+
load("@fuzzing_py_deps//:requirements.bzl", "install_deps")
20+
21+
install_deps()
22+
23+
git_repository(
24+
name = "cifuzz",
25+
commit = "b013aa0f90fe8ac60adfc6d9640a9cfa451dda9e",
26+
remote = "https://github.com/CodeIntelligenceTesting/cifuzz-bazel",
27+
)

Diff for: example-projects/advanced-setup/bazel/cifuzz.yaml

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
## Configuration for a CI Fuzz project
2+
## Generated on 2023-04-04
3+
4+
## The build system used to build this project. If not set, cifuzz tries
5+
## to detect the build system automatically.
6+
## Valid values: "bazel", "cmake", "maven", "gradle", "other".
7+
#build-system: cmake
8+
9+
## If the build system type is "other", this command is used by
10+
## `cifuzz run` to build the fuzz tests.
11+
#build-command: "make my_fuzz_test"
12+
13+
## Directories containing sample inputs for the code under tests.
14+
## See https://llvm.org/docs/LibFuzzer.html#corpus
15+
#seed-corpus-dirs:
16+
# - path/to/seed-corpus
17+
18+
## A file containing input language keywords or other interesting byte
19+
## sequences.
20+
## See https://llvm.org/docs/LibFuzzer.html#dictionaries
21+
#dict: path/to/dictionary.dct
22+
23+
## Command-line arguments to pass to libFuzzer.
24+
## See https://llvm.org/docs/LibFuzzer.html#options
25+
#engine-args:
26+
# - -rss_limit_mb=4096
27+
28+
## Maximum time to run fuzz tests. The default is to run indefinitely.
29+
#timeout: 30m
30+
31+
## Set to true to print output of the `cifuzz run` command as JSON.
32+
#print-json: true
33+
34+
## Set to true to disable desktop notifications
35+
#no-notifications: true
36+
37+
## Set URL of CI Sense
38+
#server: https://app.code-intelligence.com
39+
40+
## Set the project name on CI Sense
41+
#project: my-project-1a2b3c4d
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
2+
3+
cc_fuzz_test(
4+
name = "test_me_fuzz_test",
5+
srcs = [
6+
"test_me_fuzz_test.cpp",
7+
],
8+
corpus = glob(
9+
["test_me_fuzz_test_inputs/**"],
10+
allow_empty = True,
11+
) + select({
12+
"@cifuzz//:collect_coverage": glob([".test_me_fuzz_test_cifuzz_corpus/**"], allow_empty = True),
13+
"//conditions:default": [],
14+
}),
15+
deps = [
16+
"//lib/src:test_me",
17+
"@cifuzz",
18+
],
19+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "lib/src/test_me.h"
2+
#include <cifuzz/cifuzz.h>
3+
#include <fuzzer/FuzzedDataProvider.h>
4+
5+
FUZZ_TEST_SETUP() {}
6+
7+
FUZZ_TEST(const uint8_t *data, size_t size) {
8+
FuzzedDataProvider fuzzed_data(data, size);
9+
std::string c = fuzzed_data.ConsumeRandomLengthString();
10+
testMe(c);
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
cc_library(
2+
name = "test_me",
3+
srcs = ["test_me.cpp"],
4+
hdrs = ["test_me.h"],
5+
visibility = ["//visibility:public"],
6+
)
7+
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "lib/src/test_me.h"
2+
#include <string>
3+
4+
using namespace std;
5+
6+
void testMe(string s) {
7+
if (s == "FUZZING") {
8+
char *c = (char *) malloc(1);
9+
free(c);
10+
::printf("%s", c);
11+
} else {
12+
printf("%s", s.c_str());
13+
}
14+
}
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#include <string>
2+
using namespace std;
3+
4+
void testMe(string s);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
load("@rules_cc//cc:defs.bzl", "cc_binary")
2+
3+
cc_library(
4+
name = "explore_me",
5+
srcs = ["explore_me.cpp"],
6+
hdrs = ["explore_me.h"],
7+
visibility = ["//visibility:public"],
8+
)
9+
10+
cc_binary(
11+
name = "main",
12+
srcs = ["main.cpp"],
13+
deps = [
14+
"explore_me",
15+
"//lib/src:test_me",
16+
],
17+
)
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "explore_me.h"
2+
#include <cstdio>
3+
#include <cstring>
4+
using namespace std;
5+
6+
// just a function with multiple paths that can be discoverd by a fuzzer
7+
void exploreMe(int a, int b, string c) {
8+
if (a >= 20000) {
9+
if (b >= 2000000) {
10+
if (b - a < 100000) {
11+
// Trigger the undefined behavior sanitizer
12+
int n = 23;
13+
n <<= 32;
14+
15+
if (c == "FUZZING") {
16+
// Trigger a heap buffer overflow
17+
char *s = (char *)malloc(1);
18+
strcpy(s, "too long");
19+
printf("%s\n", s);
20+
}
21+
}
22+
}
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#include <string>
2+
using namespace std;
3+
4+
void exploreMe(int a, int b, string c);
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include "explore_me.h"
2+
#include "lib/src/test_me.h"
3+
4+
int main() {
5+
exploreMe(1, 1, "A");
6+
testMe("hello");
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
2+
3+
cc_fuzz_test(
4+
name = "explore_me_fuzz_test",
5+
srcs = [
6+
"explore_me_fuzz_test.cpp",
7+
],
8+
corpus = glob(
9+
["explore_me_fuzz_test_inputs/**"],
10+
allow_empty = True,
11+
) + select({
12+
"@cifuzz//:collect_coverage": glob([".explore_me_fuzz_test_cifuzz_corpus/**"], allow_empty = True),
13+
"//conditions:default": [],
14+
}),
15+
deps = [
16+
"//main/src:explore_me",
17+
"@cifuzz",
18+
],
19+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "../src/explore_me.h"
2+
#include <cifuzz/cifuzz.h>
3+
#include <fuzzer/FuzzedDataProvider.h>
4+
5+
FUZZ_TEST_SETUP() {}
6+
7+
FUZZ_TEST(const uint8_t *data, size_t size) {
8+
FuzzedDataProvider fuzzed_data(data, size);
9+
int a = fuzzed_data.ConsumeIntegral<int>();
10+
int b = fuzzed_data.ConsumeIntegral<int>();
11+
std::string c = fuzzed_data.ConsumeRandomLengthString();
12+
13+
exploreMe(a, b, c);
14+
}

Diff for: example-projects/advanced-setup/cmake/.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
build/
2+
.cifuzz-*/
3+
*_inputs
4+
crash-*
5+
gotest.log

Diff for: example-projects/advanced-setup/cmake/CMakeLists.txt

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
project(cmake_example)
3+
4+
set(CMAKE_CXX_STANDARD 11)
5+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
6+
7+
enable_testing()
8+
9+
find_package(cifuzz NO_SYSTEM_ENVIRONMENT_PATH)
10+
enable_fuzz_testing()
11+
12+
add_subdirectory(main)
13+
add_subdirectory(lib)
14+
15+
add_fuzz_test(test_me_fuzztest fuzztests/test_me_fuzztest.cpp)
16+
target_link_libraries(test_me_fuzztest PRIVATE testMe)
17+
18+
19+

0 commit comments

Comments
 (0)