fuzz: extract Python initialization to utility package
Avoids code duplication between fuzzers of parsers.so.
Differential Revision: https://phab.mercurial-scm.org/D5461
--- a/contrib/fuzz/Makefile Wed Dec 19 23:40:37 2018 -0500
+++ b/contrib/fuzz/Makefile Wed Dec 19 21:57:23 2018 -0500
@@ -12,6 +12,11 @@
$(CXX) $(CXXFLAGS) -std=c++17 \
-I../../mercurial -c -o fuzzutil-oss-fuzz.o fuzzutil.cc
+pyutil.o: pyutil.cc pyutil.h
+ $(CXX) $(CXXFLAGS) -g -O1 \
+ `$$OUT/sanpy/bin/python-config --cflags` \
+ -I../../mercurial -c -o pyutil.o pyutil.cc
+
bdiff.o: ../../mercurial/bdiff.c
$(CC) $(CFLAGS) -fsanitize=fuzzer-no-link,address -c -o bdiff.o \
../../mercurial/bdiff.c
@@ -108,11 +113,11 @@
-I../../mercurial \
-c -o revlog.o ../../mercurial/cext/revlog.c
-manifest_fuzzer: sanpy manifest.cc manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o
+manifest_fuzzer: sanpy manifest.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 manifest.cc \
- manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o \
+ manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o pyutil.o \
-lFuzzingEngine `$$OUT/sanpy/bin/python-config --ldflags` \
-o $$OUT/manifest_fuzzer
--- a/contrib/fuzz/manifest.cc Wed Dec 19 23:40:37 2018 -0500
+++ b/contrib/fuzz/manifest.cc Wed Dec 19 21:57:23 2018 -0500
@@ -3,43 +3,17 @@
#include <stdlib.h>
#include <unistd.h>
+#include "pyutil.h"
+
#include <string>
extern "C" {
-/* TODO: use Python 3 for this fuzzing? */
-PyMODINIT_FUNC initparsers(void);
-
-static char cpypath[8192] = "\0";
-
static PyCodeObject *code;
-static PyObject *mainmod;
-static PyObject *globals;
extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
{
- const std::string subdir = "/sanpy/lib/python2.7";
- /* HACK ALERT: we need a full Python installation built without
- pymalloc and with ASAN, so we dump one in
- $OUT/sanpy/lib/python2.7. This helps us wire that up. */
- std::string selfpath(*argv[0]);
- std::string pypath;
- auto pos = selfpath.rfind("/");
- if (pos == std::string::npos) {
- char wd[8192];
- getcwd(wd, 8192);
- pypath = std::string(wd) + subdir;
- } else {
- pypath = selfpath.substr(0, pos) + subdir;
- }
- strncpy(cpypath, pypath.c_str(), pypath.size());
- setenv("PYTHONPATH", cpypath, 1);
- setenv("PYTHONNOUSERSITE", "1", 1);
- /* prevent Python from looking up users in the fuzz environment */
- setenv("PYTHONUSERBASE", cpypath, 1);
- Py_SetPythonHome(cpypath);
- Py_InitializeEx(0);
- initparsers();
+ contrib::initpy(*argv[0]);
code = (PyCodeObject *)Py_CompileString(R"py(
from parsers import lazymanifest
try:
@@ -60,8 +34,6 @@
# print e
)py",
"fuzzer", Py_file_input);
- mainmod = PyImport_AddModule("__main__");
- globals = PyModule_GetDict(mainmod);
return 0;
}
@@ -71,7 +43,7 @@
PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
PyObject *locals = PyDict_New();
PyDict_SetItemString(locals, "mdata", mtext);
- PyObject *res = PyEval_EvalCode(code, globals, locals);
+ PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
if (!res) {
PyErr_Print();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/fuzz/pyutil.cc Wed Dec 19 21:57:23 2018 -0500
@@ -0,0 +1,49 @@
+#include "pyutil.h"
+
+#include <string>
+
+namespace contrib
+{
+
+static char cpypath[8192] = "\0";
+
+static PyObject *mainmod;
+static PyObject *globals;
+
+/* TODO: use Python 3 for this fuzzing? */
+PyMODINIT_FUNC initparsers(void);
+
+void initpy(const char *cselfpath)
+{
+ const std::string subdir = "/sanpy/lib/python2.7";
+ /* HACK ALERT: we need a full Python installation built without
+ pymalloc and with ASAN, so we dump one in
+ $OUT/sanpy/lib/python2.7. This helps us wire that up. */
+ std::string selfpath(cselfpath);
+ std::string pypath;
+ auto pos = selfpath.rfind("/");
+ if (pos == std::string::npos) {
+ char wd[8192];
+ getcwd(wd, 8192);
+ pypath = std::string(wd) + subdir;
+ } else {
+ pypath = selfpath.substr(0, pos) + subdir;
+ }
+ strncpy(cpypath, pypath.c_str(), pypath.size());
+ setenv("PYTHONPATH", cpypath, 1);
+ setenv("PYTHONNOUSERSITE", "1", 1);
+ /* prevent Python from looking up users in the fuzz environment */
+ setenv("PYTHONUSERBASE", cpypath, 1);
+ Py_SetPythonHome(cpypath);
+ Py_InitializeEx(0);
+ mainmod = PyImport_AddModule("__main__");
+ globals = PyModule_GetDict(mainmod);
+ initparsers();
+}
+
+PyObject *pyglobals()
+{
+ return globals;
+}
+
+} // namespace contrib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/fuzz/pyutil.h Wed Dec 19 21:57:23 2018 -0500
@@ -0,0 +1,9 @@
+#include <Python.h>
+
+namespace contrib
+{
+
+void initpy(const char *cselfpath);
+PyObject *pyglobals();
+
+} /* namespace contrib */