Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fuzzing: Add fuzzing support and build script #1291

Merged
merged 5 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions auto/fuzzing
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright (C) NGINX, Inc.


if [ -n "$NXT_FUZZ" ]; then

# Fuzz-Test object files list.

$echo "NXT_FUZZ_OBJS = \\" >> $NXT_MAKEFILE

for nxt_src in $NXT_FUZZ_SRCS
do
nxt_obj=${nxt_src%.c}.o
$echo " $NXT_BUILD_DIR/$nxt_obj \\" >> $NXT_MAKEFILE
done


# Fuzz-Test executables.

cat << END >> $NXT_MAKEFILE

.PHONY: fuzz
fuzz: $NXT_BUILD_DIR/fuzz_basic \\
$NXT_BUILD_DIR/fuzz_http_controller \\
$NXT_BUILD_DIR/fuzz_http_h1p \\
$NXT_BUILD_DIR/fuzz_http_h1p_peer \\
$NXT_BUILD_DIR/fuzz_json

$NXT_BUILD_DIR/fuzz_basic: \$(NXT_FUZZ_OBJS) \\
$NXT_BUILD_DIR/lib/$NXT_LIB_STATIC
\$(PP_LD) \$@
\$(v)\$(NXT_EXEC_LINK) -o $NXT_BUILD_DIR/fuzz_basic \\
\$(CFLAGS) $NXT_BUILD_DIR/fuzzing/nxt_basic_fuzz.o \\
$NXT_BUILD_DIR/lib/$NXT_LIB_STATIC \\
$NXT_LD_OPT $NXT_LIBM $NXT_LIBS $NXT_LIB_AUX_LIBS \\
$NXT_FUZZ

$NXT_BUILD_DIR/fuzz_http_controller: \$(NXT_FUZZ_OBJS) \\
$NXT_BUILD_DIR/lib/$NXT_LIB_STATIC
\$(PP_LD) \$@
\$(v)\$(NXT_EXEC_LINK) -o $NXT_BUILD_DIR/fuzz_http_controller \\
\$(CFLAGS) $NXT_BUILD_DIR/fuzzing/nxt_http_controller_fuzz.o \\
$NXT_BUILD_DIR/lib/$NXT_LIB_STATIC \\
$NXT_LD_OPT $NXT_LIBM $NXT_LIBS $NXT_LIB_AUX_LIBS \\
$NXT_FUZZ

$NXT_BUILD_DIR/fuzz_http_h1p: \$(NXT_FUZZ_OBJS) \\
$NXT_BUILD_DIR/lib/$NXT_LIB_STATIC
\$(PP_LD) \$@
\$(v)\$(NXT_EXEC_LINK) -o $NXT_BUILD_DIR/fuzz_http_h1p \\
\$(CFLAGS) $NXT_BUILD_DIR/fuzzing/nxt_http_h1p_fuzz.o \\
$NXT_BUILD_DIR/lib/$NXT_LIB_STATIC \\
$NXT_LD_OPT $NXT_LIBM $NXT_LIBS $NXT_LIB_AUX_LIBS \\
$NXT_FUZZ

$NXT_BUILD_DIR/fuzz_http_h1p_peer: \$(NXT_FUZZ_OBJS) \\
$NXT_BUILD_DIR/lib/$NXT_LIB_STATIC
\$(PP_LD) \$@
\$(v)\$(NXT_EXEC_LINK) -o $NXT_BUILD_DIR/fuzz_http_h1p_peer \\
\$(CFLAGS) $NXT_BUILD_DIR/fuzzing/nxt_http_h1p_peer_fuzz.o \\
$NXT_BUILD_DIR/lib/$NXT_LIB_STATIC \\
$NXT_LD_OPT $NXT_LIBM $NXT_LIBS $NXT_LIB_AUX_LIBS \\
$NXT_FUZZ

