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 #include <cstring>
20 #include "audio_info.h"
21 #include "audio_policy_server.h"
22 #include "audio_policy_service.h"
23 #include "audio_device_info.h"
24 #include "audio_utils.h"
25 #include "accesstoken_kit.h"
26 #include "nativetoken_kit.h"
27 #include "token_setproc.h"
28 #include "access_token.h"
29 #include "audio_channel_blend.h"
30 #include "volume_ramp.h"
31 #include "audio_speed.h"
32
33 namespace OHOS {
34 namespace AudioStandard {
35 using namespace std;
36 const int32_t LIMITSIZE = 4;
37 const int64_t LIMIT_TIME = 1;
38 const uint32_t ENUMSIZE = 4;
39 const uint64_t COMMON_UINT64_NUM = 2;
40 const int64_t COMMON_INT64_NUM = 2;
41 bool g_hasPermission = false;
42 static const uint8_t* RAW_DATA = nullptr;
43 static size_t g_dataSize = 0;
44 static size_t g_pos;
45 const size_t THRESHOLD = 10;
46
47 /*
48 * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
49 * tips: only support basic type
50 */
51 template<class T>
GetData()52 T GetData()
53 {
54 T object {};
55 size_t objectSize = sizeof(object);
56 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
57 return object;
58 }
59 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
60 if (ret != EOK) {
61 return {};
62 }
63 g_pos += objectSize;
64 return object;
65 }
66
67 template<class T>
GetArrLength(T & arr)68 uint32_t GetArrLength(T& arr)
69 {
70 if (arr == nullptr) {
71 AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
72 return 0;
73 }
74 return sizeof(arr) / sizeof(arr[0]);
75 }
76
AudioFuzzTestGetPermission()77 void AudioFuzzTestGetPermission()
78 {
79 if (!g_hasPermission) {
80 uint64_t tokenId;
81 constexpr int perNum = 10;
82 const char *perms[perNum] = {
83 "ohos.permission.MICROPHONE",
84 "ohos.permission.MANAGE_INTELLIGENT_VOICE",
85 "ohos.permission.MANAGE_AUDIO_CONFIG",
86 "ohos.permission.MICROPHONE_CONTROL",
87 "ohos.permission.MODIFY_AUDIO_SETTINGS",
88 "ohos.permission.ACCESS_NOTIFICATION_POLICY",
89 "ohos.permission.USE_BLUETOOTH",
90 "ohos.permission.CAPTURE_VOICE_DOWNLINK_AUDIO",
91 "ohos.permission.RECORD_VOICE_CALL",
92 "ohos.permission.MANAGE_SYSTEM_AUDIO_EFFECTS",
93 };
94
95 NativeTokenInfoParams infoInstance = {
96 .dcapsNum = 0,
97 .permsNum = 10,
98 .aclsNum = 0,
99 .dcaps = nullptr,
100 .perms = perms,
101 .acls = nullptr,
102 .processName = "audiofuzztest",
103 .aplStr = "system_basic",
104 };
105 tokenId = GetAccessTokenId(&infoInstance);
106 SetSelfTokenID(tokenId);
107 OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
108 g_hasPermission = true;
109 }
110 }
111
GetCurNanoFuzzTest(const uint8_t * rawData,size_t size)112 void GetCurNanoFuzzTest(const uint8_t* rawData, size_t size)
113 {
114 if (rawData == nullptr || size < LIMITSIZE) {
115 return;
116 }
117
118 ClockTime::GetCurNano();
119 }
120
AbsoluteSleepFuzzTest()121 void AbsoluteSleepFuzzTest()
122 {
123 int64_t nanoTime = COMMON_INT64_NUM;
124 if (nanoTime > LIMIT_TIME) {
125 nanoTime = LIMIT_TIME;
126 }
127 ClockTime::AbsoluteSleep(nanoTime);
128 }
129
RelativeSleepFuzzTest()130 void RelativeSleepFuzzTest()
131 {
132 int64_t nanoTime = COMMON_INT64_NUM;
133 if (nanoTime > LIMIT_TIME) {
134 nanoTime = LIMIT_TIME;
135 }
136 ClockTime::RelativeSleep(nanoTime);
137 }
138
CountFuzzTest()139 void CountFuzzTest()
140 {
141 int64_t count = COMMON_INT64_NUM;
142 const std::string value = "value";
143 Trace::Count(value, count);
144 }
145
CountVolumeFuzzTest()146 void CountVolumeFuzzTest()
147 {
148 uint8_t data = GetData<uint8_t>();
149 const std::string value = "value";
150 Trace::CountVolume(value, data);
151 }
152
VerifySystemPermissionFuzzTest(const uint8_t * rawData,size_t size)153 bool VerifySystemPermissionFuzzTest(const uint8_t* rawData, size_t size)
154 {
155 if (rawData == nullptr || size < LIMITSIZE) {
156 return false;
157 }
158
159 return PermissionUtil::VerifySystemPermission();
160 }
161
VerifyPermissionFuzzTest(const uint8_t * rawData,size_t size)162 void VerifyPermissionFuzzTest(const uint8_t *rawData, size_t size)
163 {
164 if (rawData == nullptr || size < LIMITSIZE) {
165 return;
166 }
167 uint32_t tokenId = *reinterpret_cast<const uint32_t *>(rawData);
168 PermissionUtil::VerifyPermission(ACCESS_NOTIFICATION_POLICY_PERMISSION, tokenId);
169 }
170
VerifyIsShellFuzzTest(const uint8_t * rawData,size_t size)171 void VerifyIsShellFuzzTest(const uint8_t* rawData, size_t size)
172 {
173 if (rawData == nullptr || size < LIMITSIZE) {
174 return;
175 }
176
177 PermissionUtil::VerifyIsShell();
178 }
179
VerifyIsSystemAppFuzzTest(const uint8_t * rawData,size_t size)180 void VerifyIsSystemAppFuzzTest(const uint8_t* rawData, size_t size)
181 {
182 if (rawData == nullptr || size < LIMITSIZE) {
183 return;
184 }
185
186 PermissionUtil::VerifyIsSystemApp();
187 }
188
189
NeedVerifyBackgroundCaptureFuzzTest(const uint8_t * rawData,size_t size)190 void NeedVerifyBackgroundCaptureFuzzTest(const uint8_t *rawData, size_t size)
191 {
192 if (rawData == nullptr || size < LIMITSIZE) {
193 return;
194 }
195 int32_t callingUid = *(reinterpret_cast<const int32_t*>(rawData));
196 SourceType sourceType = *(reinterpret_cast<const SourceType*>(rawData));
197 PermissionUtil::NeedVerifyBackgroundCapture(callingUid, sourceType);
198 }
199
VerifyBackgroundCaptureFuzzTest(const uint8_t * rawData,size_t size)200 void VerifyBackgroundCaptureFuzzTest(const uint8_t* rawData, size_t size)
201 {
202 if (rawData == nullptr || size < LIMITSIZE) {
203 return;
204 }
205 uint32_t tokenId = *(reinterpret_cast<const uint32_t*>(rawData));
206 uint64_t fullTokenId = COMMON_UINT64_NUM;
207
208 PermissionUtil::VerifyBackgroundCapture(tokenId, fullTokenId);
209 }
210
NotifyPrivacyFuzzTest(const uint8_t * rawData,size_t size)211 void NotifyPrivacyFuzzTest(const uint8_t *rawData, size_t size)
212 {
213 if (rawData == nullptr || size < LIMITSIZE) {
214 return;
215 }
216 uint32_t targetTokenId = *(reinterpret_cast<const uint32_t*>(rawData));
217 PermissionUtil::NotifyPrivacyStart(targetTokenId, 0);
218 PermissionUtil::NotifyPrivacyStop(targetTokenId, 0);
219 }
220
GetTimeFuzzTest()221 void GetTimeFuzzTest()
222 {
223 GetTime();
224 }
225
AudioBlendFuzzTest()226 void AudioBlendFuzzTest()
227 {
228 std::shared_ptr<AudioBlend> audioBlend = nullptr;
229 audioBlend = std::make_shared<AudioBlend>();
230 uint32_t blendModeInt = GetData<uint32_t>();
231 blendModeInt = blendModeInt % ENUMSIZE;
232 ChannelBlendMode blendMode = static_cast<ChannelBlendMode>(blendModeInt);
233 uint8_t format = GetData<uint8_t>();
234 format = format % ENUMSIZE;
235 uint8_t channel = GetData<uint8_t>();
236 audioBlend->SetParams(blendMode, format, channel);
237 uint8_t *buffer = new uint8_t[LIMITSIZE];
238 memcpy_s(buffer, LIMITSIZE, RAW_DATA, LIMITSIZE);
239 audioBlend->Process(buffer, LIMITSIZE);
240 delete[] buffer;
241 }
242
VolumeRampFuzzTest()243 void VolumeRampFuzzTest()
244 {
245 std::shared_ptr<VolumeRamp> volumeRamp = nullptr;
246 volumeRamp = std::make_shared<VolumeRamp>();
247 float targetVolume = GetData<float>();
248 float currStreamVolume = GetData<float>();
249 int32_t duration = GetData<int32_t>();
250 volumeRamp->SetVolumeRampConfig(targetVolume, currStreamVolume, duration);
251 volumeRamp->GetRampVolume();
252 volumeRamp->IsActive();
253 volumeRamp->Terminate();
254 }
255
256 typedef void (*TestFuncs[7])();
257
258 TestFuncs g_testFuncs = {
259 AbsoluteSleepFuzzTest,
260 RelativeSleepFuzzTest,
261 CountFuzzTest,
262 CountVolumeFuzzTest,
263 GetTimeFuzzTest,
264 AudioBlendFuzzTest,
265 VolumeRampFuzzTest,
266 };
267
FuzzTest(const uint8_t * rawData,size_t size)268 bool FuzzTest(const uint8_t* rawData, size_t size)
269 {
270 if (rawData == nullptr) {
271 return false;
272 }
273
274 // initialize data
275 RAW_DATA = rawData;
276 g_dataSize = size;
277 g_pos = 0;
278
279 uint32_t code = GetData<uint32_t>();
280 uint32_t len = GetArrLength(g_testFuncs);
281 if (len > 0) {
282 g_testFuncs[code % len]();
283 } else {
284 AUDIO_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
285 }
286
287 return true;
288 }
289 } // namespace AudioStandard
290 } // namesapce OHOS
291
LLVMFuzzerInitialize(int * argc,char *** argv)292 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
293 {
294 OHOS::AudioStandard::AudioFuzzTestGetPermission();
295 return 0;
296 }
297
298 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)299 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
300 {
301 if (size < OHOS::AudioStandard::THRESHOLD) {
302 return 0;
303 }
304
305 OHOS::AudioStandard::FuzzTest(data, size);
306 return 0;
307 }
308