1 /*
2 * Copyright (c) 2024-2025 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_service.h"
20 #include "ipc_stream_stub.h"
21 #include "ipc_stream_in_server.h"
22 #include "none_mix_engine.h"
23 #include "ipc_stream.h"
24 #include "securec.h"
25 #include "audio_errors.h"
26 #include "audio_service_log.h"
27 using namespace std;
28
29 namespace OHOS {
30 namespace AudioStandard {
31 constexpr int32_t DEFAULT_STREAM_ID = 10;
32 const std::u16string FORMMGR_INTERFACE_TOKEN = u"IStandardAudioService";
33 const uint64_t COMMON_LENGTH_NUM = 2;
34 const uint32_t OPERATION_ENUM_NUM = 13;
35 const uint32_t SOURCETYPE_ENUM_NUM = 4;
36 const uint32_t NUM = 1;
37 static const uint8_t* RAW_DATA = nullptr;
38 static size_t g_dataSize = 0;
39 static size_t g_pos;
40 const size_t THRESHOLD = 10;
41
42 /*
43 * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
44 * tips: only support basic type
45 */
46 template<class T>
GetData()47 T GetData()
48 {
49 T object {};
50 size_t objectSize = sizeof(object);
51 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
52 return object;
53 }
54 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
55 if (ret != EOK) {
56 return {};
57 }
58 g_pos += objectSize;
59 return object;
60 }
61
62 template<class T>
GetArrLength(T & arr)63 uint32_t GetArrLength(T& arr)
64 {
65 if (arr == nullptr) {
66 AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
67 return 0;
68 }
69 return sizeof(arr) / sizeof(arr[0]);
70 }
71
InitProcessConfig()72 static AudioProcessConfig InitProcessConfig()
73 {
74 AudioProcessConfig config;
75 config.appInfo.appUid = DEFAULT_STREAM_ID;
76 config.appInfo.appPid = DEFAULT_STREAM_ID;
77 config.streamInfo.format = SAMPLE_S32LE;
78 config.streamInfo.samplingRate = SAMPLE_RATE_48000;
79 config.streamInfo.channels = STEREO;
80 config.streamInfo.channelLayout = AudioChannelLayout::CH_LAYOUT_STEREO;
81 config.audioMode = AudioMode::AUDIO_MODE_PLAYBACK;
82 config.streamType = AudioStreamType::STREAM_MUSIC;
83 config.deviceType = DEVICE_TYPE_USB_HEADSET;
84 return config;
85 }
86
AudioServiceMoreFuzzTest()87 void AudioServiceMoreFuzzTest()
88 {
89 AudioProcessConfig config;
90 config.appInfo.appUid = DEFAULT_STREAM_ID;
91 config.appInfo.appPid = DEFAULT_STREAM_ID;
92 config.streamInfo.format = SAMPLE_S32LE;
93 config.streamInfo.samplingRate = SAMPLE_RATE_48000;
94 config.streamInfo.channels = STEREO;
95 config.streamInfo.channelLayout = AudioChannelLayout::CH_LAYOUT_STEREO;
96 config.audioMode = AudioMode::AUDIO_MODE_RECORD;
97 config.streamType = AudioStreamType::STREAM_MUSIC;
98 config.deviceType = DEVICE_TYPE_USB_HEADSET;
99
100 AudioService *audioServicePtr = AudioService::GetInstance();
101 sptr<AudioProcessInServer> processStream = AudioProcessInServer::Create(config, audioServicePtr);
102 std::shared_ptr<AudioProcessInServer> audioProcessInServer =
103 std::make_shared<AudioProcessInServer>(config, audioServicePtr);
104 audioProcessInServer->Release(true);
105 audioProcessInServer->Release(false);
106
107 uint32_t sessionId = GetData<uint32_t>();
108 AudioPlaybackCaptureConfig newConfig;
109 audioServicePtr->UpdateMuteControlSet(sessionId, true);
110 audioServicePtr->UpdateMuteControlSet(sessionId, false);
111 audioServicePtr->EnableDualToneList(sessionId);
112 audioServicePtr->OnCapturerFilterChange(sessionId, newConfig, 1);
113 audioServicePtr->OnCapturerFilterRemove(sessionId, 1);
114
115 int32_t ret = GetData<int32_t>();
116 audioServicePtr->workingConfigs_[1];
117 audioServicePtr->GetIpcStream(config, ret);
118 #ifdef HAS_FEATURE_INNERCAPTURER
119 audioServicePtr->ShouldBeInnerCap(config, 1);
120 audioServicePtr->ShouldBeDualTone(config);
121
122 audioServicePtr->OnInitInnerCapList(1);
123 audioServicePtr->OnUpdateInnerCapList(1);
124 audioServicePtr->ResetAudioEndpoint();
125 #endif
126 uint32_t sourceTypeInt = GetData<uint32_t>();
127 sourceTypeInt = (sourceTypeInt % SOURCETYPE_ENUM_NUM) - NUM;
128 SourceType sourceType = static_cast<SourceType>(sourceTypeInt);
129 audioServicePtr->UpdateSourceType(sourceType);
130 }
131
AudioCapturerInServerMoreFuzzTest()132 void AudioCapturerInServerMoreFuzzTest()
133 {
134 AudioProcessConfig config = InitProcessConfig();
135 std::weak_ptr<IStreamListener> innerListener;
136 std::shared_ptr<CapturerInServer> capturerInServer = std::make_shared<CapturerInServer>(config, innerListener);
137 if (capturerInServer == nullptr) {
138 return;
139 }
140
141 RestoreInfo restoreInfo;
142 restoreInfo.restoreReason = static_cast<RestoreReason>(GetData<int32_t>());
143 restoreInfo.targetStreamFlag = GetData<int32_t>();
144 uint32_t operationInt = GetData<uint32_t>();
145 operationInt = (operationInt % OPERATION_ENUM_NUM) - NUM;
146 IOperation operation = static_cast<IOperation>(operationInt);
147 capturerInServer->OnStatusUpdate(operation);
148
149 size_t length = COMMON_LENGTH_NUM;
150 capturerInServer->ReadData(length);
151 #ifdef HAS_FEATURE_INNERCAPTURER
152 AudioPlaybackCaptureConfig captureconfig;
153 capturerInServer->UpdatePlaybackCaptureConfig(captureconfig);
154 #endif
155 capturerInServer->SetNonInterruptMute(true);
156 capturerInServer->RestoreSession(restoreInfo);
157 }
158
AudioNoneMixEngineMoreFuzzTest()159 void AudioNoneMixEngineMoreFuzzTest()
160 {
161 std::shared_ptr<NoneMixEngine> noneMixEngine = std::make_shared<NoneMixEngine>();
162 noneMixEngine->isInit_ = true;
163 AudioDeviceDescriptor type(AudioDeviceDescriptor::DEVICE_INFO);
164 type.deviceType_ = DEVICE_TYPE_USB_HEADSET;
165 noneMixEngine->Init(type, true);
166 noneMixEngine->Start();
167
168 noneMixEngine->isStart_ = true;
169 noneMixEngine->Stop();
170 noneMixEngine->PauseAsync();
171
172 noneMixEngine->MixStreams();
173 noneMixEngine->IsPlaybackEngineRunning();
174 noneMixEngine->StandbySleep();
175
176 std::vector<AudioSamplingRate> audioSamplingRate = {
177 SAMPLE_RATE_16000,
178 SAMPLE_RATE_48000,
179 };
180 uint32_t sourceTypeInt = GetData<uint32_t>();
181 sourceTypeInt = sourceTypeInt % audioSamplingRate.size();
182 AudioSamplingRate samplingRate = audioSamplingRate[sourceTypeInt];
183 noneMixEngine->GetDirectVoipSampleRate(samplingRate);
184 }
185
AudioIpcStreamStubFuzzTest()186 void AudioIpcStreamStubFuzzTest()
187 {
188 AudioProcessConfig config = InitProcessConfig();
189 int32_t ret = 0;
190 sptr<IpcStreamInServer> ipcStream = IpcStreamInServer::Create(config, ret);
191 if (ipcStream == nullptr) {
192 return;
193 }
194
195 MessageParcel data;
196 data.WriteInterfaceToken(IpcStream::GetDescriptor());
197 data.WriteBuffer(RAW_DATA, g_dataSize);
198 data.RewindRead(0);
199 MessageParcel reply;
200 MessageOption option;
201
202 std::vector<IpcStream::IpcStreamMsg> ipcStreamType = {
203 IpcStream::ON_REGISTER_STREAM_LISTENER,
204 IpcStream::ON_RESOLVE_BUFFER,
205 IpcStream::ON_UPDATE_POSITION,
206 IpcStream::ON_GET_AUDIO_SESSIONID,
207 IpcStream::ON_START,
208 IpcStream::ON_PAUSE,
209 IpcStream::ON_STOP,
210 IpcStream::ON_RELEASE,
211 IpcStream::ON_FLUSH,
212 IpcStream::ON_DRAIN,
213 IpcStream::ON_UPDATA_PLAYBACK_CAPTURER_CONFIG,
214 IpcStream::OH_GET_AUDIO_TIME,
215 IpcStream::OH_GET_AUDIO_POSITION,
216 IpcStream::ON_GET_LATENCY,
217 IpcStream::ON_SET_RATE,
218 IpcStream::ON_GET_RATE,
219 };
220 uint32_t sourceTypeInt = GetData<uint32_t>();
221 sourceTypeInt = sourceTypeInt % ipcStreamType.size();
222 IpcStream::IpcStreamMsg StreamType = ipcStreamType[sourceTypeInt];
223 ipcStream->OnRemoteRequest(StreamType, data, reply, option);
224 }
225
AudioIpcStreamStubOnMiddleCodeFuzzTest()226 void AudioIpcStreamStubOnMiddleCodeFuzzTest()
227 {
228 AudioProcessConfig config = InitProcessConfig();
229 int32_t ret = 0;
230 sptr<IpcStreamInServer> ipcStream = IpcStreamInServer::Create(config, ret);
231 if (ipcStream == nullptr) {
232 return;
233 }
234
235 MessageParcel data;
236 data.WriteInterfaceToken(FORMMGR_INTERFACE_TOKEN);
237 data.WriteBuffer(RAW_DATA, g_dataSize);
238 data.RewindRead(0);
239 MessageParcel reply;
240 MessageOption option;
241
242 std::vector<IpcStream::IpcStreamMsg> ipcStreamType = {
243 IpcStream::ON_SET_LOWPOWER_VOLUME,
244 IpcStream::ON_GET_LOWPOWER_VOLUME,
245 IpcStream::ON_SET_EFFECT_MODE,
246 IpcStream::ON_GET_EFFECT_MODE,
247 IpcStream::ON_SET_PRIVACY_TYPE,
248 IpcStream::ON_GET_PRIVACY_TYPE,
249 IpcStream::ON_SET_OFFLOAD_MODE,
250 IpcStream::ON_UNSET_OFFLOAD_MODE,
251 IpcStream::ON_GET_OFFLOAD_APPROXIMATELY_CACHE_TIME,
252 IpcStream::ON_UPDATE_SPATIALIZATION_STATE,
253 IpcStream::ON_GET_STREAM_MANAGER_TYPE,
254 IpcStream::ON_SET_SILENT_MODE_AND_MIX_WITH_OTHERS,
255 IpcStream::ON_SET_CLIENT_VOLUME,
256 IpcStream::ON_SET_MUTE,
257 IpcStream::ON_REGISTER_THREAD_PRIORITY,
258 };
259 uint32_t sourceTypeInt = GetData<uint32_t>();
260 sourceTypeInt = sourceTypeInt % ipcStreamType.size();
261 IpcStream::IpcStreamMsg StreamType = ipcStreamType[sourceTypeInt];
262 ipcStream->OnMiddleCodeRemoteRequest(StreamType, data, reply, option);
263 }
264
265 typedef void (*TestFuncs[5])();
266
267 TestFuncs g_testFuncs = {
268 AudioServiceMoreFuzzTest,
269 AudioCapturerInServerMoreFuzzTest,
270 AudioNoneMixEngineMoreFuzzTest,
271 AudioIpcStreamStubFuzzTest,
272 AudioIpcStreamStubOnMiddleCodeFuzzTest,
273 };
274
FuzzTest(const uint8_t * rawData,size_t size)275 bool FuzzTest(const uint8_t* rawData, size_t size)
276 {
277 if (rawData == nullptr) {
278 return false;
279 }
280
281 // initialize data
282 RAW_DATA = rawData;
283 g_dataSize = size;
284 g_pos = 0;
285
286 uint32_t code = GetData<uint32_t>();
287 uint32_t len = GetArrLength(g_testFuncs);
288 if (len > 0) {
289 g_testFuncs[code % len]();
290 } else {
291 AUDIO_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
292 }
293
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 }