Skip to content

Commit 563201a

Browse files
committed
Add scenarios/ files that compile to valid structured fuzzing corpora.
1 parent eba07ea commit 563201a

File tree

153 files changed

+4222
-184
lines changed

Some content is hidden

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

153 files changed

+4222
-184
lines changed

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@ temporary directory instead.
1616

1717
`./mainline.sh` is run regressibly by Github Actions.
1818

19+
## Structure-aware fuzzing with libprotobuf-mutator
20+
21+
Every `curl_fuzzer*` binary now links
22+
[libprotobuf-mutator](https://github.com/google/libprotobuf-mutator) directly.
23+
Build the usual targets and you automatically get structured `Scenario`
24+
generation:
25+
26+
```shell
27+
cmake -S . -B build
28+
cmake --build build --target curl_fuzzer
29+
```
30+
31+
The shared engine still understands legacy TLV corpora, but the libFuzzer
32+
entry-point feeds decoded `Scenario` protos into the same execution path, so
33+
crash reports remain comparable to the classic workflow.
34+
1935
## I want more information when running a testcase or multiple testcases
2036

2137
Setting the `FUZZ_VERBOSE` environment variable turns on curl verbose logging.
@@ -80,6 +96,22 @@ read_corpus <path/to/file>
8096
```
8197
This will print out a list of contents inside the file.
8298

99+
## I want to convert TLV corpora into structured scenarios
100+
101+
Install the tooling (see above), then run the converter to mirror TLV corpus
102+
entries into Scenario `.textproto` files:
103+
104+
```shell
105+
corpora_to_textproto --output scenarios/
106+
```
107+
108+
By default the tool walks the `corpora/` tree and writes `*.textproto` files to
109+
`scenarios/`, preserving the directory structure. You can point `--output` to a
110+
different directory or pass one or more explicit corpus paths when you only
111+
want to convert selected inputs. The converter automatically skips corpora for
112+
the `curl_fuzzer_fnmatch`, `curl_fuzzer_bufq`, and `fuzz_url` harnesses because
113+
they do not use the structured Scenario pipeline.
114+
83115
## I want an HTML decoder for corpus files
84116

85117
Generate a standalone HTML page that can inspect TLV corpora directly in your browser:

corpora/.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,20 @@
11
# Ignore all the scenario corpora
2+
curl_fuzzer/
3+
curl_fuzzer_dict/
4+
curl_fuzzer_file/
5+
curl_fuzzer_ftp/
6+
curl_fuzzer_gopher/
7+
curl_fuzzer_http/
8+
curl_fuzzer_https/
9+
curl_fuzzer_imap/
10+
curl_fuzzer_ldap/
11+
curl_fuzzer_mqtt/
12+
curl_fuzzer_pop3/
13+
curl_fuzzer_rtmp/
14+
curl_fuzzer_rtsp/
15+
curl_fuzzer_scp/
16+
curl_fuzzer_sftp/
17+
curl_fuzzer_smb/
18+
curl_fuzzer_smtp/
19+
curl_fuzzer_tftp/
20+
curl_fuzzer_ws/

curl_fuzzer.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
#include <libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h>
3232

33-
DEFINE_PROTO_FUZZER(const curl::fuzzer::proto::Scenario &scenario)
33+
DEFINE_BINARY_PROTO_FUZZER(const curl::fuzzer::proto::Scenario &scenario)
3434
{
3535
CurlFuzzerRunScenario(scenario);
3636
}
@@ -51,11 +51,18 @@ int CurlFuzzerRunScenario(const curl::fuzzer::proto::Scenario &scenario)
5151

5252
rc = curl_fuzzer::ApplyScenario(scenario, &fuzz);
5353
if(rc != 0) {
54+
FV_PRINTF(&fuzz, "SCENARIO: ApplyScenario failed with rc=%d\n", rc);
5455
goto EXIT_LABEL;
5556
}
57+
FV_PRINTF(&fuzz,
58+
"SCENARIO: successfully applied scenario, starting transfer\n");
5659

5760
/* Set up the standard easy options. */
58-
FTRY(fuzz_set_easy_options(&fuzz));
61+
rc = fuzz_set_easy_options(&fuzz);
62+
if(rc != 0) {
63+
FV_PRINTF(&fuzz, "SCENARIO: fuzz_set_easy_options failed with rc=%d\n", rc);
64+
goto EXIT_LABEL;
65+
}
5966

6067
/**
6168
* Add in more curl options that have been accumulated over the scenario
@@ -567,7 +574,7 @@ int fuzz_set_allowed_protocols(FUZZ_DATA *fuzz)
567574
allowed_protocols = "http,ws,wss";
568575
FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_CONNECT_ONLY, 2L));
569576
#endif
570-
577+
FV_PRINTF(fuzz, "allowed_protocols=%s\n", allowed_protocols);
571578
FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_PROTOCOLS_STR, allowed_protocols));
572579

573580
EXIT_LABEL:

curl_fuzzer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ int CurlFuzzerRunScenario(const curl::fuzzer::proto::Scenario &scenario);
495495
int _func_rc = (FUNC); \
496496
if (_func_rc) \
497497
{ \
498+
fprintf(stderr, "FTRY failed: %s returned %d\n", #FUNC, _func_rc); \
498499
rc = _func_rc; \
499500
goto EXIT_LABEL; \
500501
} \

0 commit comments

Comments
 (0)