changeset 40373:c3ab0a89331d

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
author Augie Fackler <augie@google.com>
date Thu, 18 Oct 2018 16:36:10 -0400
parents 81c80ed7c991
children 47c03042cd1d
files contrib/fuzz/manifest.cc
diffstat 1 files changed, 17 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- 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.