From 5c7a320dcc7d3c7c94eed627deccb7c87ea1f87b Mon Sep 17 00:00:00 2001 From: Arjun <36335769+0x34d@users.noreply.github.com> Date: Mon, 10 Oct 2022 01:52:11 +0530 Subject: [PATCH] [nginx unit] initial integration (#8511) hello @thresheek @andrey-zelenkov Any thoughts on integration for fuzzing? can you take a look at the harness for both HTTP & JSON parser? Signed-off-by: 0x34d Signed-off-by: 0x34d --- projects/unit/Dockerfile | 22 +++++++++ projects/unit/build.sh | 29 +++++++++++ projects/unit/fuzzer/Fuzz_http.c | 84 ++++++++++++++++++++++++++++++++ projects/unit/fuzzer/Fuzz_http.h | 21 ++++++++ projects/unit/fuzzer/Fuzz_json.c | 57 ++++++++++++++++++++++ projects/unit/fuzzer/Makefile | 26 ++++++++++ projects/unit/project.yaml | 16 ++++++ 7 files changed, 255 insertions(+) create mode 100644 projects/unit/Dockerfile create mode 100644 projects/unit/build.sh create mode 100644 projects/unit/fuzzer/Fuzz_http.c create mode 100644 projects/unit/fuzzer/Fuzz_http.h create mode 100644 projects/unit/fuzzer/Fuzz_json.c create mode 100644 projects/unit/fuzzer/Makefile create mode 100644 projects/unit/project.yaml diff --git a/projects/unit/Dockerfile b/projects/unit/Dockerfile new file mode 100644 index 000000000..9e9129764 --- /dev/null +++ b/projects/unit/Dockerfile @@ -0,0 +1,22 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ +FROM gcr.io/oss-fuzz-base/base-builder +RUN apt-get update && apt-get install -y autoconf +RUN git clone --depth 1 https://github.com/nginx/unit +RUN git clone https://github.com/0x34d/oss-fuzz-bloat +COPY build.sh $SRC/ +COPY fuzzer/ $SRC/unit/fuzzer/ +WORKDIR $SRC/unit/ diff --git a/projects/unit/build.sh b/projects/unit/build.sh new file mode 100644 index 000000000..408bca4a2 --- /dev/null +++ b/projects/unit/build.sh @@ -0,0 +1,29 @@ +#!/bin/bash -eu +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ +./configure --debug --no-regex --no-pcre2 +make all + +pushd fuzzer/ +make +cp Fuzz_http $OUT/Fuzz_http +cp Fuzz_json $OUT/Fuzz_json +popd + +pushd $SRC/oss-fuzz-bloat/nginx-unit/ +cp Fuzz_http_seed_corpus.zip $OUT/Fuzz_http_seed_corpus.zip +cp Fuzz_json_seed_corpus.zip $OUT/Fuzz_json_seed_corpus.zip +popd diff --git a/projects/unit/fuzzer/Fuzz_http.c b/projects/unit/fuzzer/Fuzz_http.c new file mode 100644 index 000000000..dab2838ce --- /dev/null +++ b/projects/unit/fuzzer/Fuzz_http.c @@ -0,0 +1,84 @@ +/* Copyright 2022 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include +#include +#include + +#include "Fuzz_http.h" + +#define kMinInputLength 10 +#define kMaxInputLength 5120 + +static int DoInit = 0; + +extern char **environ; + +nxt_module_init_t nxt_init_modules[1]; +nxt_uint_t nxt_init_modules_n; + +extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{//src/test/nxt_http_parse_test.c + + if (Size < kMinInputLength || Size > kMaxInputLength){ + return 0; + } + + if(!DoInit){ + nxt_lib_start("tests", NULL, &environ); + DoInit = 1; + } + + nxt_int_t rc; + nxt_lvlhsh_t hash; + + nxt_memzero(&hash, sizeof(nxt_lvlhsh_t)); + + rc = nxt_http_fields_hash(&hash, nxt_h1p_fields, + nxt_nitems(nxt_h1p_fields)); + + nxt_str_t nxt_http_request; + + nxt_http_request.length = Size; + nxt_http_request.start = (uint8_t *) Data; + + rc = nxt_http_parse_fuzz(&nxt_http_request, + &hash); + + return rc; +} + +nxt_int_t nxt_http_parse_fuzz(nxt_str_t *request, nxt_lvlhsh_t *hash){ + + nxt_mp_t *mp; + nxt_buf_mem_t buf; + nxt_http_request_parse_t rp; + + buf.start = request->start; + buf.end = request->start + request->length; + + nxt_memzero(&rp, sizeof(nxt_http_request_parse_t)); + + mp = nxt_mp_create(1024, 128, 256, 32); + + nxt_http_parse_request_init(&rp, mp); + + buf.pos = buf.start; + buf.free = buf.end; + + if (nxt_slow_path(nxt_http_parse_request(&rp, &buf) == NXT_DONE)) { + nxt_http_fields_process(rp.fields, hash, NULL); + } + + nxt_mp_destroy(mp); + + return NXT_OK; +} diff --git a/projects/unit/fuzzer/Fuzz_http.h b/projects/unit/fuzzer/Fuzz_http.h new file mode 100644 index 000000000..c2461fa9b --- /dev/null +++ b/projects/unit/fuzzer/Fuzz_http.h @@ -0,0 +1,21 @@ +/* Copyright 2022 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include +#include "nxt_h1proto.c" + +nxt_int_t nxt_http_parse_fuzz(nxt_str_t *request, nxt_lvlhsh_t *hash); + +nxt_int_t +nxt_http_test_header_return(void *ctx, nxt_http_field_t *field, uintptr_t data) +{ + return data; +} diff --git a/projects/unit/fuzzer/Fuzz_json.c b/projects/unit/fuzzer/Fuzz_json.c new file mode 100644 index 000000000..f0af45d85 --- /dev/null +++ b/projects/unit/fuzzer/Fuzz_json.c @@ -0,0 +1,57 @@ +/* Copyright 2022 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include +#include +#include + +#include +#include + +#define kMinInputLength 2 +#define kMaxInputLength 5120 + +static int DoInit = 0; + +extern char **environ; + +nxt_module_init_t nxt_init_modules[1]; +nxt_uint_t nxt_init_modules_n; + +extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{//src/test/nxt_clone_test.c + + if (Size < kMinInputLength || Size > kMaxInputLength){ + return 0; + } + + if(!DoInit){ + nxt_lib_start("tests", NULL, &environ); + DoInit = 1; + } + + nxt_mp_t *mp; + nxt_str_t map_str; + + mp = nxt_mp_create(1024, 128, 256, 32); + if (mp == NULL) { + return NXT_ERROR; + } + + map_str.length = Size; + map_str.start = (uint8_t *) Data; + + nxt_conf_json_parse_str(mp,&map_str); + + nxt_mp_destroy(mp); + + return 0; +} diff --git a/projects/unit/fuzzer/Makefile b/projects/unit/fuzzer/Makefile new file mode 100644 index 000000000..073e89def --- /dev/null +++ b/projects/unit/fuzzer/Makefile @@ -0,0 +1,26 @@ +TARGET=Fuzzer + +#FileEXE +httpEXE=Fuzz_http +jsonEXE=Fuzz_json + +#Flags +INC=-I ../src -I ../build -I../src/test/ +EXTCFLAGS=-Wall -Werror -g +LibINC=-L../build/ +LibFLAGS=$(LIB_FUZZING_ENGINE) -lnxt + +all: $(TARGET) + +#SETUP +$(TARGET): + $(CC) $(CFLAGS) $(INC) $(EXTCFLAGS) -c $(httpEXE).c + $(CXX) $(CFLAGS) $(LibINC) -o $(httpEXE) $(httpEXE).o $(LibFLAGS) + + $(CC) $(CFLAGS) $(INC) $(EXTCFLAGS) -c $(jsonEXE).c + $(CXX) $(CFLAGS) $(LibINC) -o $(jsonEXE) $(jsonEXE).o $(LibFLAGS) + +clean: + rm $(jsonEXE) $(httpEXE) *.o + +.PHONY: all clean diff --git a/projects/unit/project.yaml b/projects/unit/project.yaml new file mode 100644 index 000000000..0ba65a6cf --- /dev/null +++ b/projects/unit/project.yaml @@ -0,0 +1,16 @@ +homepage: "https://unit.nginx.org" +language: c +primary_contact: "xim.andrew@gmail.com" +vendor_ccs: + - "devrep@nginx.com" +auto_ccs: + - "ajsinghyadav00@gmail.com" +fuzzing_engines: + - libfuzzer + - afl + - honggfuzz +sanitizers: + - address + - memory + - undefined +main_repo: 'https://github.com/nginx/unit'