D7033: fuzz: new fuzzer for fncache-related functions
durin42 (Augie Fackler)
phabricator at mercurial-scm.org
Wed Oct 9 16:19:06 UTC 2019
durin42 created this revision.
Herald added subscribers: mercurial-devel, mjpieters.
Herald added a reviewer: hg-reviewers.
REVISION SUMMARY
Not all of these are strictly fncache-related, but they all have th
same signature and similar-enough behavior that we may as well fuzz
them together. No obvious bugs for once, but these felt like they were
just complicated enough to cover.
REPOSITORY
rHG Mercurial
REVISION DETAIL
https://phab.mercurial-scm.org/D7033
AFFECTED FILES
contrib/fuzz/Makefile
contrib/fuzz/fncache.cc
CHANGE DETAILS
diff --git a/contrib/fuzz/fncache.cc b/contrib/fuzz/fncache.cc
new file mode 100644
--- /dev/null
+++ b/contrib/fuzz/fncache.cc
@@ -0,0 +1,78 @@
+#include <Python.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "pyutil.h"
+
+#include <iostream>
+#include <string>
+
+extern "C" {
+
+static PyCodeObject *code;
+
+extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+ contrib::initpy(*argv[0]);
+ code = (PyCodeObject *)Py_CompileString(R"py(
+from parsers import (
+ isasciistr,
+ asciilower,
+ asciiupper,
+ encodedir,
+ pathencode,
+ lowerencode,
+)
+
+try:
+ for fn in (
+ isasciistr,
+ asciilower,
+ asciiupper,
+ encodedir,
+ pathencode,
+ lowerencode,
+ ):
+ try:
+ fn(data)
+ except UnicodeDecodeError:
+ pass # some functions emit this exception
+ except AttributeError:
+ # pathencode needs hashlib, which fails to import because the time
+ # module fails to import. We should try and fix that some day, but
+ # for now we at least get coverage on non-hashencoded codepaths.
+ if fn != pathencode:
+ raise
+ # uncomment this for debugging exceptions
+ # except Exception as e:
+ # raise Exception('%r: %r' % (fn, e))
+except Exception as e:
+ pass
+ # uncomment this print if you're editing this Python code
+ # to debug failures.
+ # print(e)
+)py",
+ "fuzzer", Py_file_input);
+ if (!code) {
+ std::cerr << "failed to compile Python code!" << std::endl;
+ }
+ return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
+{
+ PyObject *mtext =
+ PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
+ PyObject *locals = PyDict_New();
+ PyDict_SetItemString(locals, "data", mtext);
+ PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
+ if (!res) {
+ PyErr_Print();
+ }
+ Py_XDECREF(res);
+ Py_DECREF(locals);
+ Py_DECREF(mtext);
+ return 0; // Non-zero return values are reserved for future use.
+}
+}
diff --git a/contrib/fuzz/Makefile b/contrib/fuzz/Makefile
--- a/contrib/fuzz/Makefile
+++ b/contrib/fuzz/Makefile
@@ -113,6 +113,14 @@
-lFuzzingEngine `$$OUT/sanpy/bin/python-config --ldflags` \
-o $$OUT/dirs_fuzzer
+fncache_fuzzer: fncache.cc manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o pyutil.o
+ $(CXX) $(CXXFLAGS) `$$OUT/sanpy/bin/python-config --cflags` \
+ -Wno-register -Wno-macro-redefined \
+ -I../../mercurial fncache.cc \
+ manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o pyutil.o \
+ -lFuzzingEngine `$$OUT/sanpy/bin/python-config --ldflags` \
+ -o $$OUT/fncache_fuzzer
+
manifest_corpus.zip:
python manifest_corpus.py $$OUT/manifest_fuzzer_seed_corpus.zip
@@ -163,6 +171,6 @@
mpatch \
xdiff
-oss-fuzz: bdiff_fuzzer mpatch_fuzzer mpatch_corpus.zip xdiff_fuzzer dirs_fuzzer manifest_fuzzer manifest_corpus.zip revlog_fuzzer revlog_corpus.zip dirstate_fuzzer dirstate_corpus.zip fm1readmarkers_fuzzer fm1readmarkers_corpus.zip
+oss-fuzz: bdiff_fuzzer mpatch_fuzzer mpatch_corpus.zip xdiff_fuzzer dirs_fuzzer fncache_fuzzer manifest_fuzzer manifest_corpus.zip revlog_fuzzer revlog_corpus.zip dirstate_fuzzer dirstate_corpus.zip fm1readmarkers_fuzzer fm1readmarkers_corpus.zip
.PHONY: all clean oss-fuzz
To: durin42, #hg-reviewers
Cc: mjpieters, mercurial-devel
More information about the Mercurial-devel
mailing list