$NXT_BUILD_DIR/fuzz_json: \$(NXT_FUZZ_OBJS) \\
$NXT_BUILD_DIR/lib/$NXT_LIB_STATIC
\$(PP_LD) \$@
\$(v)\$(NXT_EXEC_LINK) -o $NXT_BUILD_DIR/fuzz_json \\
\$(CFLAGS) $NXT_BUILD_DIR/fuzzing/nxt_json_fuzz.o \\
$NXT_BUILD_DIR/lib/$NXT_LIB_STATIC \\
$NXT_LD_OPT $NXT_LIBM $NXT_LIBS $NXT_LIB_AUX_LIBS \\
$NXT_FUZZ

END

fi
2 changes: 2 additions & 0 deletions auto/help
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ cat << END

--debug enable debug logging

--fuzz=ENGINE enable fuzz testing


python OPTIONS configure Python module
run "./configure python --help" to see available options
Expand Down
2 changes: 1 addition & 1 deletion auto/make
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ END

# Object files.

for nxt_src in $NXT_LIB_SRCS $NXT_TEST_SRCS $NXT_LIB_UNIT_SRCS \
for nxt_src in $NXT_LIB_SRCS $NXT_TEST_SRCS $NXT_FUZZ_SRCS $NXT_LIB_UNIT_SRCS \
src/test/nxt_unit_app_test.c \
src/test/nxt_unit_websocket_chat.c \
src/test/nxt_unit_websocket_echo.c
Expand Down
4 changes: 4 additions & 0 deletions auto/options
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ NXT_TEST_BUILD_HPUX_SENDFILE=NO

NXT_TESTS=NO

NXT_FUZZ=

NXT_HELP=NO

for nxt_option
Expand Down Expand Up @@ -125,6 +127,8 @@ do

--tests) NXT_TESTS=YES ;;

--fuzz=*) NXT_FUZZ="$value" ;;

--help)
. auto/help
exit 0
Expand Down
9 changes: 9 additions & 0 deletions auto/sources
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,15 @@ if [ $NXT_TESTS = YES ]; then
fi


NXT_FUZZ_SRCS=" \
fuzzing/nxt_basic_fuzz.c \
fuzzing/nxt_http_controller_fuzz.c \
fuzzing/nxt_http_h1p_fuzz.c \
fuzzing/nxt_http_h1p_peer_fuzz.c \
fuzzing/nxt_json_fuzz.c \
"


NXT_SRCS=" \
src/nxt_main.c \
"
2 changes: 2 additions & 0 deletions auto/summary
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ Unit configuration summary:

debug logging: ............. $NXT_DEBUG

fuzz engine: ............... "$NXT_FUZZ"

END
2 changes: 2 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ esac

mkdir -p $NXT_BUILD_DIR
mkdir -p $NXT_BUILD_DIR/bin
mkdir -p $NXT_BUILD_DIR/fuzzing
mkdir -p $NXT_BUILD_DIR/include
mkdir -p $NXT_BUILD_DIR/lib
mkdir -p $NXT_BUILD_DIR/lib/unit/modules
Expand Down Expand Up @@ -179,4 +180,5 @@ if [ $NXT_NJS != NO ]; then
fi

. auto/make
. auto/fuzzing
pkillarjun marked this conversation as resolved.
Show resolved Hide resolved
. auto/summary
1 change: 1 addition & 0 deletions fuzzing/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.bin whitespace=-blank-at-eol,-blank-at-eof
68 changes: 68 additions & 0 deletions fuzzing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Fuzzing unit

These tests are generally advised to run only on GNU/Linux.

## Build fuzzers using libFuzzer.

Running `sh fuzzing/build-fuzz.sh` can build all the fuzzers with standard
`ASan` and `UBSan`.

### More comprehensive How-to Guide.

#### Export flags that are to be used by Unit for fuzzing.

Note that in `CFLAGS` and `CXXFLAGS`, any type of sanitizers can be added.

- [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html),
[ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html),
[MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html),
[UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html),
[LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html).

