Show More
@@ -0,0 +1,75 b'' | |||||
|
1 | #include <Python.h> | |||
|
2 | #include <assert.h> | |||
|
3 | #include <stdlib.h> | |||
|
4 | #include <unistd.h> | |||
|
5 | ||||
|
6 | #include <string> | |||
|
7 | ||||
|
8 | extern "C" { | |||
|
9 | ||||
|
10 | /* TODO: use Python 3 for this fuzzing? */ | |||
|
11 | PyMODINIT_FUNC initparsers(void); | |||
|
12 | ||||
|
13 | static char cpypath[8192] = "\0"; | |||
|
14 | ||||
|
15 | extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) | |||
|
16 | { | |||
|
17 | const std::string subdir = "/sanpy/lib/python2.7"; | |||
|
18 | /* HACK ALERT: we need a full Python installation built without | |||
|
19 | pymalloc and with ASAN, so we dump one in | |||
|
20 | $OUT/sanpy/lib/python2.7. This helps us wire that up. */ | |||
|
21 | std::string selfpath(*argv[0]); | |||
|
22 | std::string pypath; | |||
|
23 | auto pos = selfpath.rfind("/"); | |||
|
24 | if (pos == std::string::npos) { | |||
|
25 | char wd[8192]; | |||
|
26 | getcwd(wd, 8192); | |||
|
27 | pypath = std::string(wd) + subdir; | |||
|
28 | } else { | |||
|
29 | pypath = selfpath.substr(0, pos) + subdir; | |||
|
30 | } | |||
|
31 | strncpy(cpypath, pypath.c_str(), pypath.size()); | |||
|
32 | setenv("PYTHONPATH", cpypath, 1); | |||
|
33 | Py_SetPythonHome(cpypath); | |||
|
34 | return 0; | |||
|
35 | } | |||
|
36 | ||||
|
37 | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) | |||
|
38 | { | |||
|
39 | Py_InitializeEx(0); | |||
|
40 | initparsers(); | |||
|
41 | PyObject *mtext = | |||
|
42 | PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size); | |||
|
43 | PyObject *mainmod = PyImport_AddModule("__main__"); | |||
|
44 | PyObject *globals = PyModule_GetDict(mainmod); | |||
|
45 | PyObject *locals = PyDict_New(); | |||
|
46 | PyDict_SetItemString(locals, "mdata", mtext); | |||
|
47 | PyCodeObject *code = | |||
|
48 | (PyCodeObject *)Py_CompileString(R"py( | |||
|
49 | from parsers import lazymanifest | |||
|
50 | lm = lazymanifest(mdata) | |||
|
51 | try: | |||
|
52 | # iterate the whole thing, which causes the code to fully parse | |||
|
53 | # every line in the manifest | |||
|
54 | list(lm.iterentries()) | |||
|
55 | lm[b'xyzzy'] = (b'\0' * 20, 'x') | |||
|
56 | # do an insert, text should change | |||
|
57 | assert lm.text() != mdata, "insert should change text and didn't: %r %r" % (lm.text(), mdata) | |||
|
58 | del lm[b'xyzzy'] | |||
|
59 | # should be back to the same | |||
|
60 | assert lm.text() == mdata, "delete should have restored text but didn't: %r %r" % (lm.text(), mdata) | |||
|
61 | except Exception as e: | |||
|
62 | pass | |||
|
63 | # uncomment this print if you're editing this Python code | |||
|
64 | # to debug failures. | |||
|
65 | # print e | |||
|
66 | )py", | |||
|
67 | "fuzzer", Py_file_input); | |||
|
68 | PyEval_EvalCode(code, globals, locals); | |||
|
69 | Py_DECREF(code); | |||
|
70 | Py_DECREF(locals); | |||
|
71 | Py_DECREF(mtext); | |||
|
72 | Py_Finalize(); | |||
|
73 | return 0; // Non-zero return values are reserved for future use. | |||
|
74 | } | |||
|
75 | } |
@@ -0,0 +1,30 b'' | |||||
|
1 | from __future__ import absolute_import, print_function | |||
|
2 | ||||
|
3 | import argparse | |||
|
4 | import zipfile | |||
|
5 | ||||
|
6 | ap = argparse.ArgumentParser() | |||
|
7 | ap.add_argument("out", metavar="some.zip", type=str, nargs=1) | |||
|
8 | args = ap.parse_args() | |||
|
9 | ||||
|
10 | with zipfile.ZipFile(args.out[0], "w", zipfile.ZIP_STORED) as zf: | |||
|
11 | zf.writestr("manifest_zero", | |||
|
12 | '''PKG-INFO\09b3ed8f2b81095a13064402e930565f083346e9a | |||
|
13 | README\080b6e76643dcb44d4bc729e932fc464b3e36dbe3 | |||
|
14 | hg\0b6444347c629cc058d478023905cfb83b7f5bb9d | |||
|
15 | mercurial/__init__.py\0b80de5d138758541c5f05265ad144ab9fa86d1db | |||
|
16 | mercurial/byterange.py\017f5a9fbd99622f31a392c33ac1e903925dc80ed | |||
|
17 | mercurial/fancyopts.py\0b6f52e23e356748c5039313d8b639cda16bf67ba | |||
|
18 | mercurial/hg.py\023cc12f225f1b42f32dc0d897a4f95a38ddc8f4a | |||
|
19 | mercurial/mdiff.py\0a05f65c44bfbeec6a42336cd2ff0b30217899ca3 | |||
|
20 | mercurial/revlog.py\0217bc3fde6d82c0210cf56aeae11d05a03f35b2b | |||
|
21 | mercurial/transaction.py\09d180df101dc14ce3dd582fd998b36c98b3e39aa | |||
|
22 | notes.txt\0703afcec5edb749cf5cec67831f554d6da13f2fb | |||
|
23 | setup.py\0ccf3f6daf0f13101ca73631f7a1769e328b472c9 | |||
|
24 | tkmerge\03c922edb43a9c143682f7bc7b00f98b3c756ebe7 | |||
|
25 | ''') | |||
|
26 | zf.writestr("badmanifest_shorthashes", | |||
|
27 | "narf\0aa\nnarf2\0aaa\n") | |||
|
28 | zf.writestr("badmanifest_nonull", | |||
|
29 | "narf\0cccccccccccccccccccccccccccccccccccccccc\n" | |||
|
30 | "narf2aaaaaaaaaaaaaaaaaaaa\n") |
@@ -70,12 +70,62 b' xdiff_fuzzer: xdiff.cc fuzz-xdiffi.o fuz' | |||||
70 | fuzz-xdiffi.o fuzz-xprepare.o fuzz-xutils.o fuzzutil-oss-fuzz.o \ |
|
70 | fuzz-xdiffi.o fuzz-xprepare.o fuzz-xutils.o fuzzutil-oss-fuzz.o \ | |
71 | -lFuzzingEngine -o $$OUT/xdiff_fuzzer |
|
71 | -lFuzzingEngine -o $$OUT/xdiff_fuzzer | |
72 |
|
72 | |||
|
73 | # TODO use the $OUT env var instead of hardcoding /out | |||
|
74 | /out/sanpy/bin/python: | |||
|
75 | cd /Python-2.7.15/ && ./configure --without-pymalloc --prefix=$$OUT/sanpy CFLAGS='-O1 -fno-omit-frame-pointer -g -fwrapv -fstack-protector-strong' LDFLAGS=-lasan && ASAN_OPTIONS=detect_leaks=0 make && make install | |||
|
76 | ||||
|
77 | sanpy: /out/sanpy/bin/python | |||
|
78 | ||||
|
79 | manifest.o: sanpy ../../mercurial/cext/manifest.c | |||
|
80 | $(CC) $(CFLAGS) `$$OUT/sanpy/bin/python-config --cflags` \ | |||
|
81 | -I../../mercurial \ | |||
|
82 | -c -o manifest.o ../../mercurial/cext/manifest.c | |||
|
83 | ||||
|
84 | charencode.o: sanpy ../../mercurial/cext/charencode.c | |||
|
85 | $(CC) $(CFLAGS) `$$OUT/sanpy/bin/python-config --cflags` \ | |||
|
86 | -I../../mercurial \ | |||
|
87 | -c -o charencode.o ../../mercurial/cext/charencode.c | |||
|
88 | ||||
|
89 | parsers.o: sanpy ../../mercurial/cext/parsers.c | |||
|
90 | $(CC) $(CFLAGS) `$$OUT/sanpy/bin/python-config --cflags` \ | |||
|
91 | -I../../mercurial \ | |||
|
92 | -c -o parsers.o ../../mercurial/cext/parsers.c | |||
|
93 | ||||
|
94 | dirs.o: sanpy ../../mercurial/cext/dirs.c | |||
|
95 | $(CC) $(CFLAGS) `$$OUT/sanpy/bin/python-config --cflags` \ | |||
|
96 | -I../../mercurial \ | |||
|
97 | -c -o dirs.o ../../mercurial/cext/dirs.c | |||
|
98 | ||||
|
99 | pathencode.o: sanpy ../../mercurial/cext/pathencode.c | |||
|
100 | $(CC) $(CFLAGS) `$$OUT/sanpy/bin/python-config --cflags` \ | |||
|
101 | -I../../mercurial \ | |||
|
102 | -c -o pathencode.o ../../mercurial/cext/pathencode.c | |||
|
103 | ||||
|
104 | revlog.o: sanpy ../../mercurial/cext/revlog.c | |||
|
105 | $(CC) $(CFLAGS) `$$OUT/sanpy/bin/python-config --cflags` \ | |||
|
106 | -I../../mercurial \ | |||
|
107 | -c -o revlog.o ../../mercurial/cext/revlog.c | |||
|
108 | ||||
|
109 | manifest_fuzzer: sanpy manifest.cc manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o | |||
|
110 | $(CXX) $(CXXFLAGS) `$$OUT/sanpy/bin/python-config --cflags` \ | |||
|
111 | -Wno-register -Wno-macro-redefined \ | |||
|
112 | -I../../mercurial manifest.cc \ | |||
|
113 | manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o \ | |||
|
114 | -lFuzzingEngine `$$OUT/sanpy/bin/python-config --ldflags` \ | |||
|
115 | -o $$OUT/manifest_fuzzer | |||
|
116 | ||||
|
117 | manifest_corpus.zip: | |||
|
118 | python manifest_corpus.py $$OUT/manifest_fuzzer_seed_corpus.zip | |||
|
119 | ||||
|
120 | copy_options: | |||
|
121 | cp *.options $$OUT | |||
|
122 | ||||
73 | clean: |
|
123 | clean: | |
74 | $(RM) *.o *_fuzzer \ |
|
124 | $(RM) *.o *_fuzzer \ | |
75 | bdiff \ |
|
125 | bdiff \ | |
76 | mpatch \ |
|
126 | mpatch \ | |
77 | xdiff |
|
127 | xdiff | |
78 |
|
128 | |||
79 | oss-fuzz: bdiff_fuzzer mpatch_fuzzer mpatch_corpus.zip xdiff_fuzzer |
|
129 | oss-fuzz: bdiff_fuzzer mpatch_fuzzer mpatch_corpus.zip xdiff_fuzzer manifest_fuzzer manifest_corpus.zip copy_options | |
80 |
|
130 | |||
81 | .PHONY: all clean oss-fuzz |
|
131 | .PHONY: all clean oss-fuzz sanpy copy_options |
General Comments 0
You need to be logged in to leave comments.
Login now