xref: /aosp_15_r20/system/core/libutils/binder/Vector_fuzz.cpp (revision 00c7fec1bb09f3284aad6a6f96d2f63dfc3650ad)
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <fuzzer/FuzzedDataProvider.h>
17 #include <log/log.h>
18 #include <utils/Vector.h>
19 
20 #include <functional>
21 
22 using android::Vector;
23 
24 static constexpr uint16_t MAX_VEC_SIZE = 100;
25 static constexpr bool kLog = false;
26 
27 struct NonTrivialDestructor {
NonTrivialDestructorNonTrivialDestructor28     NonTrivialDestructor() : mInit(1) {}
~NonTrivialDestructorNonTrivialDestructor29     ~NonTrivialDestructor() {
30         LOG_ALWAYS_FATAL_IF(mInit != 1, "mInit should be 1, but it's: %d", mInit);
31         mInit--;
32         LOG_ALWAYS_FATAL_IF(mInit != 0, "mInit should be 0, but it's: %d", mInit);
33     }
34 
35   private:
36     uint8_t mInit;
37 };
38 
39 template <typename T>
40 struct VectorFuzzerData {
41     Vector<T> vector;
42     const std::vector<std::function<void(FuzzedDataProvider&, Vector<T>&)>> funcs = {
__anond5f1cc6d0102VectorFuzzerData43             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
44                 (void)provider;
45                 // operator= Vector<TYPE>, still needs for SortedVector
46                 if (kLog) ALOGI("operator=");
47                 vector = testVector(provider);
48             },
__anond5f1cc6d0202VectorFuzzerData49             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
50                 (void)provider;
51                 if (kLog) ALOGI("clear");
52                 vector.clear();
53             },
__anond5f1cc6d0302VectorFuzzerData54             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
55                 (void)provider;
56                 if (kLog) ALOGI("size");
57                 vector.size();
58             },
__anond5f1cc6d0402VectorFuzzerData59             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
60                 (void)provider;
61                 if (kLog) ALOGI("isEmpty");
62                 vector.isEmpty();
63             },
__anond5f1cc6d0502VectorFuzzerData64             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
65                 (void)provider;
66                 if (kLog) ALOGI("capacity");
67                 vector.capacity();
68             },
__anond5f1cc6d0602VectorFuzzerData69             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
70                 size_t vectorSize = provider.ConsumeIntegralInRange<size_t>(0, MAX_VEC_SIZE);
71                 if (kLog) ALOGI("setCapacity");
72                 vector.setCapacity(vectorSize);
73             },
__anond5f1cc6d0702VectorFuzzerData74             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
75                 size_t vectorSize = provider.ConsumeIntegralInRange<size_t>(0, MAX_VEC_SIZE);
76                 if (kLog) ALOGI("resize");
77                 vector.resize(vectorSize);
78             },
__anond5f1cc6d0802VectorFuzzerData79             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
80                 (void)provider;
81                 if (kLog) ALOGI("array");
82                 vector.array();
83             },
__anond5f1cc6d0902VectorFuzzerData84             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
85                 (void)provider;
86                 if (kLog) ALOGI("editArray");
87                 vector.editArray();
88             },
__anond5f1cc6d0a02VectorFuzzerData89             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
90                 if (vector.size() == 0) return;
91                 size_t idx = provider.ConsumeIntegralInRange<size_t>(0, vector.size() - 1);
92                 if (kLog) ALOGI("operator[]");
93                 vector[idx];  // returns a const value for Vector
94             },
__anond5f1cc6d0b02VectorFuzzerData95             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
96                 if (vector.size() == 0) return;
97                 size_t idx = provider.ConsumeIntegralInRange<size_t>(0, vector.size() - 1);
98                 if (kLog) ALOGI("itemAt");
99                 vector.itemAt(idx);
100             },
__anond5f1cc6d0c02VectorFuzzerData101             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
102                 (void)provider;
103                 if (vector.size() == 0) return;
104                 if (kLog) ALOGI("top");
105                 vector.top();
106             },
__anond5f1cc6d0d02VectorFuzzerData107             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
108                 if (vector.size() == 0) return;
109                 size_t idx = provider.ConsumeIntegralInRange<size_t>(0, vector.size() - 1);
110                 if (kLog) ALOGI("editItemAt");
111                 vector.editItemAt(idx);
112             },
__anond5f1cc6d0e02VectorFuzzerData113             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
114                 (void)provider;
115                 if (vector.size() == 0) return;
116                 if (kLog) ALOGI("editTop");
117                 vector.editTop() = T{};
118             },
__anond5f1cc6d0f02VectorFuzzerData119             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
120                 uint8_t idx = provider.ConsumeIntegralInRange<uint8_t>(0, vector.size());
121                 Vector vec2 = testVector(provider);
122                 if (vec2.size() == 0) return;  // TODO: maybe we should support this?
123                 if (kLog) ALOGI("insertVectorAt %d of size %zu", idx, vec2.size());
124                 vector.insertVectorAt(vec2, idx);
125             },
__anond5f1cc6d1002VectorFuzzerData126             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
127                 if (kLog) ALOGI("appendVector");
128                 vector.appendVector(testVector(provider));
129             },
130             // TODO: insertArrayAt
131             // TODO: appendArray
__anond5f1cc6d1102VectorFuzzerData132             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
133                 uint8_t idx = provider.ConsumeIntegralInRange<uint8_t>(0, vector.size());
134                 uint8_t numItems = provider.ConsumeIntegralInRange<uint8_t>(1, 100);
135                 if (kLog) ALOGI("insertAt");
136                 vector.insertAt(idx, numItems);
137             },
__anond5f1cc6d1202VectorFuzzerData138             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
139                 uint8_t idx = provider.ConsumeIntegralInRange<uint8_t>(0, vector.size());
140                 uint8_t numItems = provider.ConsumeIntegralInRange<uint8_t>(1, 100);
141                 if (kLog) ALOGI("insertAt");
142                 vector.insertAt(T{}, idx, numItems);
143             },
__anond5f1cc6d1302VectorFuzzerData144             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
145                 (void)provider;
146                 if (vector.size() == 0) return;
147                 if (kLog) ALOGI("pop");
148                 vector.pop();
149             },
__anond5f1cc6d1402VectorFuzzerData150             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
151                 (void)provider;
152                 if (kLog) ALOGI("push");
153                 vector.push();
154             },
__anond5f1cc6d1502VectorFuzzerData155             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
156                 (void)provider;
157                 if (kLog) ALOGI("add");
158                 vector.add();
159             },
__anond5f1cc6d1602VectorFuzzerData160             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
161                 (void)provider;
162                 if (kLog) ALOGI("add");
163                 vector.add(T{});
164             },
__anond5f1cc6d1702VectorFuzzerData165             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
166                 uint8_t idx = provider.ConsumeIntegralInRange<uint8_t>(0, vector.size() - 1);
167                 if (kLog) ALOGI("replaceAt");
168                 vector.replaceAt(idx);
169             },
__anond5f1cc6d1802VectorFuzzerData170             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
171                 uint8_t idx = provider.ConsumeIntegralInRange<uint8_t>(0, vector.size() - 1);
172                 if (kLog) ALOGI("replaceAt");
173                 vector.replaceAt(T{}, idx);
174             },
__anond5f1cc6d1902VectorFuzzerData175             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
176                 if (vector.size() == 0) return;
177                 uint8_t idx = provider.ConsumeIntegralInRange<uint8_t>(0, vector.size() - 1);
178                 if (kLog) ALOGI("remoteItemsAt");
179                 vector.removeItemsAt(idx);  // TODO: different count
180             },
181             // removeAt is alias for removeItemsAt
182             // TODO: sort
__anond5f1cc6d1a02VectorFuzzerData183             [&](FuzzedDataProvider& provider, Vector<T>& vector) {
184                 (void)provider;
185                 if (kLog) ALOGI("getItemSize");
186                 vector.getItemSize();
187             },
188             // TODO: iterators
189     };
190 
testVectorVectorFuzzerData191     Vector<T> testVector(FuzzedDataProvider& provider) {
192         Vector<T> vec;
193         size_t vectorSize = provider.ConsumeIntegralInRange<size_t>(0, MAX_VEC_SIZE);
194         return vec;
195     }
196 
fuzzVectorFuzzerData197     void fuzz(FuzzedDataProvider&& provider) {
198         while (provider.remaining_bytes()) {
199             size_t funcIdx = provider.ConsumeIntegralInRange<size_t>(0, funcs.size() - 1);
200             funcs[funcIdx](provider, vector);
201         }
202     }
203 };
204 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)205 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
206     FuzzedDataProvider provider(data, size);
207 
208     provider.PickValueInArray<std::function<void()>>({
209             [&]() { VectorFuzzerData<uint8_t>().fuzz(std::move(provider)); },
210             [&]() { VectorFuzzerData<int32_t>().fuzz(std::move(provider)); },
211             [&]() { VectorFuzzerData<NonTrivialDestructor>().fuzz(std::move(provider)); },
212     })();
213 
214     return 0;
215 }
216