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