annotate contrib/fuzz/mpatch.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 46dcb9f14900
children 51a99e09c54b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
17 // 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
18 // 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
19 // than 10MiB.
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
20 #define MAX_OUTPUT_SIZE 10485760
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
21
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
22 extern "C" {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
23 #include "bitmanipulation.h"
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
24 #include "mpatch.h"
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
25
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
26 struct mpatchbin {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
27 std::unique_ptr<char[]> data;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
28 size_t len;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
29 };
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 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
32 {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
33 std::vector<mpatchbin> *bins = (std::vector<mpatchbin> *)vbins;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
34 const mpatchbin &bin = bins->at(pos + 1);
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
35 struct mpatch_flist *res;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
36 LOG(2) << "mpatch_decode " << bin.len << std::endl;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
37 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
38 return NULL;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
39 return res;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
40 }
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
41
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
42 // input format:
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
43 // u8 number of inputs
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
44 // one u16 for each input, its length
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
45 // the inputs
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
46 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
47 {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
48 if (!Size) {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
49 return 0;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
50 }
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
51 // 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
52 // being the base the rest being the deltas.
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
53 ssize_t numtexts = Data[0];
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
54 if (numtexts < 2) {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
55 // 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
56 return 0;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
57 }
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
58 // 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
59 // 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
60 if ((Size - 1) < (numtexts * 2)) {
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 size_t consumed = 1 + (numtexts * 2);
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
64 LOG(2) << "input contains " << Size << std::endl;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
65 LOG(2) << numtexts << " texts, consuming " << consumed << std::endl;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
66 std::vector<mpatchbin> bins;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
67 bins.reserve(numtexts);
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
68 for (int i = 0; i < numtexts; ++i) {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
69 mpatchbin bin;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
70 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
71 LOG(2) << "text " << i << " is " << nthsize << std::endl;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
72 char *start = (char *)Data + consumed;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
73 consumed += nthsize;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
74 if (consumed > Size) {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
75 LOG(2) << "ran out of data, consumed " << consumed
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
76 << " of " << Size << std::endl;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
77 return 0;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
78 }
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
79 bin.len = nthsize;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
80 bin.data.reset(new char[nthsize]);
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
81 memcpy(bin.data.get(), start, nthsize);
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
82 bins.push_back(std::move(bin));
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 LOG(2) << "mpatch_flist" << std::endl;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
85 struct mpatch_flist *patch =
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
86 mpatch_fold(&bins, getitem, 0, numtexts - 1);
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
87 if (!patch) {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
88 return 0;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
89 }
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
90 LOG(2) << "mpatch_calcsize" << std::endl;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
91 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
92 LOG(2) << "outlen " << outlen << std::endl;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
93 if (outlen < 0 || outlen > MAX_OUTPUT_SIZE) {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
94 goto cleanup;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
95 }
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
96 {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
97 char *dest = (char *)malloc(outlen);
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
98 LOG(2) << "expecting " << outlen << " total bytes at "
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
99 << (void *)dest << std::endl;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
100 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
101 free(dest);
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
102 LOG(1) << "applied a complete patch" << std::endl;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
103 }
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
104 cleanup:
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
105 mpatch_lfree(patch);
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
106 return 0;
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
107 }
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 #ifdef HG_FUZZER_INCLUDE_MAIN
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
110 int main(int argc, char **argv)
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
111 {
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
112 // One text, one patch.
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
113 const char data[] = "\x02\x00\0x1\x00\x0d"
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
114 // base text
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
115 "a"
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
116 // binary delta that will append a single b
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
117 "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01b";
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
118 return LLVMFuzzerTestOneInput((const uint8_t *)data, 19);
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
119 }
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
120 #endif
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
121
46dcb9f14900 fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff changeset
122 } // extern "C"