From 76eb154ab7f896ff502dbe92a5f31159956c7afd Mon Sep 17 00:00:00 2001 From: Arthur Chan Date: Tue, 2 Aug 2022 10:01:50 +0100 Subject: [PATCH] gunicorn: intial integration (#7921) Create util fuzzer --- projects/gunicorn/Dockerfile | 22 ++++++++++ projects/gunicorn/build.sh | 24 ++++++++++ projects/gunicorn/fuzz_util.py | 80 ++++++++++++++++++++++++++++++++++ projects/gunicorn/project.yaml | 12 +++++ 4 files changed, 138 insertions(+) create mode 100644 projects/gunicorn/Dockerfile create mode 100644 projects/gunicorn/build.sh create mode 100644 projects/gunicorn/fuzz_util.py create mode 100644 projects/gunicorn/project.yaml diff --git a/projects/gunicorn/Dockerfile b/projects/gunicorn/Dockerfile new file mode 100644 index 000000000..516d5a1da --- /dev/null +++ b/projects/gunicorn/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-python + +RUN git clone https://github.com/benoitc/gunicorn +WORKDIR gunicorn + +COPY build.sh fuzz_*.py $SRC/ diff --git a/projects/gunicorn/build.sh b/projects/gunicorn/build.sh new file mode 100644 index 000000000..6da18d63c --- /dev/null +++ b/projects/gunicorn/build.sh @@ -0,0 +1,24 @@ +#!/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. +# +################################################################################ + +# Build and install project (using current CFLAGS, CXXFLAGS). +pip3 install --upgrade pip +pip3 install . + +for fuzzer in $(find $SRC -name 'fuzz_*.py'); do + compile_python_fuzzer $fuzzer +done diff --git a/projects/gunicorn/fuzz_util.py b/projects/gunicorn/fuzz_util.py new file mode 100644 index 000000000..0d3e00b06 --- /dev/null +++ b/projects/gunicorn/fuzz_util.py @@ -0,0 +1,80 @@ +#!/usr/bin/python3 +# 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. + +import atheris +import sys +with atheris.instrument_imports(): + from gunicorn import util + from gunicorn.errors import AppImportError + +def TestInput(data): + + fdp = atheris.FuzzedDataProvider(data) + + util.is_ipv6(fdp.ConsumeString(100)) + util.warn(fdp.ConsumeString(100)) + util.split_request_uri(fdp.ConsumeString(100)) + + try: + util.parse_address(fdp.ConsumeString(100)) + except RuntimeError as e: + if "is not a valid port number." not in str(e): + raise e + + try: + util.http_date(fdp.ConsumeInt(50)) + except OSError as e: + if "Value too large for defined data type" not in str(e): + raise e + except (OverflowError,ValueError) as e: + if "out of range" not in str(e): + raise e + + try: + util.to_bytestring(fdp.ConsumeString(100)) + util.to_bytestring(fdp.ConsumeString(100),'ascii') + except UnicodeEncodeError as e: + if "codec can't encode character" not in str(e): + raise e + + try: + util.import_app(fdp.ConsumeString(100)) + except (ValueError,ImportError,AppImportError) as e: + error_list = [ + "Empty module name", + "No module", + "Failed to parse", + "Function reference", + "literal values", + "attribute name", + "find attribute", + "takes", + "inner", + "find application object", + "callable" + ] + expected_error = False + for error in error_list: + if error in str(e): + expected_error = True + if not expected_error: + raise e + +def main(): + atheris.Setup(sys.argv, TestInput, enable_python_coverage=True) + atheris.Fuzz() + +if __name__ == "__main__": + main() diff --git a/projects/gunicorn/project.yaml b/projects/gunicorn/project.yaml new file mode 100644 index 000000000..a03354d2a --- /dev/null +++ b/projects/gunicorn/project.yaml @@ -0,0 +1,12 @@ +fuzzing_engines: +- libfuzzer +homepage: https://github.com/benoitc/gunicorn +language: python +main_repo: https://github.com/benoitc/gunicorn +sanitizers: +- address +- undefined +vendor_ccs: +- david@adalogics.com +- adam@adalogics.com +- arthur.chan@adalogics.com