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 
17 #include <sys/select.h>
18 
19 #include <iostream>
20 
21 #include <utils/Looper.h>
22 
23 #include "Looper_test_pipe.h"
24 #include "fuzzer/FuzzedDataProvider.h"
25 
26 using android::Looper;
27 using android::sp;
28 
29 // We don't want this to bog down fuzzing
30 static constexpr int MAX_POLL_DELAY = 50;
31 static constexpr int MAX_OPERATIONS = 500;
32 
doNothing()33 void doNothing() {}
34 void* doNothingPointer = reinterpret_cast<void*>(doNothing);
35 
noopCallback(int,int,void *)36 static int noopCallback(int, int, void*) {
37     return 0;
38 }
39 
40 std::vector<std::function<void(FuzzedDataProvider*, sp<Looper>, Pipe)>> operations = {
__anonda8a39c00102() 41         [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe) -> void {
42             looper->pollOnce(dataProvider->ConsumeIntegralInRange<int>(0, MAX_POLL_DELAY));
43         },
__anonda8a39c00202() 44         [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe) -> void {
45             looper->pollAll(dataProvider->ConsumeIntegralInRange<int>(0, MAX_POLL_DELAY));
46         },
47         // events and callback are nullptr
__anonda8a39c00302() 48         [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe pipeObj) -> void {
49             looper->addFd(pipeObj.receiveFd, dataProvider->ConsumeIntegral<int>(),
50                           dataProvider->ConsumeIntegral<int>(), nullptr, nullptr);
51         },
52         // Events is nullptr
__anonda8a39c00402() 53         [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe pipeObj) -> void {
54             looper->addFd(pipeObj.receiveFd, dataProvider->ConsumeIntegral<int>(),
55                           dataProvider->ConsumeIntegral<int>(), noopCallback, nullptr);
56         },
57         // callback is nullptr
__anonda8a39c00502() 58         [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe pipeObj) -> void {
59             looper->addFd(pipeObj.receiveFd, dataProvider->ConsumeIntegral<int>(),
60                           dataProvider->ConsumeIntegral<int>(), nullptr, doNothingPointer);
61         },
62         // callback and events both set
__anonda8a39c00602() 63         [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe pipeObj) -> void {
64             looper->addFd(pipeObj.receiveFd, dataProvider->ConsumeIntegral<int>(),
65                           dataProvider->ConsumeIntegral<int>(), noopCallback, doNothingPointer);
66         },
67 
__anonda8a39c00702() 68         [](FuzzedDataProvider*, sp<Looper> looper, Pipe) -> void { looper->wake(); },
__anonda8a39c00802() 69         [](FuzzedDataProvider*, sp<Looper>, Pipe pipeObj) -> void { pipeObj.writeSignal(); }};
70 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)71 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
72     Pipe pipeObj;
73     FuzzedDataProvider dataProvider(data, size);
74     sp<Looper> looper = new Looper(dataProvider.ConsumeBool());
75 
76     size_t opsRun = 0;
77     while (dataProvider.remaining_bytes() > 0 && opsRun++ < MAX_OPERATIONS) {
78         uint8_t op = dataProvider.ConsumeIntegralInRange<uint8_t>(0, operations.size() - 1);
79         operations[op](&dataProvider, looper, pipeObj);
80     }
81     // Clear our pointer
82     looper.clear();
83     return 0;
84 }
85