1 // Copyright 2021 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "dice/cbor_writer.h"
16 #include "fuzzer/FuzzedDataProvider.h"
17
18 namespace {
19
20 enum CborWriterFunction {
21 WriteInt,
22 WriteUint,
23 WriteBstr,
24 AllocBstr,
25 WriteTstr,
26 AllocTstr,
27 WriteArray,
28 WriteMap,
29 WriteFalse,
30 WriteTrue,
31 WriteNull,
32 kMaxValue = WriteNull,
33 };
34
35 // Use data sizes that exceed the 16-bit range without being excessive.
36 constexpr size_t kMaxDataSize = 0xffff + 0x5000;
37 constexpr size_t kMaxBufferSize = kMaxDataSize * 3;
38 constexpr size_t kIterations = CborWriterFunction::kMaxValue * 2;
39
40 } // namespace
41
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)42 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
43 FuzzedDataProvider fdp(data, size);
44
45 auto buffer_size = fdp.ConsumeIntegralInRange<size_t>(0, kMaxBufferSize);
46 std::vector<uint8_t> buffer(buffer_size);
47 CborOut out;
48 CborOutInit(buffer.data(), buffer.size(), &out);
49
50 for (size_t i = 0; i < kIterations; i++) {
51 switch (fdp.ConsumeEnum<CborWriterFunction>()) {
52 case WriteInt:
53 CborWriteInt(fdp.ConsumeIntegral<int64_t>(), &out);
54 break;
55 case WriteUint:
56 CborWriteUint(fdp.ConsumeIntegral<uint64_t>(), &out);
57 break;
58 case WriteBstr: {
59 auto bstr_data_size =
60 fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
61 std::vector<uint8_t> bstr_data(bstr_data_size);
62 CborWriteBstr(bstr_data.size(), bstr_data.data(), &out);
63 break;
64 }
65 case AllocBstr: {
66 auto bstr_data_size =
67 fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
68 uint8_t* ptr = CborAllocBstr(bstr_data_size, &out);
69 if (ptr) {
70 memset(ptr, 0x5a, bstr_data_size);
71 }
72 break;
73 }
74 case WriteTstr: {
75 auto tstr_data_size =
76 fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
77 std::string str(tstr_data_size, 'a');
78 CborWriteTstr(str.c_str(), &out);
79 break;
80 }
81 case AllocTstr: {
82 auto tstr_data_size =
83 fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
84 char* str = CborAllocTstr(tstr_data_size, &out);
85 if (str) {
86 memset(str, 'q', tstr_data_size);
87 }
88 break;
89 }
90 case WriteArray: {
91 auto num_elements = fdp.ConsumeIntegral<size_t>();
92 CborWriteArray(num_elements, &out);
93 break;
94 }
95 case WriteMap: {
96 auto num_pairs = fdp.ConsumeIntegral<size_t>();
97 CborWriteMap(num_pairs, &out);
98 break;
99 }
100 case WriteFalse:
101 CborWriteNull(&out);
102 break;
103 case WriteTrue:
104 CborWriteNull(&out);
105 break;
106 case WriteNull:
107 CborWriteNull(&out);
108 break;
109 }
110 }
111
112 return 0;
113 }
114