annotate contrib/fuzz/manifest.cc @ 40788:41f0529b5112 stable

commandserver: get around ETIMEDOUT raised by selectors2 selector.select() should exits with an empty event list on timed out, but selectors2 raises OSError if timeout expires while recovering from EINTR. Spotted while debugging new chg feature.
author Yuya Nishihara <yuya@tcha.org>
date Mon, 03 Dec 2018 21:45:15 +0900
parents c3ab0a89331d
children ef103c96ed33
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
40053
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
1 #include <Python.h>
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
2 #include <assert.h>
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
3 #include <stdlib.h>
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
4 #include <unistd.h>
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
5
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
6 #include <string>
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
7
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
8 extern "C" {
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
9
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
10 /* TODO: use Python 3 for this fuzzing? */
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
11 PyMODINIT_FUNC initparsers(void);
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
12
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
13 static char cpypath[8192] = "\0";
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
14
40373
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
15 static PyCodeObject *code;
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
16 static PyObject *mainmod;
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
17 static PyObject *globals;
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
18
40053
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
19 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
20 {
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
21 const std::string subdir = "/sanpy/lib/python2.7";
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
22 /* HACK ALERT: we need a full Python installation built without
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
23 pymalloc and with ASAN, so we dump one in
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
24 $OUT/sanpy/lib/python2.7. This helps us wire that up. */
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
25 std::string selfpath(*argv[0]);
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
26 std::string pypath;
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
27 auto pos = selfpath.rfind("/");
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
28 if (pos == std::string::npos) {
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
29 char wd[8192];
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
30 getcwd(wd, 8192);
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
31 pypath = std::string(wd) + subdir;
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
32 } else {
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
33 pypath = selfpath.substr(0, pos) + subdir;
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
34 }
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
35 strncpy(cpypath, pypath.c_str(), pypath.size());
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
36 setenv("PYTHONPATH", cpypath, 1);
40146
adfe4bb53a47 fuzz: try setting PYTHONNOUSERSITE=1 to avoid loading site-packages
Augie Fackler <augie@google.com>
parents: 40100
diff changeset
37 setenv("PYTHONNOUSERSITE", "1", 1);
40280
170cd2a5a1da fuzz: try *even harder* to prevent Python from looking up usernames
Augie Fackler <augie@google.com>
parents: 40146
diff changeset
38 /* prevent Python from looking up users in the fuzz environment */
170cd2a5a1da fuzz: try *even harder* to prevent Python from looking up usernames
Augie Fackler <augie@google.com>
parents: 40146
diff changeset
39 setenv("PYTHONUSERBASE", cpypath, 1);
40053
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
40 Py_SetPythonHome(cpypath);
40089
3418f83c8874 fuzzers: init Python in LLVMFuzzerInitialize and intentionally leak it
Augie Fackler <augie@google.com>
parents: 40053
diff changeset
41 Py_InitializeEx(0);
40053
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
42 initparsers();
40373
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
43 code = (PyCodeObject *)Py_CompileString(R"py(
40053
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
44 from parsers import lazymanifest
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
45 try:
40100
ca4a32d0a4d6 fuzz: report error if Python code raised exception
Yuya Nishihara <yuya@tcha.org>
parents: 40089
diff changeset
46 lm = lazymanifest(mdata)
40053
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
47 # iterate the whole thing, which causes the code to fully parse
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
48 # every line in the manifest
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
49 list(lm.iterentries())
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
50 lm[b'xyzzy'] = (b'\0' * 20, 'x')
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
51 # do an insert, text should change
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
52 assert lm.text() != mdata, "insert should change text and didn't: %r %r" % (lm.text(), mdata)
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
53 del lm[b'xyzzy']
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
54 # should be back to the same
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
55 assert lm.text() == mdata, "delete should have restored text but didn't: %r %r" % (lm.text(), mdata)
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
56 except Exception as e:
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
57 pass
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
58 # uncomment this print if you're editing this Python code
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
59 # to debug failures.
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
60 # print e
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
61 )py",
40373
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
62 "fuzzer", Py_file_input);
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
63 mainmod = PyImport_AddModule("__main__");
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
64 globals = PyModule_GetDict(mainmod);
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
65 return 0;
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
66 }
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
67
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
68 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
69 {
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
70 PyObject *mtext =
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
71 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
72 PyObject *locals = PyDict_New();
c3ab0a89331d fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents: 40280
diff changeset
73 PyDict_SetItemString(locals, "mdata", mtext);
40100
ca4a32d0a4d6 fuzz: report error if Python code raised exception
Yuya Nishihara <yuya@tcha.org>
parents: 40089
diff changeset
74 PyObject *res = PyEval_EvalCode(code, globals, locals);
ca4a32d0a4d6 fuzz: report error if Python code raised exception
Yuya Nishihara <yuya@tcha.org>
parents: 40089
diff changeset
75 if (!res) {
ca4a32d0a4d6 fuzz: report error if Python code raised exception
Yuya Nishihara <yuya@tcha.org>
parents: 40089
diff changeset
76 PyErr_Print();
ca4a32d0a4d6 fuzz: report error if Python code raised exception
Yuya Nishihara <yuya@tcha.org>
parents: 40089
diff changeset
77 }
ca4a32d0a4d6 fuzz: report error if Python code raised exception
Yuya Nishihara <yuya@tcha.org>
parents: 40089
diff changeset
78 Py_XDECREF(res);
40053
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
79 Py_DECREF(locals);
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
80 Py_DECREF(mtext);
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
81 return 0; // Non-zero return values are reserved for future use.
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
82 }
8c692a6b5ad1 fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff changeset
83 }