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