fuzz: move many initialization steps into LLVMFuzzerInitialize
authorAugie Fackler <augie@google.com>
Thu, 18 Oct 2018 16:36:10 -0400
changeset 40373 c3ab0a89331d
parent 40372 81c80ed7c991
child 40374 47c03042cd1d
fuzz: move many initialization steps into LLVMFuzzerInitialize Doing this means that things we intentionally leak (eg type objects) no longer confuse AddressSanitizer, so now we can run the fuzzer MUCH longer. Differential Revision: https://phab.mercurial-scm.org/D5154
contrib/fuzz/manifest.cc
--- a/contrib/fuzz/manifest.cc	Thu Nov 17 15:51:33 2016 -0800
+++ b/contrib/fuzz/manifest.cc	Thu Oct 18 16:36:10 2018 -0400
@@ -12,6 +12,10 @@
 
 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";
@@ -35,20 +39,8 @@
 	setenv("PYTHONUSERBASE", cpypath, 1);
 	Py_SetPythonHome(cpypath);
 	Py_InitializeEx(0);
-	return 0;
-}
-
-int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
-{
 	initparsers();
-	PyObject *mtext =
-	    PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
-	PyObject *mainmod = PyImport_AddModule("__main__");
-	PyObject *globals = PyModule_GetDict(mainmod);
-	PyObject *locals = PyDict_New();
-	PyDict_SetItemString(locals, "mdata", mtext);
-	PyCodeObject *code =
-	    (PyCodeObject *)Py_CompileString(R"py(
+	code = (PyCodeObject *)Py_CompileString(R"py(
 from parsers import lazymanifest
 try:
   lm = lazymanifest(mdata)
@@ -67,13 +59,23 @@
   # to debug failures.
   # print e
 )py",
-	                                     "fuzzer", Py_file_input);
+	                                        "fuzzer", Py_file_input);
+	mainmod = PyImport_AddModule("__main__");
+	globals = PyModule_GetDict(mainmod);
+	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, "mdata", mtext);
 	PyObject *res = PyEval_EvalCode(code, globals, locals);
 	if (!res) {
 		PyErr_Print();
 	}
 	Py_XDECREF(res);
-	Py_DECREF(code);
 	Py_DECREF(locals);
 	Py_DECREF(mtext);
 	return 0; // Non-zero return values are reserved for future use.