```shell
$ export CC=clang
$ export CXX=clang++
$ export CFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=fuzzer-no-link"
$ export CXXFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=fuzzer-no-link"
$ export LIB_FUZZING_ENGINE="-fsanitize=fuzzer"
```

#### Build Unit for Fuzzing.

```shell
$ ./configure --no-regex --no-pcre2 --fuzz=$LIB_FUZZING_ENGINE
$ make fuzz -j$(nproc)
```

#### Running fuzzers.

```shell
$ mkdir -p build/fuzz_basic_seed
$ mkdir -p build/fuzz_http_controller_seed
$ mkdir -p build/fuzz_http_h1p_seed
$ mkdir -p build/fuzz_http_h1p_peer_seed
$ mkdir -p build/fuzz_json_seed

$ ./build/fuzz_basic build/fuzz_basic_seed src/fuzz/fuzz_basic_seed_corpus
$ ./build/fuzz_http_controller build/fuzz_http_controller_seed src/fuzz/fuzz_http_controller_seed_corpus
$ ./build/fuzz_http_h1p build/fuzz_http_h1p_seed src/fuzz/fuzz_http_h1p_seed_corpus
$ ./build/fuzz_http_h1p_peer build/fuzz_http_h1p_peer_seed src/fuzz/fuzz_http_h1p_peer_seed_corpus
$ ./build/fuzz_json build/fuzz_json_seed src/fuzz/fuzz_json_seed_corpus
```

