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