1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <iostream>
17 #include <cstddef>
18 #include <cstdint>
19 #include "audio_info.h"
20 #include "audio_policy_server.h"
21 #include "audio_policy_service.h"
22 #include "audio_bluetooth_manager.h"
23 #include "common/hdi_adapter_info.h"
24 #include "manager/hdi_adapter_manager.h"
25 #include "sink/i_audio_render_sink.h"
26 #include "audio_device_info.h"
27
28 namespace OHOS {
29 namespace AudioStandard {
30 using namespace std;
31 const char *SINK_ADAPTER_NAME = "primary";
32 const uint64_t COMMON_UINT64_NUM = 2;
33 static const uint8_t *RAW_DATA = nullptr;
34 static size_t g_dataSize = 0;
35 static size_t g_pos;
36 static uint32_t g_renderId = HDI_INVALID_ID;
37 const size_t THRESHOLD = 10;
38
GetRenderId()39 void GetRenderId()
40 {
41 g_renderId = HdiAdapterManager::GetInstance().GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_MMAP,
42 true);
43 }
44
ReleaseRenderId()45 void ReleaseRenderId()
46 {
47 HdiAdapterManager::GetInstance().ReleaseId(g_renderId);
48 }
49
GetAdaptorBlueToothSink()50 std::shared_ptr<IAudioRenderSink> GetAdaptorBlueToothSink()
51 {
52 return HdiAdapterManager::GetInstance().GetRenderSink(g_renderId, true);
53 }
54
55 /*
56 * describe: get data from outside untrusted data(RAW_DATA) which size is according to sizeof(T)
57 * tips: only support basic type
58 */
59 template<class T>
GetData()60 T GetData()
61 {
62 T object {};
63 size_t objectSize = sizeof(object);
64 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
65 return object;
66 }
67 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
68 if (ret != EOK) {
69 return {};
70 }
71 g_pos += objectSize;
72 return object;
73 }
74
75 template<class T>
GetArrLength(T & arr)76 uint32_t GetArrLength(T& arr)
77 {
78 if (arr == nullptr) {
79 AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
80 return 0;
81 }
82 return sizeof(arr) / sizeof(arr[0]);
83 }
84
IsInitedFuzzTest()85 void IsInitedFuzzTest()
86 {
87 GetAdaptorBlueToothSink()->IsInited();
88 }
89
SetAudioSceneFuzzTest()90 void SetAudioSceneFuzzTest()
91 {
92 AudioScene audioScene = GetData<AudioScene>();
93 DeviceType deviceType = GetData<DeviceType>();
94 std::vector<DeviceType> activeDevices = {deviceType};
95 GetAdaptorBlueToothSink()->SetAudioScene(audioScene, activeDevices);
96 }
97
SetOutputRoutesFuzzTest()98 void SetOutputRoutesFuzzTest()
99 {
100 DeviceType deviceType = GetData<DeviceType>();
101 std::vector<DeviceType> outputDevices = {deviceType};
102 GetAdaptorBlueToothSink()->UpdateActiveDevice(outputDevices);
103 }
104
SetAudioParameterFuzzTest()105 void SetAudioParameterFuzzTest()
106 {
107 AudioParamKey key = GetData<AudioParamKey>();
108 std::string condition = "123456";
109 std::string value = "123456";
110 GetAdaptorBlueToothSink()->SetAudioParameter(key, condition, value);
111 }
112
GetAudioParameterFuzzTest()113 void GetAudioParameterFuzzTest()
114 {
115 AudioParamKey key = GetData<AudioParamKey>();
116 std::string condition = "123456";
117 GetAdaptorBlueToothSink()->GetAudioParameter(key, condition);
118 }
119
RegisterParameterCallbackFuzzTest()120 void RegisterParameterCallbackFuzzTest()
121 {
122 IAudioSinkCallback *callback_ = nullptr;
123 GetAdaptorBlueToothSink()->RegistCallback(HDI_CB_RENDER_STATE, callback_);
124 }
125
InitFuzzTest()126 void InitFuzzTest()
127 {
128 IAudioSinkAttr attr = {};
129 attr.adapterName = SINK_ADAPTER_NAME;
130 attr.sampleRate = GetData<uint32_t>();
131 attr.channel = GetData<uint32_t>();
132 attr.format = GetData<AudioSampleFormat>();
133 attr.channelLayout = COMMON_UINT64_NUM;
134 attr.deviceType = GetData<DeviceType>();
135 attr.volume = GetData<float>();
136 attr.openMicSpeaker = GetData<uint32_t>();
137
138 GetAdaptorBlueToothSink()->Init(attr);
139 }
140
RenderFrameFuzzTest()141 void RenderFrameFuzzTest()
142 {
143 char data = GetData<char>();
144 uint64_t len = GetData<uint64_t>();
145 uint64_t writeLen = GetData<uint64_t>();
146 GetAdaptorBlueToothSink()->RenderFrame(data, len, writeLen);
147 }
148
StartFuzzTest()149 void StartFuzzTest()
150 {
151 GetAdaptorBlueToothSink()->Start();
152 }
153
SetVolumeFuzzTest()154 void SetVolumeFuzzTest()
155 {
156 float left = GetData<float>();
157 float right = GetData<float>();
158
159 GetAdaptorBlueToothSink()->SetVolume(left, right);
160 }
161
GetVolumeFuzzTest()162 void GetVolumeFuzzTest()
163 {
164 float left, right;
165 if (g_dataSize >= sizeof(left)) {
166 left = GetData<float>();
167 } else {
168 return;
169 }
170 if (g_dataSize >= sizeof(right)) {
171 right = GetData<float>();
172 } else {
173 return;
174 }
175 GetAdaptorBlueToothSink()->GetVolume(left, right);
176 }
177
GetTransactionIdFuzzTest()178 void GetTransactionIdFuzzTest()
179 {
180 uint64_t transactionId = GetData<uint64_t>();
181 GetAdaptorBlueToothSink()->GetTransactionId(transactionId);
182 }
183
StopFuzzTest()184 void StopFuzzTest()
185 {
186 GetAdaptorBlueToothSink()->Stop();
187 }
188
PauseFuzzTest()189 void PauseFuzzTest()
190 {
191 GetAdaptorBlueToothSink()->Pause();
192 }
193
ResumeFuzzTest()194 void ResumeFuzzTest()
195 {
196 GetAdaptorBlueToothSink()->Resume();
197 }
198
ResetFuzzTest()199 void ResetFuzzTest()
200 {
201 GetAdaptorBlueToothSink()->Reset();
202 }
203
FlushFuzzTest()204 void FlushFuzzTest()
205 {
206 GetAdaptorBlueToothSink()->Flush();
207 }
208
SuspendRenderSinkFuzzTest()209 void SuspendRenderSinkFuzzTest()
210 {
211 GetAdaptorBlueToothSink()->SuspendRenderSink();
212 }
213
RestoreRenderSinkFuzzTest()214 void RestoreRenderSinkFuzzTest()
215 {
216 GetAdaptorBlueToothSink()->RestoreRenderSink();
217 }
218
GetPresentationPositionFuzzTest()219 void GetPresentationPositionFuzzTest()
220 {
221 uint64_t frames = GetData<uint64_t>();
222 int64_t timeSec = GetData<int64_t>();
223 int64_t timeNanoSec = GetData<int64_t>();
224 GetAdaptorBlueToothSink()->GetPresentationPosition(frames, timeSec, timeNanoSec);
225 }
226
ResetOutputRouteForDisconnectFuzzTest()227 void ResetOutputRouteForDisconnectFuzzTest()
228 {
229 DeviceType deviceType = GetData<DeviceType>();
230 GetAdaptorBlueToothSink()->ResetActiveDeviceForDisconnect(deviceType);
231 }
232
SetPaPowerFuzzTest()233 void SetPaPowerFuzzTest()
234 {
235 int32_t flag = GetData<int32_t>();
236 GetAdaptorBlueToothSink()->SetPaPower(flag);
237 }
238
ReleaseRenderIdFuzzTest()239 void ReleaseRenderIdFuzzTest()
240 {
241 g_renderId = HdiAdapterManager::GetInstance().GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_MMAP,
242 true);
243 }
244
245 typedef void (*TestFuncs[22])();
246
247 TestFuncs g_testFuncs = {
248 InitFuzzTest,
249 RenderFrameFuzzTest,
250 StartFuzzTest,
251 IsInitedFuzzTest,
252 SetAudioSceneFuzzTest,
253 SetOutputRoutesFuzzTest,
254 SetAudioParameterFuzzTest,
255 GetAudioParameterFuzzTest,
256 RegisterParameterCallbackFuzzTest,
257 SetVolumeFuzzTest,
258 GetVolumeFuzzTest,
259 GetTransactionIdFuzzTest,
260 SuspendRenderSinkFuzzTest,
261 RestoreRenderSinkFuzzTest,
262 GetPresentationPositionFuzzTest,
263 ResetOutputRouteForDisconnectFuzzTest,
264 SetPaPowerFuzzTest,
265 PauseFuzzTest,
266 ResumeFuzzTest,
267 ResetFuzzTest,
268 FlushFuzzTest,
269 StopFuzzTest,
270 };
271
FuzzTest(const uint8_t * rawData,size_t size)272 bool FuzzTest(const uint8_t* rawData, size_t size)
273 {
274 if (rawData == nullptr) {
275 return false;
276 }
277
278 // initialize data
279 RAW_DATA = rawData;
280 g_dataSize = size;
281 g_pos = 0;
282 GetRenderId();
283
284 uint32_t code = GetData<uint32_t>();
285 uint32_t len = GetArrLength(g_testFuncs);
286 if (len > 0) {
287 g_testFuncs[code % len]();
288 } else {
289 AUDIO_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
290 }
291
292 // release data
293 ReleaseRenderId();
294 return true;
295 }
296 } // namespace AudioStandard
297 } // namesapce OHOS
298
299 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)300 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
301 {
302 if (size < OHOS::AudioStandard::THRESHOLD) {
303 return 0;
304 }
305
306 OHOS::AudioStandard::FuzzTest(data, size);
307 return 0;
308 }
309