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 <android-base/logging.h>
18 #include <fuzzer/FuzzedDataProvider.h>
19 #include <gmock/gmock.h>
20 #include "ClientConfig.pb.h"
21 #include "Common.h"
22 #include "GrpcGraph.h"
23 #include "GrpcGraphServerImpl.h"
24
25 using ::android::automotive::computepipe::runner::ClientConfig;
26
27 namespace android {
28 namespace automotive {
29 namespace computepipe {
30 namespace graph {
31
32 namespace {
33
34 enum GRPC_GRAPH_FUZZ_FUNCS {
35 GRAPH_RUNNER_BASE_ENUM,
36 DISPATCH_PIXEL_DATA, /* verify dispatchPixelData */
37 DISPATCH_SERIALIZED_DATA, /* dispatchSerializedData */
38 DISPATCH_GRAPH_TERMINATION_MSG, /* dispatchGraphTerminationMessage */
39 RUNNER_COMP_BASE_ENUM
40 };
41
DoInitialization()42 bool DoInitialization() {
43 // Initialization goes here
44 std::shared_ptr<GrpcGraphServerImpl> server;
45 server = std::make_shared<GrpcGraphServerImpl>(runner::test::kAddress);
46 std::thread t = std::thread([server]() { server->startServer(); });
47 t.detach();
48 std::this_thread::sleep_for(std::chrono::seconds(1));
49 return true;
50 }
51
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)52 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
53 static bool initialized = DoInitialization();
54 std::shared_ptr<PrebuiltEngineInterfaceImpl> engine;
55 std::unique_ptr<GrpcGraph> graph = std::make_unique<GrpcGraph>();
56 engine = std::make_shared<PrebuiltEngineInterfaceImpl>();
57 Status status = graph->initialize(runner::test::kAddress, engine);
58 if (status != Status::SUCCESS) {
59 LOG(ERROR) << "Initialization of GrpcGraph failed, aborting...";
60 exit(1);
61 }
62
63 // Fuzz goes here
64 FuzzedDataProvider fdp(data, size);
65 while (fdp.remaining_bytes() > runner::test::kMaxFuzzerConsumedBytes) {
66 switch (fdp.ConsumeIntegralInRange<uint32_t>(0, API_SUM - 1)) {
67 case GET_GRAPH_TYPE: {
68 graph->GetGraphType();
69 break;
70 }
71 case GET_GRAPH_STATE: {
72 graph->GetGraphState();
73 break;
74 }
75 case GET_STATUS: {
76 graph->GetStatus();
77 break;
78 }
79 case GET_ERROR_MESSAGE: {
80 graph->GetErrorMessage();
81 break;
82 }
83 case GET_SUPPORTED_GRAPH_CONFIGS: {
84 graph->GetSupportedGraphConfigs();
85 break;
86 }
87 case SET_INPUT_STREAM_DATA: {
88 graph->SetInputStreamData(/*streamIndex =*/2, /* timestamp =*/0, /* data =*/"");
89 break;
90 }
91 case SET_INPUT_STREAM_PIXEL_DATA: {
92 runner::InputFrame inputFrame(0, 0, PixelFormat::RGB, 0, nullptr);
93 graph->SetInputStreamPixelData(/*streamIndex =*/1, /*timestamp =*/0,
94 /*inputFrame =*/inputFrame);
95 break;
96 }
97 case START_GRAPH_PROFILING: {
98 graph->StartGraphProfiling();
99 break;
100 }
101 case STOP_GRAPH_PROFILING: {
102 graph->StopGraphProfiling();
103 break;
104 }
105 case HANDLE_CONFIG_PHASE: {
106 std::map<int, int> maxOutputPacketsPerStream;
107 ClientConfig e(0, 0, 0, maxOutputPacketsPerStream, proto::ProfilingType::DISABLED);
108 e.setPhaseState(runner::PhaseState::ENTRY);
109 graph->handleConfigPhase(e);
110 break;
111 }
112 case HANDLE_EXECUTION_PHASE: {
113 std::map<int, int> maxOutputPacketsPerStream;
114 ClientConfig e(0, 0, 0, maxOutputPacketsPerStream, proto::ProfilingType::DISABLED);
115 e.setPhaseState(runner::PhaseState::ENTRY);
116 graph->handleExecutionPhase(e);
117 break;
118 }
119 case HANDLE_STOP_IMMEDIATE_PHASE: {
120 std::map<int, int> maxOutputPacketsPerStream;
121 ClientConfig e(0, 0, 0, maxOutputPacketsPerStream, proto::ProfilingType::DISABLED);
122 e.setPhaseState(runner::PhaseState::ENTRY);
123 graph->handleStopImmediatePhase(e);
124 break;
125 }
126 case HANDLE_STOP_WITH_FLUSH_PHASE: {
127 std::map<int, int> maxOutputPacketsPerStream;
128 ClientConfig e(0, 0, 0, maxOutputPacketsPerStream, proto::ProfilingType::DISABLED);
129 e.setPhaseState(runner::PhaseState::ENTRY);
130 graph->handleStopWithFlushPhase(e);
131 break;
132 }
133 case HANDLE_RESET_PHASE: {
134 std::map<int, int> maxOutputPacketsPerStream;
135 ClientConfig e(0, 0, 0, maxOutputPacketsPerStream, proto::ProfilingType::DISABLED);
136 e.setPhaseState(runner::PhaseState::ENTRY);
137 graph->handleResetPhase(e);
138 break;
139 }
140 case DISPATCH_PIXEL_DATA: {
141 runner::InputFrame inputFrame(0, 0, PixelFormat::RGB, 0, nullptr);
142 graph->dispatchPixelData(/*streamIndex =*/2, /*timestamp =*/0,
143 /*inputFrame =*/inputFrame);
144 break;
145 }
146 case DISPATCH_SERIALIZED_DATA: {
147 graph->dispatchSerializedData(/*streamIndex =*/1, /* timestamp =*/0, /* data =*/"");
148 break;
149 }
150 case DISPATCH_GRAPH_TERMINATION_MSG: {
151 uint8_t status = fdp.ConsumeIntegralInRange<uint8_t>(0, Status::STATUS_MAX - 1);
152 graph->dispatchGraphTerminationMessage(static_cast<Status>(status), "");
153 break;
154 }
155 default:
156 LOG(ERROR) << "Unexpected option aborting...";
157 break;
158 }
159 }
160 return 0;
161 }
162
163 } // namespace
164 } // namespace graph
165 } // namespace computepipe
166 } // namespace automotive
167 } // namespace android
168