• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
20 #include "audio_manager_base.h"
21 #include "audio_policy_manager_listener_stub.h"
22 #include "audio_server.h"
23 #include "audio_service.h"
24 #include "sink/i_audio_render_sink.h"
25 #include "common/hdi_adapter_info.h"
26 #include "manager/hdi_adapter_manager.h"
27 #include "audio_endpoint.h"
28 #include "access_token.h"
29 #include "message_parcel.h"
30 #include "audio_process_in_client.h"
31 #include "audio_process_in_server.h"
32 #include "audio_param_parser.h"
33 #include "none_mix_engine.h"
34 #include "pro_renderer_stream_impl.h"
35 #include "oh_audio_buffer.h"
36 using namespace std;
37 
38 namespace OHOS {
39 namespace AudioStandard {
40 constexpr int32_t DEFAULT_STREAM_ID = 10;
41 static std::unique_ptr<NoneMixEngine> playbackEngine_ = nullptr;
42 static const uint8_t* RAW_DATA = nullptr;
43 static size_t g_dataSize = 0;
44 static size_t g_pos;
45 const size_t THRESHOLD = 10;
46 
47 /*
48 * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
49 * tips: only support basic type
50 */
51 template<class T>
GetData()52 T GetData()
53 {
54     T object {};
55     size_t objectSize = sizeof(object);
56     if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
57         return object;
58     }
59     errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
60     if (ret != EOK) {
61         return {};
62     }
63     g_pos += objectSize;
64     return object;
65 }
66 
67 template<class T>
GetArrLength(T & arr)68 uint32_t GetArrLength(T& arr)
69 {
70     if (arr == nullptr) {
71         AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
72         return 0;
73     }
74     return sizeof(arr) / sizeof(arr[0]);
75 }
76 
DeviceFuzzTestSetUp()77 void DeviceFuzzTestSetUp()
78 {
79     if (playbackEngine_ != nullptr) {
80         return;
81     }
82     AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO);
83     deviceInfo.deviceType_ = DEVICE_TYPE_USB_HEADSET;
84     playbackEngine_ = std::make_unique<NoneMixEngine>();
85     bool isVoip = GetData<bool>();
86     playbackEngine_->Init(deviceInfo, isVoip);
87 }
88 
InitProcessConfig()89 static AudioProcessConfig InitProcessConfig()
90 {
91     AudioProcessConfig config;
92     config.appInfo.appUid = DEFAULT_STREAM_ID;
93     config.appInfo.appPid = DEFAULT_STREAM_ID;
94     config.streamInfo.format = SAMPLE_S32LE;
95     config.streamInfo.samplingRate = SAMPLE_RATE_48000;
96     config.streamInfo.channels = STEREO;
97     config.streamInfo.channelLayout = AudioChannelLayout::CH_LAYOUT_STEREO;
98     config.audioMode = AudioMode::AUDIO_MODE_RECORD;
99     config.streamType = AudioStreamType::STREAM_MUSIC;
100     config.deviceType = DEVICE_TYPE_USB_HEADSET;
101     return config;
102 }
103 
DirectAudioPlayBackEngineStateFuzzTest()104 void DirectAudioPlayBackEngineStateFuzzTest()
105 {
106     AudioProcessConfig config = InitProcessConfig();
107     std::shared_ptr<ProRendererStreamImpl> rendererStream = std::make_shared<ProRendererStreamImpl>(config, true);
108     rendererStream->InitParams();
109     uint32_t num = GetData<uint32_t>();
110     rendererStream->SetStreamIndex(num);
111     rendererStream->Start();
112     rendererStream->Pause();
113     rendererStream->Flush();
114     rendererStream->Stop();
115     rendererStream->Release();
116 }
117 
NoneMixEngineStartFuzzTest()118 void NoneMixEngineStartFuzzTest()
119 {
120     playbackEngine_ = std::make_unique<NoneMixEngine>();
121     playbackEngine_->Start();
122 }
123 
NoneMixEngineStopFuzzTest()124 void NoneMixEngineStopFuzzTest()
125 {
126     playbackEngine_ = std::make_unique<NoneMixEngine>();
127     playbackEngine_->Stop();
128 }
129 
NoneMixEnginePauseFuzzTest()130 void NoneMixEnginePauseFuzzTest()
131 {
132     playbackEngine_ = std::make_unique<NoneMixEngine>();
133     playbackEngine_->Pause();
134 }
135 
NoneMixEngineFlushFuzzTest()136 void NoneMixEngineFlushFuzzTest()
137 {
138     playbackEngine_ = std::make_unique<NoneMixEngine>();
139     playbackEngine_->Flush();
140 }
141 
NoneMixEngineAddRendererFuzzTest()142 void NoneMixEngineAddRendererFuzzTest()
143 {
144     AudioProcessConfig config = InitProcessConfig();
145     std::shared_ptr<ProRendererStreamImpl> rendererStream = std::make_shared<ProRendererStreamImpl>(config, true);
146     rendererStream->InitParams();
147     uint32_t num = GetData<uint32_t>();
148     rendererStream->SetStreamIndex(num);
149     rendererStream->Start();
150     playbackEngine_ = std::make_unique<NoneMixEngine>();
151     playbackEngine_->AddRenderer(rendererStream);
152 }
153 
NoneMixEngineRemoveRendererFuzzTest()154 void NoneMixEngineRemoveRendererFuzzTest()
155 {
156     AudioProcessConfig config = InitProcessConfig();
157     std::shared_ptr<ProRendererStreamImpl> rendererStream = std::make_shared<ProRendererStreamImpl>(config, true);
158     rendererStream->InitParams();
159     uint32_t num = GetData<uint32_t>();
160     rendererStream->SetStreamIndex(num);
161     rendererStream->Start();
162     playbackEngine_ = std::make_unique<NoneMixEngine>();
163     playbackEngine_->AddRenderer(rendererStream);
164     playbackEngine_->RemoveRenderer(rendererStream);
165 }
166 
167 
AudioEndPointSeparateStartDeviceFuzzTest(std::shared_ptr<AudioEndpointSeparate> audioEndpoint)168 void AudioEndPointSeparateStartDeviceFuzzTest(std::shared_ptr<AudioEndpointSeparate> audioEndpoint)
169 {
170     audioEndpoint->StartDevice();
171     audioEndpoint->GetEndpointName();
172     audioEndpoint->ShouldInnerCap(1);
173     audioEndpoint->EnableFastInnerCap(1);
174     audioEndpoint->DisableFastInnerCap(1);
175     return;
176 }
177 
AudioEndPointSeparateConfigFuzzTest()178 void AudioEndPointSeparateConfigFuzzTest()
179 {
180     AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO);
181     deviceInfo.deviceType_ = DEVICE_TYPE_USB_HEADSET;
182     deviceInfo.networkId_ = LOCAL_NETWORK_ID;
183     DeviceStreamInfo audioStreamInfo = {
184         SAMPLE_RATE_48000,
185         ENCODING_PCM,
186         SAMPLE_S16LE,
187         STEREO
188     };
189     deviceInfo.audioStreamInfo_ = audioStreamInfo;
190     std::shared_ptr<AudioEndpointSeparate> audioEndpoint = nullptr;
191     uint64_t id = GetData<uint64_t>();
192     AudioEndpoint::EndpointType type = GetData<AudioEndpoint::EndpointType>();
193     AudioStreamType streamType = GetData<AudioStreamType>();
194     audioEndpoint = std::make_shared<AudioEndpointSeparate>(type, id, streamType);
195     AudioProcessConfig config = InitProcessConfig();
196     AudioService *g_audioServicePtr = AudioService::GetInstance();
197     sptr<AudioProcessInServer> processStream = AudioProcessInServer::Create(config, g_audioServicePtr);
198     audioEndpoint->Config(deviceInfo);
199 
200     AudioEndPointSeparateStartDeviceFuzzTest(audioEndpoint);
201 
202     audioEndpoint->fastRenderId_ = HdiAdapterManager::GetInstance().GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_FAST,
203         HDI_ID_INFO_DEFAULT, true);
204     float volume = GetData<float>();
205     audioEndpoint->SetVolume(streamType, volume);
206 
207     uint32_t spanSizeInFrame = GetData<uint32_t>();
208     uint32_t totalSizeInFrame = GetData<uint32_t>();
209     uint32_t byteSizePerFrame = GetData<uint32_t>();
210     std::shared_ptr<OHAudioBuffer> oHAudioBuffer =
211         OHAudioBuffer::CreateFromLocal(totalSizeInFrame, spanSizeInFrame, byteSizePerFrame);
212     audioEndpoint->ResolveBuffer(oHAudioBuffer);
213     audioEndpoint->GetBuffer();
214     audioEndpoint->GetStatus();
215     audioEndpoint->OnStart(processStream);
216     audioEndpoint->OnPause(processStream);
217     audioEndpoint->OnUpdateHandleInfo(processStream);
218     audioEndpoint->LinkProcessStream(processStream);
219     audioEndpoint->UnlinkProcessStream(processStream);
220     audioEndpoint->GetPreferBufferInfo(totalSizeInFrame, spanSizeInFrame);
221     std::string dumpString = "";
222     audioEndpoint->Dump(dumpString);
223     audioEndpoint->GetEndpointType();
224     audioEndpoint->GetDeviceInfo();
225     audioEndpoint->GetDeviceRole();
226     audioEndpoint->GetMaxAmplitude();
227     audioEndpoint->Release();
228     audioEndpoint->StopDevice();
229     return;
230 }
231 
232 typedef void (*TestFuncs[9])();
233 
234 TestFuncs g_testFuncs = {
235     DeviceFuzzTestSetUp,
236     DirectAudioPlayBackEngineStateFuzzTest,
237     NoneMixEngineStartFuzzTest,
238     NoneMixEngineStopFuzzTest,
239     NoneMixEnginePauseFuzzTest,
240     NoneMixEngineFlushFuzzTest,
241     NoneMixEngineAddRendererFuzzTest,
242     NoneMixEngineRemoveRendererFuzzTest,
243     AudioEndPointSeparateConfigFuzzTest,
244 };
245 
FuzzTest(const uint8_t * rawData,size_t size)246 bool FuzzTest(const uint8_t* rawData, size_t size)
247 {
248     if (rawData == nullptr) {
249         return false;
250     }
251 
252     // initialize data
253     RAW_DATA = rawData;
254     g_dataSize = size;
255     g_pos = 0;
256 
257     uint32_t code = GetData<uint32_t>();
258     uint32_t len = GetArrLength(g_testFuncs);
259     if (len > 0) {
260         g_testFuncs[code % len]();
261     } else {
262         AUDIO_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
263     }
264 
265     return true;
266 }
267 } // namespace AudioStandard
268 } // namesapce OHOS
269 
270 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)271 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
272 {
273     if (size < OHOS::AudioStandard::THRESHOLD) {
274         return 0;
275     }
276 
277     OHOS::AudioStandard::FuzzTest(data, size);
278     return 0;
279 }
280