• 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 #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