diff --git a/projects/oracle-py-cx/Dockerfile b/projects/oracle-py-cx/Dockerfile new file mode 100644 index 000000000..22e2e41a7 --- /dev/null +++ b/projects/oracle-py-cx/Dockerfile @@ -0,0 +1,35 @@ +# 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 mkdir -p /opt/oracle +WORKDIR /opt/oracle +RUN wget https://download.oracle.com/otn_software/linux/instantclient/216000/instantclient-basic-linux.x64-21.6.0.0.0dbru.zip && \ + unzip instantclient-basic-linux.x64-21.6.0.0.0dbru.zip && \ + rm instantclient-basic-linux.x64-21.6.0.0.0dbru.zip && \ + echo /opt/oracle/instantclient_21_6 > /etc/ld.so.conf.d/oracle-instantclient.conf && \ + ldconfig + +ENV LD_LIBRARY_PATH=/opt/oracle/instantclient_21_6 +RUN apt-get install libaio1 libaio-dev +RUN pip3 install --upgrade pip && pip install requests + +RUN git clone https://github.com/oracle/python-cx_Oracle oracle-py-cx +WORKDIR oracle-py-cx +RUN git submodule init && \ + git submodule update + +COPY build.sh fuzz_*.py $SRC/ diff --git a/projects/oracle-py-cx/build.sh b/projects/oracle-py-cx/build.sh new file mode 100644 index 000000000..abf3f88a7 --- /dev/null +++ b/projects/oracle-py-cx/build.sh @@ -0,0 +1,21 @@ +#!/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. +# +################################################################################ + +pip3 install . +for fuzzer in $(find $SRC -name 'fuzz_*.py'); do + compile_python_fuzzer $fuzzer --add-binary /opt/oracle/instantclient_21_6:./ --add-binary /usr/lib/x86_64-linux-gnu/:./ +done diff --git a/projects/oracle-py-cx/fuzz_basic.py b/projects/oracle-py-cx/fuzz_basic.py new file mode 100644 index 000000000..70500190a --- /dev/null +++ b/projects/oracle-py-cx/fuzz_basic.py @@ -0,0 +1,94 @@ +#!/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 +import time +import socket +import threading +import cx_Oracle + +fuzzed_input = b"" + + +def SetFuzzedInput(input_bytes): + global fuzzed_input + fuzzed_input = input_bytes + + +class ServerThread(threading.Thread): + def __init__(self): + self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.s.bind(("127.0.0.1", 8009)) + self.s.settimeout(0.4) + self.s.listen(1) + + threading.Thread.__init__(self) + + def run(self): + global fuzzed_input + try: + conn, addr = self.s.accept() + except socket.timeout: + return + conn.recv(1024) + conn.send(fuzzed_input) + time.sleep(0.005) + conn.close() + self.s.shutdown(1) + self.s.close() + time.sleep(0.01) + + +@atheris.instrument_func +def TestInput(data): + t1 = ServerThread() + t1.start() + + fdp = atheris.FuzzedDataProvider(data) + args = dict() + args['user'] = fdp.ConsumeUnicodeNoSurrogates(64) + args['password'] = fdp.ConsumeUnicodeNoSurrogates(64) + args['dsn'] = "127.0.0.1:8009" + if fdp.ConsumeBool(): + args['newpassword'] = fdp.ConsumeUnicodeNoSurrogates(64) + if fdp.ConsumeBool(): + args['nencoding'] = fdp.ConsumeUnicodeNoSurrogates(64) + + SetFuzzedInput(fdp.ConsumeBytes(400)) + try: + connection = cx_Oracle.connect(**args) + except cx_Oracle.DatabaseError: + connection = None + pass + + if connection is None: + t1.join() + return + + cursor = connection.cursor() + cursor.execute(fdp.ConsumeUnicodeNoSurrogates(1024)) + t1.join() + + +def main(): + atheris.Setup(sys.argv, TestInput, enable_python_coverage=True) + atheris.instrument_all() + atheris.Fuzz() + + +if __name__ == "__main__": + main() diff --git a/projects/oracle-py-cx/project.yaml b/projects/oracle-py-cx/project.yaml new file mode 100644 index 000000000..6e74025a2 --- /dev/null +++ b/projects/oracle-py-cx/project.yaml @@ -0,0 +1,12 @@ +fuzzing_engines: +- libfuzzer +homepage: https://github.com/oracle/python-cx_Oracle +language: python +main_repo: https://github.com/oracle/python-cx_Oracle +sanitizers: +- address +- undefined +vendor_ccs: +- david@adalogics.com +- adam@adalogics.com +- arthur.chan@adalogics.com