• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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