Skip to main content

Fuzz.

Project description

About

!!! UNDER CONSTRUCTION - DO NOT USE !!!

Use libFuzzer to fuzzy-test Python C extension modules.

Ideas

  • Use type annotations for less type errors in generic mutator.
  • Add support to fuzzy test pure Python modules by generating C code from them using Cython.

Installation

$ apt install clang
$ pip install pyfuzzer

Example Usage

Use the default generic mutator when testing the module hello_world.

$ cd examples/hello_world
$ pyfuzzer hello_world.c
clang -fprofile-instr-generate -fcoverage-mapping -I/usr/include/python3.7m -g -fsanitize=fuzzer -fsanitize=signed-integer-overflow -fno-sanitize-recover=all hello_world.c module.c ../../pyfuzzer/pyfuzzer.c -lpython3.7m -o hello_world
rm -f hello_world.profraw
./hello_world -max_total_time=5 -max_len=4096
INFO: Seed: 2099947845
INFO: Loaded 1 modules   (22 inline 8-bit counters): 22 [0x47444d, 0x474463),
INFO: Loaded 1 PC tables (22 PCs): 22 [0x4616c0,0x461820),
ModuleNotFoundError: No module named 'mutator'
INFO: A corpus is not provided, starting from an empty corpus
#2   INITED cov: 7 ft: 8 corp: 1/1b lim: 4 exec/s: 0 rss: 43Mb
#8   NEW    cov: 8 ft: 9 corp: 2/3b lim: 4 exec/s: 0 rss: 43Mb L: 2/2 MS: 1 InsertByte-
#10  NEW    cov: 9 ft: 10 corp: 3/6b lim: 4 exec/s: 0 rss: 43Mb L: 3/3 MS: 2 CopyPart-InsertByte-
#11  NEW    cov: 10 ft: 11 corp: 4/10b lim: 4 exec/s: 0 rss: 43Mb L: 4/4 MS: 1 InsertByte-
#1048576     pulse  cov: 10 ft: 11 corp: 4/10b lim: 4096 exec/s: 524288 rss: 43Mb
#2097152     pulse  cov: 10 ft: 11 corp: 4/10b lim: 4096 exec/s: 699050 rss: 43Mb
#3189296     DONE   cov: 10 ft: 11 corp: 4/10b lim: 4096 exec/s: 531549 rss: 43Mb
Done 3189296 runs in 6 second(s)
llvm-profdata merge -sparse hello_world.profraw -o hello_world.profdata
llvm-cov show hello_world -instr-profile=hello_world.profdata
/home/erik/workspace/pyfuzzer/examples/hello_world/hello_world.c:
    1|       |#include <Python.h>
    2|       |
    3|       |PyDoc_STRVAR(
    4|       |    tell_doc,
    5|       |    "tell(message)\n"
    6|       |    "--\n"
    7|       |    "Arguments: (message:bytes)\n");
    8|       |
    9|       |static PyObject *m_tell(PyObject *module_p, PyObject *message_p)
   10|  3.18M|{
   11|  3.18M|    Py_ssize_t size;
   12|  3.18M|    char* buf_p;
   13|  3.18M|    int res;
   14|  3.18M|    PyObject *res_p;
   15|  3.18M|
   16|  3.18M|    res = PyBytes_AsStringAndSize(message_p, &buf_p, &size);
   17|  3.18M|
   18|  3.18M|    if (res != -1) {
   19|  3.18M|        switch (size) {
   20|  3.18M|
   21|  3.18M|        case 0:
   22|   144k|            res_p = PyLong_FromLong(5);
   23|   144k|            break;
   24|  3.18M|
   25|  3.18M|        case 1:
   26|   328k|            res_p = PyBool_FromLong(1);
   27|   328k|            break;
   28|  3.18M|
   29|  3.18M|        case 2:
   30|   348k|            res_p = PyBytes_FromString("Hello!");
   31|   348k|            break;
   32|  3.18M|
   33|  3.18M|        default:
   34|  2.36M|            res_p = PyLong_FromLong(0);
   35|  2.36M|            break;
   36|      0|        }
   37|      0|    } else {
   38|      0|        Py_INCREF(Py_None);
   39|      0|        res_p = Py_None;
   40|      0|    }
   41|  3.18M|
   42|  3.18M|    return (res_p);
   43|  3.18M|}
   44|       |
   45|       |static struct PyMethodDef methods[] = {
   46|       |    { "tell", m_tell, METH_O, tell_doc},
   47|       |    { NULL }
   48|       |};
   49|       |
   50|       |static PyModuleDef module = {
   51|       |    PyModuleDef_HEAD_INIT,
   52|       |    .m_name = "hello_world",
   53|       |    .m_size = -1,
   54|       |    .m_methods = methods
   55|       |};
   56|       |
   57|       |PyMODINIT_FUNC PyInit_hello_world(void)
   58|      1|{
   59|      1|    return (PyModule_Create(&module));
   60|      1|}
...

Use a custom mutator when testing the module hello_world.

Testing with a custom mutator is often more efficient then using a generic.

$ cd examples/hello_world
$ pyfuzzer -m mutator.py hello_world.c
...

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for pyfuzzer, version 0.2.0
Filename, size File type Python version Upload date Hashes
Filename, size pyfuzzer-0.2.0.tar.gz (5.8 kB) File type Source Python version None Upload date Hashes View

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring DigiCert DigiCert EV certificate Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page