1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "libaudioprocessing_fuzz_utils.h"
18 #include "fuzzer/FuzzedDataProvider.h"
19 #include <media/AudioResampler.h>
20 #include <media/RecordBufferConverter.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 using namespace android;
25 
26 constexpr int MAX_FRAMES = 1024;
27 
28 #define AUDIO_FORMAT_PCM_MAIN 0
29 
30 // Copied and simplified from audio-hal-enums.h?l=571
31 constexpr uint32_t FUZZ_AUDIO_FORMATS[] = {
32   AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_16_BIT,
33   AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_8_BIT,
34   AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_32_BIT,
35   AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_8_24_BIT,
36   AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_FLOAT,
37   AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED,
38   0x01000000u,
39   0x02000000u,
40   0x03000000u,
41   0x04000000u,
42   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_MAIN,
43   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_LC,
44   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_SSR,
45   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_LTP,
46   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_HE_V1,
47   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_SCALABLE,
48   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_ERLC,
49   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_LD,
50   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_HE_V2,
51   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_ELD,
52   AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_XHE,
53   0x05000000u,
54   0x06000000u,
55   0x07000000u,
56   0x08000000u,
57   0x09000000u,
58   0x0A000000u,
59   AUDIO_FORMAT_E_AC3 | AUDIO_FORMAT_E_AC3_SUB_JOC,
60   0x0B000000u,
61   0x0C000000u,
62   0x0D000000u,
63   0x0E000000u,
64   0x10000000u,
65   0x11000000u,
66   0x12000000u,
67   0x13000000u,
68   0x14000000u,
69   0x15000000u,
70   0x16000000u,
71   0x17000000u,
72   0x18000000u,
73   0x19000000u,
74   0x1A000000u,
75   0x1B000000u,
76   0x1C000000u,
77   0x1D000000u,
78   0x1E000000u,
79   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_MAIN,
80   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_LC,
81   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_SSR,
82   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_LTP,
83   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_HE_V1,
84   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_SCALABLE,
85   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_ERLC,
86   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_LD,
87   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_HE_V2,
88   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_ELD,
89   AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_XHE,
90   0x1F000000u,
91   0x20000000u,
92   0x21000000u,
93   0x22000000u,
94   0x23000000u,
95   0x24000000u,
96   AUDIO_FORMAT_MAT | AUDIO_FORMAT_MAT_SUB_1_0,
97   AUDIO_FORMAT_MAT | AUDIO_FORMAT_MAT_SUB_2_0,
98   AUDIO_FORMAT_MAT | AUDIO_FORMAT_MAT_SUB_2_1,
99   0x25000000u,
100   AUDIO_FORMAT_AAC_LATM | AUDIO_FORMAT_AAC_SUB_LC,
101   AUDIO_FORMAT_AAC_LATM | AUDIO_FORMAT_AAC_SUB_HE_V1,
102   AUDIO_FORMAT_AAC_LATM | AUDIO_FORMAT_AAC_SUB_HE_V2,
103   0x26000000u,
104   0x27000000u,
105   0x28000000u,
106   0x29000000u,
107   0x2A000000u,
108   0x2B000000u,
109   0xFFFFFFFFu,
110   AUDIO_FORMAT_PCM_MAIN,
111   AUDIO_FORMAT_PCM,
112 };
113 constexpr size_t NUM_AUDIO_FORMATS = std::size(FUZZ_AUDIO_FORMATS);
114 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)115 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
116   FuzzedDataProvider fdp(data, size);
117   fdp.ConsumeIntegral<int>();
118 
119   const audio_channel_mask_t srcChannelMask = (audio_channel_mask_t)fdp.ConsumeIntegral<int>();
120   const audio_format_t srcFormat =
121       (audio_format_t)FUZZ_AUDIO_FORMATS[fdp.ConsumeIntegralInRange<int>(0, NUM_AUDIO_FORMATS - 1)];
122   const uint32_t srcSampleRate = fdp.ConsumeIntegralInRange<int>(1, 0x7fffffff);
123   const audio_channel_mask_t dstChannelMask = (audio_channel_mask_t)fdp.ConsumeIntegral<int>();
124   const audio_format_t dstFormat =
125       (audio_format_t)FUZZ_AUDIO_FORMATS[fdp.ConsumeIntegralInRange<int>(0, NUM_AUDIO_FORMATS - 1)];
126   const uint32_t dstSampleRate = fdp.ConsumeIntegralInRange<int>(1, 0x7fffffff);
127 
128   // Certain formats will result in LOG_ALWAYS_FATAL errors that aren't interesting crashes
129   // for fuzzing.  Don't use those ones.
130   const uint32_t dstChannelCount = audio_channel_count_from_in_mask(dstChannelMask);
131   constexpr android::AudioResampler::src_quality quality =
132       android::AudioResampler::DEFAULT_QUALITY;
133   const int maxChannels =
134       quality < android::AudioResampler::DYN_LOW_QUALITY ? 2 : 8;
135   if (dstChannelCount < 1 || dstChannelCount > maxChannels) {
136     return 0;
137   }
138 
139   const uint32_t srcChannelCount = audio_channel_count_from_in_mask(srcChannelMask);
140   if (srcChannelCount < 1 || srcChannelCount > maxChannels) {
141     return 0;
142   }
143 
144   RecordBufferConverter converter(srcChannelMask, srcFormat, srcSampleRate,
145                                   dstChannelMask, dstFormat, dstSampleRate);
146   if (converter.initCheck() != NO_ERROR) {
147     return 0;
148   }
149 
150   const uint32_t srcFrameSize = srcChannelCount * audio_bytes_per_sample(srcFormat);
151   const int srcNumFrames = fdp.ConsumeIntegralInRange<int>(0, MAX_FRAMES);
152   constexpr size_t metadataSize = 2 + 3 * sizeof(int) + 2 * sizeof(float);
153   std::vector<uint8_t> inputData = fdp.ConsumeBytes<uint8_t>(
154       metadataSize + (srcFrameSize * srcNumFrames));
155   Provider provider(inputData.data(), srcNumFrames, srcFrameSize);
156 
157   const uint32_t dstFrameSize = dstChannelCount * audio_bytes_per_sample(dstFormat);
158   const size_t frames = fdp.ConsumeIntegralInRange<size_t>(0, MAX_FRAMES + 1);
159   int8_t dst[dstFrameSize * frames];
160   memset(dst, 0, sizeof(int8_t) * dstFrameSize * frames);
161 
162   // Add a small number of loops to see if repeated calls to convert cause
163   // any change in behavior.
164   const int numLoops = fdp.ConsumeIntegralInRange<int>(1, 3);
165   for (int loop = 0; loop < numLoops; ++loop) {
166     switch (fdp.ConsumeIntegralInRange<int>(0, 1)) {
167       case 0:
168         converter.reset();
169         FALLTHROUGH_INTENDED;
170       case 1:
171         converter.convert(dst, &provider, frames);
172         break;
173     }
174   }
175 
176   return 0;
177 }
178