• 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 "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