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 <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <vndk/hardware_buffer.h>
20
21 #include <fuzzer/FuzzedDataProvider.h>
22 #include "EventGenerator.h"
23 #include "InputFrame.h"
24 #include "MockEngine.h"
25 #include "OutputConfig.pb.h"
26 #include "PixelFormatUtils.h"
27 #include "PixelStreamManager.h"
28 #include "RunnerComponent.h"
29 #include "StreamEngineInterface.h"
30 #include "StreamManager.h"
31 #include "src/libfuzzer/libfuzzer_macro.h"
32 #include "types/Status.h"
33
34 using ::android::automotive::computepipe::runner::generator::DefaultEvent;
35 using ::testing::Return;
36
37 namespace android {
38 namespace automotive {
39 namespace computepipe {
40 namespace runner {
41 namespace stream_manager {
42 namespace {
43
44 enum State {
45 RESET = 0,
46 RUN,
47 STOP_WITH_FLUSH,
48 STOP_IMMEDIATE,
49 QUEUE_PACKET,
50 FREE_PACKET,
51 CLONE_PACKET
52 };
53
CreateStreamManagerAndEngine(int maxInFlightPackets)54 std::pair<std::shared_ptr<MockEngine>, std::unique_ptr<StreamManager>> CreateStreamManagerAndEngine(
55 int maxInFlightPackets) {
56 StreamManagerFactory factory;
57 proto::OutputConfig outputConfig;
58 outputConfig.set_type(proto::PacketType::PIXEL_DATA);
59 outputConfig.set_stream_name("pixel_stream");
60 std::shared_ptr<MockEngine> mockEngine = std::make_shared<MockEngine>();
61 std::unique_ptr<StreamManager> manager =
62 factory.getStreamManager(outputConfig, mockEngine, maxInFlightPackets);
63
64 return std::pair(mockEngine, std::move(manager));
65 }
66
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)67 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
68 if (size < sizeof(uint32_t)) {
69 return 0;
70 }
71
72 FuzzedDataProvider fdp(data, size);
73 int maxInFlightPackets = fdp.ConsumeIntegral<uint32_t>();
74 auto [mockEngine, manager] = CreateStreamManagerAndEngine(maxInFlightPackets);
75 std::vector<uint8_t> pixelData(16 * 16 * 3, 100);
76 InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &pixelData[0]);
77 std::shared_ptr<MemHandle> memHandle;
78 EXPECT_CALL((*mockEngine), dispatchPacket)
79 .Times(testing::AnyNumber())
80 .WillRepeatedly(
81 testing::DoAll(testing::SaveArg<0>(&memHandle), (Return(Status::SUCCESS))));
82
83 while (fdp.remaining_bytes() > 0) {
84 uint8_t state = fdp.ConsumeIntegralInRange<uint8_t>(RESET, CLONE_PACKET);
85 DefaultEvent e = DefaultEvent::generateEntryEvent(static_cast<DefaultEvent::Phase>(state));
86
87 switch (state) {
88 case RESET:
89 case RUN: {
90 manager->handleExecutionPhase(e);
91 break;
92 }
93 case STOP_WITH_FLUSH: {
94 EXPECT_CALL((*mockEngine), notifyEndOfStream).Times(testing::AtMost(1));
95 manager->handleStopWithFlushPhase(e);
96 sleep(1);
97 break;
98 }
99 case STOP_IMMEDIATE: {
100 EXPECT_CALL((*mockEngine), notifyEndOfStream).Times(testing::AtMost(1));
101 manager->handleStopImmediatePhase(e);
102 sleep(1);
103 break;
104 }
105 case QUEUE_PACKET: {
106 manager->queuePacket(frame, rand());
107 sleep(1);
108 break;
109 }
110 case FREE_PACKET: {
111 if (memHandle != nullptr) {
112 manager->freePacket(memHandle->getBufferId());
113 }
114 break;
115 }
116 case CLONE_PACKET: {
117 manager->clonePacket(memHandle);
118 break;
119 }
120 }
121 }
122
123 return 0;
124 }
125
126 } // namespace
127 } // namespace stream_manager
128 } // namespace runner
129 } // namespace computepipe
130 } // namespace automotive
131 } // namespace android
132