Mercurial > public > mercurial-scm > hg
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 |
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 } |