Mercurial > hg
annotate contrib/fuzz/mpatch.cc @ 45043:be58fb1eaa73
procutil: make stdout line-buffered on Windows if connected to TTY
Windows doesn’t support line buffering. Previously, we worked around that by
setting the stream unbuffered. Instead, we can use our own line buffering we
already use on Python 3.
author | Manuel Jacob <me@manueljacob.de> |
---|---|
date | Sat, 04 Jul 2020 11:41:39 +0200 |
parents | d37658efbec2 |
children |
rev | line source |
---|---|
38246
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1 /* |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
2 * mpatch.cc - fuzzer harness for mpatch.c |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
3 * |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
4 * Copyright 2018, Google Inc. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
5 * |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
6 * This software may be used and distributed according to the terms of |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
7 * the GNU General Public License, incorporated herein by reference. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
8 */ |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
9 #include <iostream> |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
10 #include <memory> |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
11 #include <stdint.h> |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
12 #include <stdlib.h> |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
13 #include <vector> |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
14 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
15 #include "fuzzutil.h" |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
16 |
43809
51a99e09c54b
fuzz: always define LLVMFuzzerInitialize() even if we don't need it
Augie Fackler <augie@google.com>
parents:
38246
diff
changeset
|
17 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) |
51a99e09c54b
fuzz: always define LLVMFuzzerInitialize() even if we don't need it
Augie Fackler <augie@google.com>
parents:
38246
diff
changeset
|
18 { |
51a99e09c54b
fuzz: always define LLVMFuzzerInitialize() even if we don't need it
Augie Fackler <augie@google.com>
parents:
38246
diff
changeset
|
19 return 0; |
51a99e09c54b
fuzz: always define LLVMFuzzerInitialize() even if we don't need it
Augie Fackler <augie@google.com>
parents:
38246
diff
changeset
|
20 } |
51a99e09c54b
fuzz: always define LLVMFuzzerInitialize() even if we don't need it
Augie Fackler <augie@google.com>
parents:
38246
diff
changeset
|
21 |
38246
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
22 // To avoid having too many OOMs from the fuzzer infrastructure, we'll |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
23 // skip patch application if the resulting fulltext would be bigger |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
24 // than 10MiB. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
25 #define MAX_OUTPUT_SIZE 10485760 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
26 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
27 extern "C" { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
28 #include "bitmanipulation.h" |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
29 #include "mpatch.h" |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
30 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
31 struct mpatchbin { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
32 std::unique_ptr<char[]> data; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
33 size_t len; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
34 }; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
35 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
36 static mpatch_flist *getitem(void *vbins, ssize_t pos) |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
37 { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
38 std::vector<mpatchbin> *bins = (std::vector<mpatchbin> *)vbins; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
39 const mpatchbin &bin = bins->at(pos + 1); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
40 struct mpatch_flist *res; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
41 LOG(2) << "mpatch_decode " << bin.len << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
42 if (mpatch_decode(bin.data.get(), bin.len, &res) < 0) |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
43 return NULL; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
44 return res; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
45 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
46 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
47 // input format: |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
48 // u8 number of inputs |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
49 // one u16 for each input, its length |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
50 // the inputs |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
51 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
52 { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
53 if (!Size) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
54 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
55 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
56 // First byte of data is how many texts we expect, first text |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
57 // being the base the rest being the deltas. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
58 ssize_t numtexts = Data[0]; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
59 if (numtexts < 2) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
60 // No point if we don't have at least a base text and a delta... |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
61 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
62 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
63 // Each text will be described by a byte for how long it |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
64 // should be, so give up if we don't have enough. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
65 if ((Size - 1) < (numtexts * 2)) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
66 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
67 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
68 size_t consumed = 1 + (numtexts * 2); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
69 LOG(2) << "input contains " << Size << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
70 LOG(2) << numtexts << " texts, consuming " << consumed << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
71 std::vector<mpatchbin> bins; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
72 bins.reserve(numtexts); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
73 for (int i = 0; i < numtexts; ++i) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
74 mpatchbin bin; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
75 size_t nthsize = getbeuint16((char *)Data + 1 + (2 * i)); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
76 LOG(2) << "text " << i << " is " << nthsize << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
77 char *start = (char *)Data + consumed; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
78 consumed += nthsize; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
79 if (consumed > Size) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
80 LOG(2) << "ran out of data, consumed " << consumed |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
81 << " of " << Size << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
82 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
83 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
84 bin.len = nthsize; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
85 bin.data.reset(new char[nthsize]); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
86 memcpy(bin.data.get(), start, nthsize); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
87 bins.push_back(std::move(bin)); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
88 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
89 LOG(2) << "mpatch_flist" << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
90 struct mpatch_flist *patch = |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
91 mpatch_fold(&bins, getitem, 0, numtexts - 1); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
92 if (!patch) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
93 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
94 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
95 LOG(2) << "mpatch_calcsize" << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
96 ssize_t outlen = mpatch_calcsize(bins[0].len, patch); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
97 LOG(2) << "outlen " << outlen << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
98 if (outlen < 0 || outlen > MAX_OUTPUT_SIZE) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
99 goto cleanup; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
100 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
101 { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
102 char *dest = (char *)malloc(outlen); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
103 LOG(2) << "expecting " << outlen << " total bytes at " |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
104 << (void *)dest << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
105 mpatch_apply(dest, bins[0].data.get(), bins[0].len, patch); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
106 free(dest); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
107 LOG(1) << "applied a complete patch" << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
108 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
109 cleanup: |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
110 mpatch_lfree(patch); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
111 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
112 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
113 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
114 } // extern "C" |