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 "accesstoken_kit.h"
21 #include "message_parcel.h"
22 #include "nativetoken_kit.h"
23 #include "token_setproc.h"
24 #include "access_token.h"
25 #include "securec.h"
26 #include "parameter.h"
27
28 #include "audio_info.h"
29 #include "audio_inner_call.h"
30 #include "audio_server.h"
31 #include "audio_service.h"
32 #include "audio_param_parser.h"
33 #include "audio_process_config.h"
34 #include "audio_utils.h"
35 #include "audio_stream_info.h"
36 #include "policy_provider_stub.h"
37
38 namespace OHOS {
39 namespace AudioStandard {
40 const std::u16string FORMMGR_INTERFACE_TOKEN = u"IStandardAudioService";
41 const int32_t SYSTEM_ABILITY_ID = 3001;
42 const int32_t POLICY_SYSTEM_ABILITY_ID = 3009;
43 const uint32_t LIMIT_TWO = 2;
44 const uint32_t FUZZ_TEST_UID = 10000; // for test
45 const uint32_t STD_OUT_FD = 1;
46 const bool RUN_ON_CREATE = false;
47
48 bool g_hasServerInit = false;
49 bool g_dumpPlayback = false;
50 bool g_dumpCapturer = false;
51
52 const uint8_t *g_baseFuzzData = nullptr;
53 size_t g_baseFuzzSize = 0;
54 size_t g_baseFuzzPos;
55
GetData()56 template <class T> T GetData()
57 {
58 T object{};
59 size_t objectSize = sizeof(object);
60 if (g_baseFuzzData == nullptr || objectSize > g_baseFuzzSize - g_baseFuzzPos) {
61 return object;
62 }
63 errno_t ret = memcpy_s(&object, objectSize, g_baseFuzzData + g_baseFuzzPos, objectSize);
64 if (ret != EOK) {
65 return {};
66 }
67 g_baseFuzzPos += objectSize;
68 return object;
69 }
70
71 class MockPolicyProvider : public IPolicyProvider {
72 public:
MockPolicyProvider()73 MockPolicyProvider() {};
~MockPolicyProvider()74 ~MockPolicyProvider() {};
75
76 int32_t GetProcessDeviceInfo(const AudioProcessConfig &config, bool lockFlag,
77 AudioDeviceDescriptor &deviceInfo) override;
78
79 int32_t InitSharedVolume(std::shared_ptr<AudioSharedMemory> &buffer) override;
80
81 int32_t SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config) override;
82
83 int32_t NotifyCapturerAdded(AudioCapturerInfo capturerInfo, AudioStreamInfo streamInfo,
84 uint32_t sessionId) override;
85
86 int32_t NotifyWakeUpCapturerRemoved() override;
87
88 bool IsAbsVolumeSupported() override;
89
90 int32_t OffloadGetRenderPosition(uint32_t &delayValue, uint64_t &sendDataSize, uint32_t &timeStamp) override;
91
92 int32_t GetAndSaveClientType(uint32_t uid, const std::string &bundleName) override;
93
94 int32_t GetMaxRendererInstances() override;
95
96 int32_t ActivateConcurrencyFromServer(AudioPipeType incomingPipe) override;
97
98 int32_t NotifyCapturerRemoved(uint64_t sessionId) override;
99
100 int32_t SetDefaultOutputDevice(const DeviceType defaultOutputDevice, const uint32_t sessionID,
101 const StreamUsage streamUsage, bool isRunning) override;
102
103 std::shared_ptr<AudioSharedMemory> policyVolumeMap_ = nullptr;
104 };
105
GetProcessDeviceInfo(const AudioProcessConfig & config,bool lockFlag,AudioDeviceDescriptor & deviceInfo)106 int32_t MockPolicyProvider::GetProcessDeviceInfo(const AudioProcessConfig &config, bool lockFlag,
107 AudioDeviceDescriptor &deviceInfo)
108 {
109 if (config.audioMode == AUDIO_MODE_PLAYBACK) {
110 deviceInfo.deviceRole_ = OUTPUT_DEVICE;
111 deviceInfo.deviceType_ = DEVICE_TYPE_SPEAKER;
112 } else {
113 deviceInfo.deviceRole_ = INPUT_DEVICE;
114 deviceInfo.deviceType_ = DEVICE_TYPE_MIC;
115 }
116 deviceInfo.deviceId_ = 0;
117 deviceInfo.networkId_ = "LocalDevice";
118 deviceInfo.deviceName_ = "testname";
119
120 deviceInfo.audioStreamInfo_ = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO};
121 return SUCCESS;
122 }
123
InitSharedVolume(std::shared_ptr<AudioSharedMemory> & buffer)124 int32_t MockPolicyProvider::InitSharedVolume(std::shared_ptr<AudioSharedMemory> &buffer)
125 {
126 size_t mapSize = IPolicyProvider::GetVolumeVectorSize() * sizeof(Volume);
127 policyVolumeMap_ = AudioSharedMemory::CreateFormLocal(mapSize, "MockVolumeMap");
128 buffer = policyVolumeMap_;
129 return SUCCESS;
130 }
131
SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig & config)132 int32_t MockPolicyProvider::SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config)
133 {
134 return SUCCESS;
135 }
136
NotifyCapturerAdded(AudioCapturerInfo capturerInfo,AudioStreamInfo streamInfo,uint32_t sessionId)137 int32_t MockPolicyProvider::NotifyCapturerAdded(AudioCapturerInfo capturerInfo, AudioStreamInfo streamInfo,
138 uint32_t sessionId)
139 {
140 return SUCCESS;
141 }
142
NotifyWakeUpCapturerRemoved()143 int32_t MockPolicyProvider::NotifyWakeUpCapturerRemoved()
144 {
145 return SUCCESS;
146 }
147
IsAbsVolumeSupported()148 bool MockPolicyProvider::IsAbsVolumeSupported()
149 {
150 return SUCCESS;
151 }
152
OffloadGetRenderPosition(uint32_t & delayValue,uint64_t & sendDataSize,uint32_t & timeStamp)153 int32_t MockPolicyProvider::OffloadGetRenderPosition(uint32_t &delayValue, uint64_t &sendDataSize, uint32_t &timeStamp)
154 {
155 return SUCCESS;
156 }
157
GetAndSaveClientType(uint32_t uid,const std::string & bundleName)158 int32_t MockPolicyProvider::GetAndSaveClientType(uint32_t uid, const std::string &bundleName)
159 {
160 return SUCCESS;
161 }
162
GetMaxRendererInstances()163 int32_t MockPolicyProvider::GetMaxRendererInstances()
164 {
165 return SUCCESS;
166 }
167
ActivateConcurrencyFromServer(AudioPipeType incomingPipe)168 int32_t MockPolicyProvider::ActivateConcurrencyFromServer(AudioPipeType incomingPipe)
169 {
170 return SUCCESS;
171 }
172
NotifyCapturerRemoved(uint64_t sessionId)173 int32_t MockPolicyProvider::NotifyCapturerRemoved(uint64_t sessionId)
174 {
175 return SUCCESS;
176 }
177
SetDefaultOutputDevice(const DeviceType defaultOutputDevice,const uint32_t sessionID,const StreamUsage streamUsage,bool isRunning)178 int32_t MockPolicyProvider::SetDefaultOutputDevice(const DeviceType defaultOutputDevice, const uint32_t sessionID,
179 const StreamUsage streamUsage, bool isRunning)
180 {
181 return SUCCESS;
182 }
AudioFuzzTestGetPermission()183 void AudioFuzzTestGetPermission()
184 {
185 uint64_t tokenId;
186 constexpr int perNum = 10;
187 const char *perms[perNum] = {
188 "ohos.permission.MICROPHONE",
189 "ohos.permission.RECORD_VOICE_CALL",
190 "ohos.permission.CAST_AUDIO_OUTPUT",
191 "ohos.permission.MANAGE_INTELLIGENT_VOICE",
192 "ohos.permission.MANAGE_AUDIO_CONFIG",
193 "ohos.permission.MICROPHONE_CONTROL",
194 "ohos.permission.MODIFY_AUDIO_SETTINGS",
195 };
196
197 NativeTokenInfoParams infoInstance = {
198 .dcapsNum = 0,
199 .permsNum = 10,
200 .aclsNum = 0,
201 .dcaps = nullptr,
202 .perms = perms,
203 .acls = nullptr,
204 .processName = "audiofuzztest",
205 .aplStr = "system_basic",
206 };
207 tokenId = GetAccessTokenId(&infoInstance);
208 SetSelfTokenID(tokenId);
209 OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
210 }
211
GetServerPtr()212 AudioServer *GetServerPtr()
213 {
214 static AudioServer server(SYSTEM_ABILITY_ID, RUN_ON_CREATE);
215 if (!g_hasServerInit) {
216 g_hasServerInit = true;
217 server.OnAddSystemAbility(POLICY_SYSTEM_ABILITY_ID, "");
218 server.RegisterAudioCapturerSourceCallback();
219 std::unique_ptr<AudioParamParser> audioParamParser = std::make_unique<AudioParamParser>();
220 if (audioParamParser == nullptr) {
221 server.WriteServiceStartupError();
222 }
223 if (audioParamParser->LoadConfiguration(AudioServer::audioParameterKeys)) {
224 AUDIO_INFO_LOG("Audio extra parameters load configuration successfully.");
225 }
226
227 std::vector<std::pair<std::string, std::string>> kvpairs = {
228 {"key1", "value1"},
229 {"key2", "value2"},
230 {"key3", "value3"}
231 };
232 server.SetExtraParameters("PCM_DUMP", kvpairs);
233 server.SetExtraParameters("test", kvpairs);
234
235 AudioInnerCall::GetInstance()->RegisterAudioServer(&server);
236
237 server.GetHapBuildApiVersion(0);
238 server.GetBundleNameFromUid(0);
239 }
240 return &server;
241 }
242
InitAudioServer()243 void InitAudioServer()
244 {
245 static MockPolicyProvider mockProvider;
246 sptr<PolicyProviderWrapper> wrapper = new(std::nothrow) PolicyProviderWrapper(&mockProvider);
247
248 // call GetServerPtr()->RegiestPolicyProvider will enable capturer
249
250 std::shared_ptr<AudioSharedMemory> buffer;
251 wrapper->InitSharedVolume(buffer);
252 AudioProcessConfig config;
253 AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO);
254 wrapper->GetProcessDeviceInfo(config, true, deviceInfo);
255 wrapper->SetWakeUpAudioCapturerFromAudioServer(config);
256 wrapper->NotifyCapturerAdded(config.capturerInfo, config.streamInfo, 0);
257 wrapper->NotifyWakeUpCapturerRemoved();
258 wrapper->IsAbsVolumeSupported();
259 }
260
ModifyStreamInfoFormat(AudioProcessConfig & config)261 void ModifyStreamInfoFormat(AudioProcessConfig &config)
262 {
263 if (config.streamInfo.samplingRate > SAMPLE_RATE_48000) {
264 config.streamInfo.samplingRate = SAMPLE_RATE_96000;
265 } else {
266 config.streamInfo.samplingRate = SAMPLE_RATE_48000;
267 }
268
269 config.streamInfo.format = static_cast<AudioSampleFormat>(config.streamInfo.format % (SAMPLE_F32LE + 1));
270
271 config.streamInfo.encoding = static_cast<AudioEncodingType>(config.streamInfo.encoding % LIMIT_TWO);
272
273 config.streamInfo.channelLayout = CH_LAYOUT_STEREO;
274
275 if (config.audioMode == AUDIO_MODE_PLAYBACK) {
276 config.streamInfo.channels = static_cast<AudioChannel>(config.streamInfo.channels % (CHANNEL_16 + 1));
277 }
278
279 if (config.audioMode == AUDIO_MODE_RECORD) {
280 config.streamInfo.channels = static_cast<AudioChannel>(config.streamInfo.channels % (CHANNEL_6 + 1));
281 }
282 }
283
ModifyRendererConfig(AudioProcessConfig & config)284 void ModifyRendererConfig(AudioProcessConfig &config)
285 {
286 config.rendererInfo.streamUsage = static_cast<StreamUsage>(config.rendererInfo.streamUsage %
287 (STREAM_USAGE_MAX + 1));
288
289 config.rendererInfo.rendererFlags = config.rendererInfo.rendererFlags % (AUDIO_FLAG_VOIP_DIRECT + 1);
290
291 config.rendererInfo.pipeType = static_cast<AudioPipeType>(config.rendererInfo.pipeType %
292 (PIPE_TYPE_DIRECT_VOIP + 1));
293 }
294
ModifyRecorderConfig(AudioProcessConfig & config)295 void ModifyRecorderConfig(AudioProcessConfig &config)
296 {
297 config.capturerInfo.sourceType = static_cast<SourceType>(config.capturerInfo.sourceType % (SOURCE_TYPE_MAX + 1));
298
299 config.capturerInfo.capturerFlags = config.capturerInfo.capturerFlags % (AUDIO_FLAG_VOIP_DIRECT + 1);
300
301 config.capturerInfo.pipeType = static_cast<AudioPipeType>(config.capturerInfo.pipeType %
302 (PIPE_TYPE_DIRECT_VOIP + 1));
303 }
304
ModifyProcessConfig(AudioProcessConfig & config)305 void ModifyProcessConfig(AudioProcessConfig &config)
306 {
307 config.audioMode = static_cast<AudioMode>(config.audioMode % LIMIT_TWO);
308 ModifyStreamInfoFormat(config);
309
310 if (config.audioMode == AUDIO_MODE_PLAYBACK) {
311 ModifyRendererConfig(config);
312 }
313
314 if (config.audioMode == AUDIO_MODE_RECORD) {
315 ModifyRecorderConfig(config);
316 }
317 }
318
CallStreamFuncs(sptr<IpcStreamInServer> ipcStream)319 void CallStreamFuncs(sptr<IpcStreamInServer> ipcStream)
320 {
321 if (ipcStream == nullptr) {
322 return;
323 }
324
325 std::shared_ptr<OHAudioBuffer> buffer = nullptr;
326 ipcStream->ResolveBuffer(buffer);
327 ipcStream->UpdatePosition();
328
329 std::string name = "fuzz_test";
330 ipcStream->RegisterThreadPriority(0, name);
331 uint32_t sessionId = 0;
332 ipcStream->GetAudioSessionID(sessionId);
333 ipcStream->Start();
334 ipcStream->Pause();
335 ipcStream->Drain();
336 AudioPlaybackCaptureConfig config = {{{STREAM_USAGE_MUSIC}, FilterMode::INCLUDE, {0}, FilterMode::INCLUDE}, false};
337 ipcStream->UpdatePlaybackCaptureConfig(config);
338 uint64_t framePos = 0;
339 uint64_t timestamp = 0;
340 uint64_t latency = 0;
341 if (ipcStream->rendererInServer_ != nullptr) {
342 ipcStream->Flush();
343 ipcStream->GetAudioTime(framePos, timestamp);
344 ipcStream->GetAudioPosition(framePos, timestamp, latency);
345 ipcStream->GetLatency(timestamp);
346 }
347 int32_t param = 0;
348 ipcStream->SetRate(param);
349 ipcStream->GetRate(param);
350 float volume = 0.0f;
351 ipcStream->SetLowPowerVolume(volume);
352 ipcStream->GetLowPowerVolume(volume);
353 ipcStream->SetAudioEffectMode(param);
354 ipcStream->GetAudioEffectMode(param);
355 ipcStream->SetPrivacyType(param);
356 ipcStream->GetPrivacyType(param);
357 ipcStream->SetOffloadMode(param, false);
358 ipcStream->UnsetOffloadMode();
359 ipcStream->GetOffloadApproximatelyCacheTime(framePos, timestamp, timestamp, timestamp);
360 ipcStream->UpdateSpatializationState(true, false);
361 ipcStream->GetStreamManagerType();
362 ipcStream->SetSilentModeAndMixWithOthers(false);
363 ipcStream->SetClientVolume();
364 ipcStream->SetMute(false);
365 ipcStream->SetDuckFactor(volume);
366 ipcStream->Stop();
367 ipcStream->Release();
368 }
369
DoStreamFuzzTest(const AudioProcessConfig & config,const uint8_t * rawData,size_t size)370 void DoStreamFuzzTest(const AudioProcessConfig &config, const uint8_t *rawData, size_t size)
371 {
372 int32_t ret = 0;
373 sptr<IpcStreamInServer> ipcStream = AudioService::GetInstance()->GetIpcStream(config, ret);
374 if (ipcStream == nullptr || rawData == nullptr || size < sizeof(uint32_t)) {
375 return;
376 }
377
378 g_baseFuzzData = rawData;
379 g_baseFuzzSize = size;
380 g_baseFuzzPos = 0;
381 uint32_t code = GetData<uint32_t>() % (IpcStream::IpcStreamMsg::IPC_STREAM_MAX_MSG);
382
383 rawData = rawData + sizeof(uint32_t);
384 size = size - sizeof(uint32_t);
385
386 MessageParcel data;
387 data.WriteInterfaceToken(FORMMGR_INTERFACE_TOKEN);
388 data.WriteBuffer(rawData, size);
389 data.RewindRead(0);
390
391 MessageParcel reply;
392 MessageOption option;
393
394 ipcStream->OnRemoteRequest(code, data, reply, option);
395
396 if (config.audioMode == AUDIO_MODE_PLAYBACK && !g_dumpPlayback) {
397 g_dumpPlayback = true;
398 std::vector<std::u16string> args = {};
399 GetServerPtr()->Dump(STD_OUT_FD, args);
400 }
401
402 if (config.audioMode == AUDIO_MODE_RECORD && !g_dumpCapturer) {
403 g_dumpCapturer = true;
404 std::vector<std::u16string> args = {};
405 GetServerPtr()->Dump(STD_OUT_FD, args);
406 }
407
408 CallStreamFuncs(ipcStream);
409 }
410
AudioServerFuzzTest(const uint8_t * rawData,size_t size)411 void AudioServerFuzzTest(const uint8_t *rawData, size_t size)
412 {
413 g_baseFuzzData = rawData;
414 g_baseFuzzSize = size;
415 g_baseFuzzPos = 0;
416
417 if (size < sizeof(AudioProcessConfig)) {
418 return;
419 }
420
421 AudioProcessConfig config = {};
422 config.callerUid = GetData<int32_t>();
423 config.appInfo = GetData<AppInfo>();
424 config.streamInfo = GetData<AudioStreamInfo>();
425 config.audioMode = GetData<AudioMode>();
426
427 config.rendererInfo.contentType = GetData<ContentType>();
428 config.rendererInfo.streamUsage = GetData<StreamUsage>();
429 config.rendererInfo.rendererFlags = GetData<int32_t>();
430
431 config.rendererInfo.sceneType = ""; // in plan
432
433 config.rendererInfo.originalFlag = GetData<int32_t>();
434 config.rendererInfo.pipeType = GetData<AudioPipeType>();
435 config.rendererInfo.samplingRate = GetData<AudioSamplingRate>();
436 config.rendererInfo.format = GetData<AudioSampleFormat>();
437
438 config.capturerInfo.sourceType = GetData<SourceType>();
439 config.capturerInfo.capturerFlags = GetData<int32_t>();
440 config.capturerInfo.pipeType = GetData<AudioPipeType>();
441 config.capturerInfo.samplingRate = GetData<AudioSamplingRate>();
442 config.capturerInfo.encodingType = GetData<uint8_t>();
443 config.capturerInfo.channelLayout = GetData<uint64_t>();
444 config.capturerInfo.sceneType = ""; // in plan
445 config.capturerInfo.originalFlag = GetData<int32_t>();
446
447 config.streamType = GetData<AudioStreamType>();
448 config.deviceType = GetData<DeviceType>();
449 config.privacyType = GetData<AudioPrivacyType>();
450 config.innerCapMode = GetData<InnerCapMode>();
451
452 ModifyProcessConfig(config);
453
454 int32_t errorCode = 0;
455 auto remoteObj = GetServerPtr()->CreateAudioProcess(config, errorCode);
456 if (remoteObj != nullptr) {
457 DoStreamFuzzTest(config, rawData, size);
458 }
459 if (config.appInfo.appUid == 0) {
460 config.appInfo.appUid = FUZZ_TEST_UID; // to skip root pass
461 }
462 GetServerPtr()->CheckRecorderPermission(config);
463 }
464 } // namespace AudioStandard
465 } // namesapce OHOS
466
LLVMFuzzerInitialize(int * argc,char *** argv)467 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
468 {
469 OHOS::AudioStandard::AudioFuzzTestGetPermission();
470 SetParameter("persist.multimedia.audioflag.fast.disableseparate", "1");
471 OHOS::AudioStandard::InitAudioServer();
472 return 0;
473 }
474
475 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)476 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
477 {
478 /* Run your code on data */
479 OHOS::AudioStandard::AudioServerFuzzTest(data, size);
480 return 0;
481 }