| Dylan Katz | 7168f27 | 2020-07-02 11:51:44 -0700 | [diff] [blame] | 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 |  | 
 | 33 | void doNothing() {} | 
 | 34 | void* doNothingPointer = reinterpret_cast<void*>(doNothing); | 
 | 35 |  | 
 | 36 | static int noopCallback(int, int, void*) { | 
 | 37 |     return 0; | 
 | 38 | } | 
 | 39 |  | 
 | 40 | std::vector<std::function<void(FuzzedDataProvider*, sp<Looper>, Pipe)>> operations = { | 
 | 41 |         [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe) -> void { | 
 | 42 |             looper->pollOnce(dataProvider->ConsumeIntegralInRange<int>(0, MAX_POLL_DELAY)); | 
 | 43 |         }, | 
 | 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 | 
 | 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 | 
 | 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 | 
 | 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 | 
 | 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 |  | 
 | 68 |         [](FuzzedDataProvider*, sp<Looper> looper, Pipe) -> void { looper->wake(); }, | 
 | 69 |         [](FuzzedDataProvider*, sp<Looper>, Pipe pipeObj) -> void { pipeObj.writeSignal(); }}; | 
 | 70 |  | 
 | 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 | } |