##// END OF EJS Templates
fuzz: new fuzzer for cext/manifest.c...
Augie Fackler -
r40089:8c692a6b default
parent child Browse files
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")
@@ -0,0 +1,2 b''
1 [libfuzzer]
2 detect_leaks = 0
@@ -1,81 +1,131 b''
1 CC = clang
1 CC = clang
2 CXX = clang++
2 CXX = clang++
3
3
4 all: bdiff mpatch xdiff
4 all: bdiff mpatch xdiff
5
5
6 fuzzutil.o: fuzzutil.cc fuzzutil.h
6 fuzzutil.o: fuzzutil.cc fuzzutil.h
7 $(CXX) $(CXXFLAGS) -g -O1 -fsanitize=fuzzer-no-link,address \
7 $(CXX) $(CXXFLAGS) -g -O1 -fsanitize=fuzzer-no-link,address \
8 -std=c++17 \
8 -std=c++17 \
9 -I../../mercurial -c -o fuzzutil.o fuzzutil.cc
9 -I../../mercurial -c -o fuzzutil.o fuzzutil.cc
10
10
11 fuzzutil-oss-fuzz.o: fuzzutil.cc fuzzutil.h
11 fuzzutil-oss-fuzz.o: fuzzutil.cc fuzzutil.h
12 $(CXX) $(CXXFLAGS) -std=c++17 \
12 $(CXX) $(CXXFLAGS) -std=c++17 \
13 -I../../mercurial -c -o fuzzutil-oss-fuzz.o fuzzutil.cc
13 -I../../mercurial -c -o fuzzutil-oss-fuzz.o fuzzutil.cc
14
14
15 bdiff.o: ../../mercurial/bdiff.c
15 bdiff.o: ../../mercurial/bdiff.c
16 $(CC) $(CFLAGS) -fsanitize=fuzzer-no-link,address -c -o bdiff.o \
16 $(CC) $(CFLAGS) -fsanitize=fuzzer-no-link,address -c -o bdiff.o \
17 ../../mercurial/bdiff.c
17 ../../mercurial/bdiff.c
18
18
19 bdiff: bdiff.cc bdiff.o fuzzutil.o
19 bdiff: bdiff.cc bdiff.o fuzzutil.o
20 $(CXX) $(CXXFLAGS) -DHG_FUZZER_INCLUDE_MAIN=1 -g -O1 -fsanitize=fuzzer-no-link,address \
20 $(CXX) $(CXXFLAGS) -DHG_FUZZER_INCLUDE_MAIN=1 -g -O1 -fsanitize=fuzzer-no-link,address \
21 -std=c++17 \
21 -std=c++17 \
22 -I../../mercurial bdiff.cc bdiff.o fuzzutil.o -o bdiff
22 -I../../mercurial bdiff.cc bdiff.o fuzzutil.o -o bdiff
23
23
24 bdiff-oss-fuzz.o: ../../mercurial/bdiff.c
24 bdiff-oss-fuzz.o: ../../mercurial/bdiff.c
25 $(CC) $(CFLAGS) -c -o bdiff-oss-fuzz.o ../../mercurial/bdiff.c
25 $(CC) $(CFLAGS) -c -o bdiff-oss-fuzz.o ../../mercurial/bdiff.c
26
26
27 bdiff_fuzzer: bdiff.cc bdiff-oss-fuzz.o fuzzutil-oss-fuzz.o
27 bdiff_fuzzer: bdiff.cc bdiff-oss-fuzz.o fuzzutil-oss-fuzz.o
28 $(CXX) $(CXXFLAGS) -std=c++17 -I../../mercurial bdiff.cc \
28 $(CXX) $(CXXFLAGS) -std=c++17 -I../../mercurial bdiff.cc \
29 bdiff-oss-fuzz.o fuzzutil-oss-fuzz.o -lFuzzingEngine -o \
29 bdiff-oss-fuzz.o fuzzutil-oss-fuzz.o -lFuzzingEngine -o \
30 $$OUT/bdiff_fuzzer
30 $$OUT/bdiff_fuzzer
31
31
32 mpatch.o: ../../mercurial/mpatch.c
32 mpatch.o: ../../mercurial/mpatch.c
33 $(CC) -g -O1 -fsanitize=fuzzer-no-link,address -c -o mpatch.o \
33 $(CC) -g -O1 -fsanitize=fuzzer-no-link,address -c -o mpatch.o \
34 ../../mercurial/mpatch.c
34 ../../mercurial/mpatch.c
35
35
36 mpatch: CXXFLAGS += -std=c++17
36 mpatch: CXXFLAGS += -std=c++17
37 mpatch: mpatch.cc mpatch.o fuzzutil.o
37 mpatch: mpatch.cc mpatch.o fuzzutil.o
38 $(CXX) $(CXXFLAGS) -DHG_FUZZER_INCLUDE_MAIN=1 -g -O1 -fsanitize=fuzzer-no-link,address \
38 $(CXX) $(CXXFLAGS) -DHG_FUZZER_INCLUDE_MAIN=1 -g -O1 -fsanitize=fuzzer-no-link,address \
39 -I../../mercurial mpatch.cc mpatch.o fuzzutil.o -o mpatch
39 -I../../mercurial mpatch.cc mpatch.o fuzzutil.o -o mpatch
40
40
41 mpatch-oss-fuzz.o: ../../mercurial/mpatch.c
41 mpatch-oss-fuzz.o: ../../mercurial/mpatch.c
42 $(CC) $(CFLAGS) -c -o mpatch-oss-fuzz.o ../../mercurial/mpatch.c
42 $(CC) $(CFLAGS) -c -o mpatch-oss-fuzz.o ../../mercurial/mpatch.c
43
43
44 mpatch_fuzzer: mpatch.cc mpatch-oss-fuzz.o fuzzutil-oss-fuzz.o
44 mpatch_fuzzer: mpatch.cc mpatch-oss-fuzz.o fuzzutil-oss-fuzz.o
45 $(CXX) $(CXXFLAGS) -std=c++17 -I../../mercurial mpatch.cc \
45 $(CXX) $(CXXFLAGS) -std=c++17 -I../../mercurial mpatch.cc \
46 mpatch-oss-fuzz.o fuzzutil-oss-fuzz.o -lFuzzingEngine -o \
46 mpatch-oss-fuzz.o fuzzutil-oss-fuzz.o -lFuzzingEngine -o \
47 $$OUT/mpatch_fuzzer
47 $$OUT/mpatch_fuzzer
48
48
49 mpatch_corpus.zip:
49 mpatch_corpus.zip:
50 python mpatch_corpus.py $$OUT/mpatch_fuzzer_seed_corpus.zip
50 python mpatch_corpus.py $$OUT/mpatch_fuzzer_seed_corpus.zip
51
51
52 x%.o: ../../mercurial/thirdparty/xdiff/x%.c ../../mercurial/thirdparty/xdiff/*.h
52 x%.o: ../../mercurial/thirdparty/xdiff/x%.c ../../mercurial/thirdparty/xdiff/*.h
53 $(CC) -g -O1 -fsanitize=fuzzer-no-link,address -c \
53 $(CC) -g -O1 -fsanitize=fuzzer-no-link,address -c \
54 -o $@ \
54 -o $@ \
55 $<
55 $<
56
56
57 xdiff: CXXFLAGS += -std=c++17
57 xdiff: CXXFLAGS += -std=c++17
58 xdiff: xdiff.cc xdiffi.o xprepare.o xutils.o fuzzutil.o
58 xdiff: xdiff.cc xdiffi.o xprepare.o xutils.o fuzzutil.o
59 $(CXX) $(CXXFLAGS) -DHG_FUZZER_INCLUDE_MAIN=1 -g -O1 -fsanitize=fuzzer-no-link,address \
59 $(CXX) $(CXXFLAGS) -DHG_FUZZER_INCLUDE_MAIN=1 -g -O1 -fsanitize=fuzzer-no-link,address \
60 -I../../mercurial xdiff.cc \
60 -I../../mercurial xdiff.cc \
61 xdiffi.o xprepare.o xutils.o fuzzutil.o -o xdiff
61 xdiffi.o xprepare.o xutils.o fuzzutil.o -o xdiff
62
62
63 fuzz-x%.o: ../../mercurial/thirdparty/xdiff/x%.c ../../mercurial/thirdparty/xdiff/*.h
63 fuzz-x%.o: ../../mercurial/thirdparty/xdiff/x%.c ../../mercurial/thirdparty/xdiff/*.h
64 $(CC) $(CFLAGS) -c \
64 $(CC) $(CFLAGS) -c \
65 -o $@ \
65 -o $@ \
66 $<
66 $<
67
67
68 xdiff_fuzzer: xdiff.cc fuzz-xdiffi.o fuzz-xprepare.o fuzz-xutils.o fuzzutil-oss-fuzz.o
68 xdiff_fuzzer: xdiff.cc fuzz-xdiffi.o fuzz-xprepare.o fuzz-xutils.o fuzzutil-oss-fuzz.o
69 $(CXX) $(CXXFLAGS) -std=c++17 -I../../mercurial xdiff.cc \
69 $(CXX) $(CXXFLAGS) -std=c++17 -I../../mercurial xdiff.cc \
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