/* * Copyright 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "EventGenerator.h" #include "InputFrame.h" #include "MockEngine.h" #include "OutputConfig.pb.h" #include "PixelFormatUtils.h" #include "PixelStreamManager.h" #include "RunnerComponent.h" #include "StreamEngineInterface.h" #include "StreamManager.h" #include "src/libfuzzer/libfuzzer_macro.h" #include "types/Status.h" using ::android::automotive::computepipe::runner::generator::DefaultEvent; using ::testing::Return; namespace android { namespace automotive { namespace computepipe { namespace runner { namespace stream_manager { namespace { enum State { RESET = 0, RUN, STOP_WITH_FLUSH, STOP_IMMEDIATE, QUEUE_PACKET, FREE_PACKET, CLONE_PACKET }; std::pair, std::unique_ptr> CreateStreamManagerAndEngine( int maxInFlightPackets) { StreamManagerFactory factory; proto::OutputConfig outputConfig; outputConfig.set_type(proto::PacketType::PIXEL_DATA); outputConfig.set_stream_name("pixel_stream"); std::shared_ptr mockEngine = std::make_shared(); std::unique_ptr manager = factory.getStreamManager(outputConfig, mockEngine, maxInFlightPackets); return std::pair(mockEngine, std::move(manager)); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (size < sizeof(uint32_t)) { return 0; } FuzzedDataProvider fdp(data, size); int maxInFlightPackets = fdp.ConsumeIntegral(); auto [mockEngine, manager] = CreateStreamManagerAndEngine(maxInFlightPackets); std::vector pixelData(16 * 16 * 3, 100); InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &pixelData[0]); std::shared_ptr memHandle; EXPECT_CALL((*mockEngine), dispatchPacket) .Times(testing::AnyNumber()) .WillRepeatedly( testing::DoAll(testing::SaveArg<0>(&memHandle), (Return(Status::SUCCESS)))); while (fdp.remaining_bytes() > 0) { uint8_t state = fdp.ConsumeIntegralInRange(RESET, CLONE_PACKET); DefaultEvent e = DefaultEvent::generateEntryEvent(static_cast(state)); switch (state) { case RESET: case RUN: { manager->handleExecutionPhase(e); break; } case STOP_WITH_FLUSH: { EXPECT_CALL((*mockEngine), notifyEndOfStream).Times(testing::AtMost(1)); manager->handleStopWithFlushPhase(e); sleep(1); break; } case STOP_IMMEDIATE: { EXPECT_CALL((*mockEngine), notifyEndOfStream).Times(testing::AtMost(1)); manager->handleStopImmediatePhase(e); sleep(1); break; } case QUEUE_PACKET: { manager->queuePacket(frame, rand()); sleep(1); break; } case FREE_PACKET: { if (memHandle != nullptr) { manager->freePacket(memHandle->getBufferId()); } break; } case CLONE_PACKET: { manager->clonePacket(memHandle); break; } } } return 0; } } // namespace } // namespace stream_manager } // namespace runner } // namespace computepipe } // namespace automotive } // namespace android