• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }