• 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_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 }