Here is more information about [LibFuzzer](https://llvm.org/docs/LibFuzzer.html).

## Build fuzzers using other fuzzing engines.

- [Honggfuzz](https://github.com/google/honggfuzz/blob/master/docs/PersistentFuzzing.md).
- [AFLplusplus](https://github.com/AFLplusplus/AFLplusplus/blob/stable/utils/aflpp_driver/README.md).


## Requirements.

You will likely need at least the following packages installed (package names
may vary).

```
clang, llvm & compiler-rt
```
20 changes: 20 additions & 0 deletions fuzzing/build-fuzz.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash

export CC=clang
export CXX=clang++
export CFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address,undefined -fsanitize=fuzzer-no-link"
export CXXFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address,undefined -fsanitize=fuzzer-no-link"
export LIB_FUZZING_ENGINE="-fsanitize=fuzzer"

./configure --no-regex --no-pcre2 --fuzz=$LIB_FUZZING_ENGINE
make fuzz -j$(nproc)

mkdir -p build/fuzz_basic_seed
mkdir -p build/fuzz_http_controller_seed
mkdir -p build/fuzz_http_h1p_seed
mkdir -p build/fuzz_http_h1p_peer_seed
pkillarjun marked this conversation as resolved.
Show resolved Hide resolved
mkdir -p build/fuzz_json_seed

echo ""
echo "Run: ./build/\${fuzzer} build/\${fuzzer}_seed src/fuzz/\${fuzzer}_seed_corpus"
echo ""
Binary file added fuzzing/fuzz_basic_seed_corpus/base64_0.bin
Binary file not shown.
Binary file added fuzzing/fuzz_basic_seed_corpus/term_0.bin
Binary file not shown.
Binary file added fuzzing/fuzz_basic_seed_corpus/term_1.bin
Binary file not shown.
Binary file added fuzzing/fuzz_basic_seed_corpus/utf8_0.bin
Binary file not shown.
38 changes: 38 additions & 0 deletions fuzzing/fuzz_http.dict
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"Accept-Encoding"
"Accept-Language"
"Accept"
"Authorization"
"Cache-Control"
"Connection"
"Content-Length"
"Content-Range"
"Content-Type"
"Cookie"
"Date"
"Expect"
"Host"
"If-Match"
"If-Modified-Since"
"If-None-Match"
"If-Range"
"If-Unmodified-Since"
"Keep-Alive"
"Origin"
"Pragma"
"Range"
"Referer"
"Sec-WebSocket-Key"
"Sec-WebSocket-Version"
"Server"
"TE"
"Transfer-Encoding"
"Upgrade-Insecure-Requests"
"Upgrade"
"User-Agent"
"Via"
"X-Forwarded-For"
"X-Forwarded-Host"
"X-Forwarded-Proto"
"X-Http-Method-Override"
"X-Real-IP"
"X-Request-ID"
16 changes: 16 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_bench.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
POST /path/to/very/interesting/article/on.this.site?arg1=value&arg2=value2&very_big_arg=even_bigger_value HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (X11; Gentoo Linux x86_64; rv:42.0) Firefox/42.0
Accept: text/html,application/json,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Encoding: gzip, deflate, br
If-Modified-Since: Wed, 31 Dec 1986 16:00:00 GMT
Referer: https://example.org/path/to/not-interesting/article.html
Cookie: name=value; name2=value2; some_big_cookie=Olr+/9hoA0og/dAcHH1p8sEFAHAAAAAElFTkSuQmCC
Connection: keep-alive
Content-Length: 0
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
X-Forwarded-For: 192.0.2.0, 198.51.100.0, 203.0.113.0

2 changes: 2 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_0.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
XXX-METHOD /d.ir/fi+le.ext?key=val HTTP/1.2

2 changes: 2 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_1.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GEt / HTTP/1.0

2 changes: 2 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_10.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET /na %20me.ext?args HTTP/1.0

2 changes: 2 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_11.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET / HTTP/1.0 HTTP/1.1

3 changes: 3 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_12.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GET / HTTP/1.1
Host:example.com

3 changes: 3 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_13.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GET / HTTP/1.1
Host:

3 changes: 3 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_14.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GET / HTTP/1.1
:Host: example.com

3 changes: 3 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_15.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GET / HTTP/1.1
Ho_st: example.com

4 changes: 4 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_16.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
GET / HTTP/1.1
Ho
st: example.com

3 changes: 3 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_17.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GET / HTTP/1.1
Host: example.com

Expand Down
3 changes: 3 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_18.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GET / HTTP/1.1
Host: example.com

3 changes: 3 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_19.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GET / HTTP/1.1
!#$%&'*+.^_`|~: allowed

3 changes: 3 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_2.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GET /
HTTP/1.0

3 changes: 3 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_20.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GET / HTTP/1.1
Host: xn--e1afmkfd.xn--80akhbyknj4f

4 changes: 4 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_21.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
GET / HTTP/1.1
Host: exa
mple.com

3 changes: 3 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_22.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GET / HTTP/1.1
Host: exa mple.com

5 changes: 5 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_23.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
GET / HTTP/1.1
X-Unknown-Header: value
X-Good-Header: value
!#$%&'*+.^_`|~: skipped

5 changes: 5 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_24.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
GET / HTTP/1.1
X-Good-Header: value
X-Unknown-Header: value
X-Bad-Header: value

1 change: 1 addition & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_3.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GET / HTTP/1.0
Expand Down
1 change: 1 addition & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_4.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GET / HTTP/2.0
2 changes: 2 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_5.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET /. HTTP/1.0

2 changes: 2 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_6.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET /# HTTP/1.0

2 changes: 2 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_7.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET /?# HTTP/1.0

2 changes: 2 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_8.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET // HTTP/1.0

2 changes: 2 additions & 0 deletions fuzzing/fuzz_http_seed_corpus/nxt_http_test_run_9.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET /%20 HTTP/1.0

1 change: 1 addition & 0 deletions fuzzing/fuzz_json_seed_corpus/json_0.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"container": 1000, "host": 0, "size": 1},{"container": 10000, "host": 10000, "size": 1}, {"container": 60000, "host": 60000, "size": 1}]
1 change: 1 addition & 0 deletions fuzzing/fuzz_json_seed_corpus/json_1.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
1 change: 1 addition & 0 deletions fuzzing/fuzz_json_seed_corpus/json_2.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"container": 0, "host": 0, "size": 1}]
Loading
Loading