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") |
@@ -1,81 +1,131 b'' | |||
|
1 | 1 | CC = clang |
|
2 | 2 | CXX = clang++ |
|
3 | 3 | |
|
4 | 4 | all: bdiff mpatch xdiff |
|
5 | 5 | |
|
6 | 6 | fuzzutil.o: fuzzutil.cc fuzzutil.h |
|
7 | 7 | $(CXX) $(CXXFLAGS) -g -O1 -fsanitize=fuzzer-no-link,address \ |
|
8 | 8 | -std=c++17 \ |
|
9 | 9 | -I../../mercurial -c -o fuzzutil.o fuzzutil.cc |
|
10 | 10 | |
|
11 | 11 | fuzzutil-oss-fuzz.o: fuzzutil.cc fuzzutil.h |
|
12 | 12 | $(CXX) $(CXXFLAGS) -std=c++17 \ |
|
13 | 13 | -I../../mercurial -c -o fuzzutil-oss-fuzz.o fuzzutil.cc |
|
14 | 14 | |
|
15 | 15 | bdiff.o: ../../mercurial/bdiff.c |
|
16 | 16 | $(CC) $(CFLAGS) -fsanitize=fuzzer-no-link,address -c -o bdiff.o \ |
|
17 | 17 | ../../mercurial/bdiff.c |
|
18 | 18 | |
|
19 | 19 | bdiff: bdiff.cc bdiff.o fuzzutil.o |
|
20 | 20 | $(CXX) $(CXXFLAGS) -DHG_FUZZER_INCLUDE_MAIN=1 -g -O1 -fsanitize=fuzzer-no-link,address \ |
|
21 | 21 | -std=c++17 \ |
|
22 | 22 | -I../../mercurial bdiff.cc bdiff.o fuzzutil.o -o bdiff |
|
23 | 23 | |
|
24 | 24 | bdiff-oss-fuzz.o: ../../mercurial/bdiff.c |
|
25 | 25 | $(CC) $(CFLAGS) -c -o bdiff-oss-fuzz.o ../../mercurial/bdiff.c |
|
26 | 26 | |
|
27 | 27 | bdiff_fuzzer: bdiff.cc bdiff-oss-fuzz.o fuzzutil-oss-fuzz.o |
|
28 | 28 | $(CXX) $(CXXFLAGS) -std=c++17 -I../../mercurial bdiff.cc \ |
|
29 | 29 | bdiff-oss-fuzz.o fuzzutil-oss-fuzz.o -lFuzzingEngine -o \ |
|
30 | 30 | $$OUT/bdiff_fuzzer |
|
31 | 31 | |
|
32 | 32 | mpatch.o: ../../mercurial/mpatch.c |
|
33 | 33 | $(CC) -g -O1 -fsanitize=fuzzer-no-link,address -c -o mpatch.o \ |
|
34 | 34 | ../../mercurial/mpatch.c |
|
35 | 35 | |
|
36 | 36 | mpatch: CXXFLAGS += -std=c++17 |
|
37 | 37 | mpatch: mpatch.cc mpatch.o fuzzutil.o |
|
38 | 38 | $(CXX) $(CXXFLAGS) -DHG_FUZZER_INCLUDE_MAIN=1 -g -O1 -fsanitize=fuzzer-no-link,address \ |
|
39 | 39 | -I../../mercurial mpatch.cc mpatch.o fuzzutil.o -o mpatch |
|
40 | 40 | |
|
41 | 41 | mpatch-oss-fuzz.o: ../../mercurial/mpatch.c |
|
42 | 42 | $(CC) $(CFLAGS) -c -o mpatch-oss-fuzz.o ../../mercurial/mpatch.c |
|
43 | 43 | |
|
44 | 44 | mpatch_fuzzer: mpatch.cc mpatch-oss-fuzz.o fuzzutil-oss-fuzz.o |
|
45 | 45 | $(CXX) $(CXXFLAGS) -std=c++17 -I../../mercurial mpatch.cc \ |
|
46 | 46 | mpatch-oss-fuzz.o fuzzutil-oss-fuzz.o -lFuzzingEngine -o \ |
|
47 | 47 | $$OUT/mpatch_fuzzer |
|
48 | 48 | |
|
49 | 49 | mpatch_corpus.zip: |
|
50 | 50 | python mpatch_corpus.py $$OUT/mpatch_fuzzer_seed_corpus.zip |
|
51 | 51 | |
|
52 | 52 | x%.o: ../../mercurial/thirdparty/xdiff/x%.c ../../mercurial/thirdparty/xdiff/*.h |
|
53 | 53 | $(CC) -g -O1 -fsanitize=fuzzer-no-link,address -c \ |
|
54 | 54 | -o $@ \ |
|
55 | 55 | $< |
|
56 | 56 | |
|
57 | 57 | xdiff: CXXFLAGS += -std=c++17 |
|
58 | 58 | xdiff: xdiff.cc xdiffi.o xprepare.o xutils.o fuzzutil.o |
|
59 | 59 | $(CXX) $(CXXFLAGS) -DHG_FUZZER_INCLUDE_MAIN=1 -g -O1 -fsanitize=fuzzer-no-link,address \ |
|
60 | 60 | -I../../mercurial xdiff.cc \ |
|
61 | 61 | xdiffi.o xprepare.o xutils.o fuzzutil.o -o xdiff |
|
62 | 62 | |
|
63 | 63 | fuzz-x%.o: ../../mercurial/thirdparty/xdiff/x%.c ../../mercurial/thirdparty/xdiff/*.h |
|
64 | 64 | $(CC) $(CFLAGS) -c \ |
|
65 | 65 | -o $@ \ |
|
66 | 66 | $< |
|
67 | 67 | |
|
68 | 68 | xdiff_fuzzer: xdiff.cc fuzz-xdiffi.o fuzz-xprepare.o fuzz-xutils.o fuzzutil-oss-fuzz.o |
|
69 | 69 | $(CXX) $(CXXFLAGS) -std=c++17 -I../../mercurial xdiff.cc \ |
|
70 | 70 | fuzz-xdiffi.o fuzz-xprepare.o fuzz-xutils.o fuzzutil-oss-fuzz.o \ |
|
71 | 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 | 123 | clean: |
|
74 | 124 | $(RM) *.o *_fuzzer \ |
|
75 | 125 | bdiff \ |
|
76 | 126 | mpatch \ |
|
77 | 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