Skip to content
Merged
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
31 changes: 17 additions & 14 deletions Modules/_xxtestfuzz/README.rst
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
Fuzz Tests for CPython
======================

These fuzz tests are designed to be included in Google's `oss-fuzz`_ project.
These fuzz tests are designed to be included in Google's `OSS-Fuzz`_ project.

oss-fuzz works against a library exposing a function of the form
OSS-Fuzz works against a library exposing a function of the form
``int LLVMFuzzerTestOneInput(const uint8_t* data, size_t length)``. We provide
that library (``fuzzer.c``), and include a ``_fuzz`` module for testing with
that library (``fuzzer.c``), and include a ``_xxtestfuzz`` module for testing with
some toy values -- no fuzzing occurs in Python's test suite.

oss-fuzz will regularly pull from CPython, discover all the tests in
OSS-Fuzz will regularly pull from CPython, discover all the tests in
``fuzz_tests.txt``, and run them -- so adding a new test here means it will
automatically be run in oss-fuzz, while also being smoke-tested as part of
automatically be run in OSS-Fuzz, while also being smoke-tested as part of
CPython's test suite.

In addition, the tests are run on GitHub Actions using CIFuzz for PRs to the
main branch changing relevant files.
In addition, the tests are run on GitHub Actions using `CIFuzz
<https://google.github.io/oss-fuzz/getting-started/continuous-integration/>`_
for PRs to the ``main`` branch changing relevant files.


Adding a new fuzz test
----------------------
Expand All @@ -28,7 +30,6 @@ In ``fuzzer.c``, add a function to be run::
return 0;
}


And invoke it from ``LLVMFuzzerTestOneInput``::

#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_$fuzz_test_name)
Expand All @@ -37,25 +38,27 @@ And invoke it from ``LLVMFuzzerTestOneInput``::

Don't forget to replace ``$fuzz_test_name`` with your actual test name.

``LLVMFuzzerTestOneInput`` will run in oss-fuzz, with each test in
``LLVMFuzzerTestOneInput`` will run in OSS-Fuzz, with each test in
``fuzz_tests.txt`` run separately.

Seed data (corpus) for the test can be provided in a subfolder called
``<test_name>_corpus`` such as ``fuzz_json_loads_corpus``. A wide variety
of good input samples allows the fuzzer to more easily explore a diverse
set of paths and provides a better base to find buggy input from.

Dictionaries of tokens (see oss-fuzz documentation for more details) can
be placed in the ``dictionaries`` folder with the name of the test.
Dictionaries of tokens (see the `libFuzzer documentation
<https://llvm.org/docs/LibFuzzer.html#dictionaries>`_ for more information) can
be placed in the ``dictionaries/`` folder with the name of the test.
For example, ``dictionaries/fuzz_json_loads.dict`` contains JSON tokens
to guide the fuzzer.


What makes a good fuzz test
---------------------------

Libraries written in C that might handle untrusted data are worthwhile. The
more complex the logic (e.g. parsing), the more likely this is to be a useful
more complex the logic (e.g., parsing), the more likely this is to be a useful
fuzz test. See the existing examples for reference, and refer to the
`oss-fuzz`_ docs.
`OSS-Fuzz`_ docs.

.. _oss-fuzz: https://github.com/google/oss-fuzz
.. _OSS-Fuzz: https://github.com/google/oss-fuzz
Loading