changeset 41013:ef103c96ed33

fuzz: extract Python initialization to utility package Avoids code duplication between fuzzers of parsers.so. Differential Revision: https://phab.mercurial-scm.org/D5461
author Augie Fackler <augie@google.com>
date Wed, 19 Dec 2018 21:57:23 -0500
parents 1e51dc85ce12
children c06f0ef9a5ba
files contrib/fuzz/Makefile contrib/fuzz/manifest.cc contrib/fuzz/pyutil.cc contrib/fuzz/pyutil.h
diffstat 4 files changed, 69 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- 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 */