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 "audio_common_converter.h"
20 #include "pro_renderer_stream_impl.h"
21 #include "securec.h"
22 #include "audio_service_log.h"
23 #include "audio_down_mix_stereo.h"
24 #include "audio_log_utils.h"
25 #include "audio_volume.h"
26 #include "format_converter.h"
27 #include "futex_tool.h"
28 using namespace std;
29
30 namespace OHOS {
31 namespace AudioStandard {
32 const int32_t FORMAT_COUNT = 5;
33 const int32_t VOLSTART_COUNT = 1;
34 const int64_t SILENT_COUNT = 1;
35 const int64_t SOUND_COUNT = -1;
36 const uint8_t BUFFER_CONSTANT = 1;
37 const uint32_t FRAMESIZE = 5;
38 const uint32_t FRAMESIZE_NEW = 1;
39 const size_t SIZE_FLOAT = 5;
40 const float FLOAT_BUFFER = 5.0f;
41 constexpr int32_t AUDIO_SAMPLE_FORMAT_8BIT = 0;
42 constexpr int32_t AUDIO_SAMPLE_FORMAT_16BIT = 1;
43 constexpr int32_t AUDIO_SAMPLE_FORMAT_24BIT = 2;
44 constexpr int32_t AUDIO_SAMPLE_FORMAT_32BIT = 3;
45 constexpr int32_t AUDIO_SAMPLE_FORMAT_32F_BIT = 4;
46 static const uint8_t *RAW_DATA = nullptr;
47 static size_t g_dataSize = 0;
48 static size_t g_pos;
49 const size_t THRESHOLD = 10;
50
51 /*
52 * describe: get data from outside untrusted data(RAW_DATA) which size is according to sizeof(T)
53 * tips: only support basic type
54 */
55 template<class T>
GetData()56 T GetData()
57 {
58 T object {};
59 size_t objectSize = sizeof(object);
60 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
61 return object;
62 }
63 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
64 if (ret != EOK) {
65 return {};
66 }
67 g_pos += objectSize;
68 return object;
69 }
70
71 template<class T>
GetArrLength(T & arr)72 uint32_t GetArrLength(T& arr)
73 {
74 if (arr == nullptr) {
75 AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
76 return 0;
77 }
78 return sizeof(arr) / sizeof(arr[0]);
79 }
80
AudioCommonConverterFuzzTest()81 void AudioCommonConverterFuzzTest()
82 {
83 BufferBaseInfo srcBuffer;
84 srcBuffer.frameSize = FRAMESIZE;
85 size_t floatBufferSize = SIZE_FLOAT;
86 std::vector<float> floatBuffer(floatBufferSize, FLOAT_BUFFER);
87 AudioCommonConverter::ConvertBufferToFloat(srcBuffer, floatBuffer);
88 AudioCommonConverter::ConvertFloatToFloatWithVolume(srcBuffer, floatBuffer);
89
90 BufferBaseInfo srcBufferTo;
91 srcBufferTo.frameSize = FRAMESIZE_NEW;
92 std::vector<char> dstBuffer32Bit{'0', '0', '0', '0'};
93 std::vector<char> dstBuffer16Bit{'0', '0'};
94
95 std::vector<int32_t> formatVec = {
96 AUDIO_SAMPLE_FORMAT_8BIT,
97 AUDIO_SAMPLE_FORMAT_16BIT,
98 AUDIO_SAMPLE_FORMAT_24BIT,
99 AUDIO_SAMPLE_FORMAT_32BIT,
100 AUDIO_SAMPLE_FORMAT_32F_BIT,
101 FORMAT_COUNT,
102 };
103 int32_t formatInt = GetData<int32_t>() % formatVec.size();
104 srcBufferTo.format = formatVec[formatInt];
105 AudioCommonConverter::ConvertBufferTo32Bit(srcBufferTo, dstBuffer32Bit);
106 AudioCommonConverter::ConvertBufferTo16Bit(srcBufferTo, dstBuffer16Bit);
107 }
108
AudioDownMixStereoFuzzTest()109 void AudioDownMixStereoFuzzTest()
110 {
111 std::shared_ptr<AudioDownMixStereo> audioDownMixStereo = std::make_shared<AudioDownMixStereo>();
112
113 AudioChannelLayout mode = GetData<AudioChannelLayout>();
114 int32_t channels = GetData<int32_t>();
115 audioDownMixStereo->InitMixer(mode, channels);
116
117 int32_t frameLength = GetData<int32_t>();
118 float *input = GetData<float*>();
119 float *output = GetData<float*>();
120 audioDownMixStereo->Apply(frameLength, input, output);
121 }
122
AudioLogUtilsFuzzTest()123 void AudioLogUtilsFuzzTest()
124 {
125 std::string logTag = "logTag";
126 ChannelVolumes vols;
127 int64_t countSilent = SILENT_COUNT;
128 AudioLogUtils::ProcessVolumeData(logTag, vols, countSilent);
129
130 ChannelVolumes volumes;
131 volumes.volStart[0] = VOLSTART_COUNT;
132 int64_t countSound = SOUND_COUNT;
133 AudioLogUtils::ProcessVolumeData(logTag, volumes, countSound);
134 }
135
AudioVolumeFuzzTest()136 void AudioVolumeFuzzTest()
137 {
138 std::shared_ptr<AudioVolume> audioVolume = std::make_shared<AudioVolume>();
139 uint32_t sessionId = GetData<uint32_t>();
140 audioVolume->GetHistoryVolume(sessionId);
141
142 float volume = GetData<float>();
143 audioVolume->SetHistoryVolume(sessionId, volume);
144 audioVolume->SetStreamVolumeDuckFactor(sessionId, volume);
145 audioVolume->SetStreamVolumeLowPowerFactor(sessionId, volume);
146 audioVolume->GetStreamVolumeFade(sessionId);
147 audioVolume->SetStreamVolumeFade(sessionId, volume, volume);
148
149 int32_t volumeType = GetData<int32_t>();
150 int32_t volumeLevel = GetData<int32_t>();
151 std::string deviceClass = "primary";
152 audioVolume->SetSystemVolume(volumeType, deviceClass, volume, volumeLevel);
153 audioVolume->SetSystemVolumeMute(volumeType, deviceClass, true);
154
155 std::string streamType = "streamType";
156 audioVolume->ConvertStreamTypeStrToInt(streamType);
157
158 float x = GetData<float>();
159 float y = GetData<float>();
160 audioVolume->IsSameVolume(x, y);
161
162 std::string dumpString = "dumpString";
163 audioVolume->Dump(dumpString);
164 }
165
AudioFormatConverterFuzzTest()166 void AudioFormatConverterFuzzTest()
167 {
168 BufferDesc srcDesc;
169 uint8_t srcBuffer[4] = {0};
170 srcBuffer[0] = BUFFER_CONSTANT;
171 srcDesc.buffer = srcBuffer;
172 BufferDesc dstDesc;
173 uint8_t dstBuffer[4] = {0};
174 dstBuffer[0] = BUFFER_CONSTANT;
175 dstDesc.buffer = dstBuffer;
176 FormatConverter::S16MonoToS16Stereo(srcDesc, dstDesc);
177 FormatConverter::S16StereoToS16Mono(srcDesc, dstDesc);
178 }
179
180 typedef void (*TestFuncs[5])();
181
182 TestFuncs g_testFuncs = {
183 AudioCommonConverterFuzzTest,
184 AudioDownMixStereoFuzzTest,
185 AudioLogUtilsFuzzTest,
186 AudioVolumeFuzzTest,
187 AudioFormatConverterFuzzTest,
188 };
189
FuzzTest(const uint8_t * rawData,size_t size)190 bool FuzzTest(const uint8_t* rawData, size_t size)
191 {
192 if (rawData == nullptr) {
193 return false;
194 }
195
196 // initialize data
197 RAW_DATA = rawData;
198 g_dataSize = size;
199 g_pos = 0;
200
201 uint32_t code = GetData<uint32_t>();
202 uint32_t len = GetArrLength(g_testFuncs);
203 if (len > 0) {
204 g_testFuncs[code % len]();
205 } else {
206 AUDIO_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
207 }
208
209 return true;
210 }
211 } // namespace AudioStandard
212 } // namesapce OHOS
213
214 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)215 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
216 {
217 if (size < OHOS::AudioStandard::THRESHOLD) {
218 return 0;
219 }
220
221 OHOS::AudioStandard::FuzzTest(data, size);
222 return 0;
223 }
224