1 /*
2 * Copyright (C) 2021 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
18 #include "aaudio/AAudio.h"
19 #include "aaudio/AAudioTesting.h"
20 #include "system/aaudio/AAudio.h"
21 #include <fuzzer/FuzzedDataProvider.h>
22
23 #include <functional>
24
25 constexpr int32_t kRandomStringLength = 256;
26 constexpr int32_t kMaxRuns = 100;
27 constexpr int64_t kNanosPerMillisecond = 1000 * 1000;
28 constexpr int32_t kAAudioAttributesTagsMaxSize = 256;
29
30 constexpr aaudio_direction_t kDirections[] = {
31 AAUDIO_DIRECTION_OUTPUT, AAUDIO_DIRECTION_INPUT, AAUDIO_UNSPECIFIED};
32
33 constexpr aaudio_performance_mode_t kPerformanceModes[] = {
34 AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_PERFORMANCE_MODE_POWER_SAVING,
35 AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_UNSPECIFIED};
36
37 constexpr aaudio_format_t kFormats[] = {
38 AAUDIO_FORMAT_INVALID, AAUDIO_FORMAT_UNSPECIFIED,
39 AAUDIO_FORMAT_PCM_I16, AAUDIO_FORMAT_PCM_FLOAT,
40 AAUDIO_FORMAT_PCM_I24_PACKED, AAUDIO_FORMAT_PCM_I32};
41
42 constexpr aaudio_sharing_mode_t kSharingModes[] = {
43 AAUDIO_SHARING_MODE_EXCLUSIVE, AAUDIO_SHARING_MODE_SHARED};
44
45 constexpr int32_t kSampleRates[] = {AAUDIO_UNSPECIFIED,
46 8000,
47 11025,
48 16000,
49 22050,
50 32000,
51 44100,
52 48000,
53 88200,
54 96000};
55
56 constexpr aaudio_usage_t kUsages[] = {
57 AAUDIO_USAGE_MEDIA,
58 AAUDIO_USAGE_VOICE_COMMUNICATION,
59 AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
60 AAUDIO_USAGE_ALARM,
61 AAUDIO_USAGE_NOTIFICATION,
62 AAUDIO_USAGE_NOTIFICATION_RINGTONE,
63 AAUDIO_USAGE_NOTIFICATION_EVENT,
64 AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY,
65 AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
66 AAUDIO_USAGE_ASSISTANCE_SONIFICATION,
67 AAUDIO_USAGE_GAME,
68 AAUDIO_USAGE_ASSISTANT,
69 AAUDIO_SYSTEM_USAGE_EMERGENCY,
70 AAUDIO_SYSTEM_USAGE_SAFETY,
71 AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS,
72 AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT,
73 AAUDIO_UNSPECIFIED};
74
75 constexpr aaudio_content_type_t kContentTypes[] = {
76 AAUDIO_CONTENT_TYPE_SPEECH, AAUDIO_CONTENT_TYPE_MUSIC,
77 AAUDIO_CONTENT_TYPE_MOVIE, AAUDIO_CONTENT_TYPE_SONIFICATION,
78 AAUDIO_UNSPECIFIED};
79
80 constexpr aaudio_input_preset_t kInputPresets[] = {
81 AAUDIO_INPUT_PRESET_GENERIC,
82 AAUDIO_INPUT_PRESET_CAMCORDER,
83 AAUDIO_INPUT_PRESET_VOICE_RECOGNITION,
84 AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION,
85 AAUDIO_INPUT_PRESET_UNPROCESSED,
86 AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE,
87 AAUDIO_UNSPECIFIED};
88
89 constexpr aaudio_allowed_capture_policy_t kAllowedCapturePolicies[] = {
90 AAUDIO_ALLOW_CAPTURE_BY_ALL, AAUDIO_ALLOW_CAPTURE_BY_SYSTEM,
91 AAUDIO_ALLOW_CAPTURE_BY_NONE, AAUDIO_UNSPECIFIED};
92
93 constexpr aaudio_session_id_t kSessionIds[] = {
94 AAUDIO_SESSION_ID_NONE, AAUDIO_SESSION_ID_ALLOCATE, AAUDIO_UNSPECIFIED};
95
96 constexpr aaudio_policy_t kPolicies[] = {
97 AAUDIO_POLICY_NEVER, AAUDIO_POLICY_AUTO, AAUDIO_POLICY_ALWAYS,
98 AAUDIO_UNSPECIFIED};
99
100 class LibAaudioFuzzer {
101 public:
~LibAaudioFuzzer()102 ~LibAaudioFuzzer() { deInit(); }
103 bool init();
104 void invokeAAudioSetAPIs(FuzzedDataProvider &fdp);
105 void process(const uint8_t *data, size_t size);
106 void deInit();
107
108 private:
109 AAudioStreamBuilder *mAaudioBuilder = nullptr;
110 AAudioStream *mAaudioStream = nullptr;
111 };
112
init()113 bool LibAaudioFuzzer::init() {
114 aaudio_result_t result = AAudio_createStreamBuilder(&mAaudioBuilder);
115 if ((result != AAUDIO_OK) || (!mAaudioBuilder)) {
116 return false;
117 }
118 return true;
119 }
120
invokeAAudioSetAPIs(FuzzedDataProvider & fdp)121 void LibAaudioFuzzer::invokeAAudioSetAPIs(FuzzedDataProvider &fdp){
122 aaudio_performance_mode_t mode = fdp.PickValueInArray(
123 {fdp.PickValueInArray(kPerformanceModes), fdp.ConsumeIntegral<int32_t>()});
124 AAudioStreamBuilder_setPerformanceMode(mAaudioBuilder, mode);
125
126 int32_t deviceId = fdp.PickValueInArray({AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
127 AAudioStreamBuilder_setDeviceId(mAaudioBuilder, deviceId);
128
129 std::string packageName =
130 fdp.PickValueInArray<std::string>({"android.nativemedia.aaudio", "android.app.appops.cts",
131 fdp.ConsumeRandomLengthString(kRandomStringLength)});
132 AAudioStreamBuilder_setPackageName(mAaudioBuilder, packageName.c_str());
133
134 std::string attributionTag = fdp.ConsumeRandomLengthString(kRandomStringLength);
135 AAudioStreamBuilder_setAttributionTag(mAaudioBuilder, attributionTag.c_str());
136
137 int32_t sampleRate = fdp.PickValueInArray(kSampleRates);
138 AAudioStreamBuilder_setSampleRate(mAaudioBuilder, sampleRate);
139
140 int32_t channelCount = fdp.PickValueInArray({AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
141 AAudioStreamBuilder_setChannelCount(mAaudioBuilder, channelCount);
142
143 aaudio_direction_t direction =
144 fdp.PickValueInArray({fdp.PickValueInArray(kDirections), fdp.ConsumeIntegral<int32_t>()});
145 AAudioStreamBuilder_setDirection(mAaudioBuilder, direction);
146
147 aaudio_format_t format =
148 fdp.PickValueInArray({fdp.PickValueInArray(kFormats), fdp.ConsumeIntegral<int32_t>()});
149 AAudioStreamBuilder_setFormat(mAaudioBuilder, format);
150
151 aaudio_sharing_mode_t sharingMode = fdp.PickValueInArray(
152 {fdp.PickValueInArray(kSharingModes), fdp.ConsumeIntegral<int32_t>()});
153 AAudioStreamBuilder_setSharingMode(mAaudioBuilder, sharingMode);
154
155 aaudio_usage_t usage =
156 fdp.PickValueInArray({fdp.PickValueInArray(kUsages), fdp.ConsumeIntegral<int32_t>()});
157 AAudioStreamBuilder_setUsage(mAaudioBuilder, usage);
158
159 aaudio_content_type_t contentType = fdp.PickValueInArray(
160 {fdp.PickValueInArray(kContentTypes), fdp.ConsumeIntegral<int32_t>()});
161 AAudioStreamBuilder_setContentType(mAaudioBuilder, contentType);
162
163 aaudio_input_preset_t inputPreset = fdp.PickValueInArray(
164 {fdp.PickValueInArray(kInputPresets), fdp.ConsumeIntegral<int32_t>()});
165 AAudioStreamBuilder_setInputPreset(mAaudioBuilder, inputPreset);
166
167 bool privacySensitive = fdp.ConsumeBool();
168 AAudioStreamBuilder_setPrivacySensitive(mAaudioBuilder, privacySensitive);
169
170 int32_t frames = fdp.PickValueInArray({AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
171 AAudioStreamBuilder_setBufferCapacityInFrames(mAaudioBuilder, frames);
172
173 aaudio_allowed_capture_policy_t allowedCapturePolicy = fdp.PickValueInArray(
174 {fdp.PickValueInArray(kAllowedCapturePolicies), fdp.ConsumeIntegral<int32_t>()});
175 AAudioStreamBuilder_setAllowedCapturePolicy(mAaudioBuilder, allowedCapturePolicy);
176
177 aaudio_session_id_t sessionId =
178 fdp.PickValueInArray({fdp.PickValueInArray(kSessionIds), fdp.ConsumeIntegral<int32_t>()});
179 AAudioStreamBuilder_setSessionId(mAaudioBuilder, sessionId);
180
181 AAudioStreamBuilder_setDataCallback(mAaudioBuilder, nullptr, nullptr);
182 AAudioStreamBuilder_setErrorCallback(mAaudioBuilder, nullptr, nullptr);
183
184 int32_t framesPerDataCallback =
185 fdp.PickValueInArray({AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
186 AAudioStreamBuilder_setFramesPerDataCallback(mAaudioBuilder, framesPerDataCallback);
187
188 const size_t tagsNumBytes = fdp.ConsumeIntegralInRange<size_t>(
189 0, kAAudioAttributesTagsMaxSize + 10);
190 AAudioStreamBuilder_addTag(mAaudioBuilder,
191 (tagsNumBytes == 0 ? nullptr
192 : fdp.ConsumeBytesAsString(tagsNumBytes).c_str()));
193
194 aaudio_policy_t policy =
195 fdp.PickValueInArray({fdp.PickValueInArray(kPolicies), fdp.ConsumeIntegral<int32_t>()});
196 AAudio_setMMapPolicy(policy);
197 }
198
process(const uint8_t * data,size_t size)199 void LibAaudioFuzzer::process(const uint8_t *data, size_t size) {
200 FuzzedDataProvider fdp(data, size);
201 int32_t maxFrames = 0;
202 int32_t count = 0;
203 aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
204 int numOfTags = 0;
205
206 invokeAAudioSetAPIs(fdp);
207
208 aaudio_result_t result = AAudioStreamBuilder_openStream(mAaudioBuilder, &mAaudioStream);
209 if ((result != AAUDIO_OK) || (!mAaudioStream)) {
210 return;
211 }
212 /* The 'runs' variable serves to set an upper limit on the loop iterations, preventing excessive
213 * execution.
214 */
215 int32_t runs = kMaxRuns;
216 while (fdp.remaining_bytes() > 0 && --runs) {
217 auto AAudioapi = fdp.PickValueInArray<const std::function<void()>>({
218 [&]() { (void)AAudio_getMMapPolicy(); },
219
220 [&]() {
221 int32_t framesPerBurst = AAudioStream_getFramesPerBurst(mAaudioStream);
222 uint8_t numberOfBursts = fdp.ConsumeIntegral<uint8_t>();
223 maxFrames = numberOfBursts * framesPerBurst;
224 int32_t requestedBufferSize = fdp.ConsumeIntegral<uint16_t>() * framesPerBurst;
225 AAudioStream_setBufferSizeInFrames(mAaudioStream, requestedBufferSize);
226 },
227 [&]() {
228 int64_t position = 0, nanoseconds = 0;
229 AAudioStream_getTimestamp(mAaudioStream, CLOCK_MONOTONIC, &position, &nanoseconds);
230 },
231 [&]() {
232 AAudioStream_requestStart(mAaudioStream);
233 },
234 [&]() {
235 AAudioStream_requestPause(mAaudioStream);
236 },
237 [&]() {
238 AAudioStream_requestFlush(mAaudioStream);
239 },
240 [&]() {
241 AAudioStream_requestStop(mAaudioStream);
242 },
243 [&]() {
244 aaudio_format_t actualFormat = AAudioStream_getFormat(mAaudioStream);
245 int32_t actualChannelCount = AAudioStream_getChannelCount(mAaudioStream);
246
247 count = fdp.ConsumeIntegral<int32_t>();
248 aaudio_direction_t direction = AAudioStream_getDirection(mAaudioStream);
249
250 if (actualFormat == AAUDIO_FORMAT_PCM_I16) {
251 std::vector<int16_t> inputShortData(maxFrames * actualChannelCount, 0x0);
252 if (direction == AAUDIO_DIRECTION_INPUT) {
253 AAudioStream_read(mAaudioStream, inputShortData.data(), maxFrames,
254 count * kNanosPerMillisecond);
255 } else if (direction == AAUDIO_DIRECTION_OUTPUT) {
256 AAudioStream_write(mAaudioStream, inputShortData.data(), maxFrames,
257 count * kNanosPerMillisecond);
258 }
259 } else if (actualFormat == AAUDIO_FORMAT_PCM_FLOAT) {
260 std::vector<float> inputFloatData(maxFrames * actualChannelCount, 0x0);
261 if (direction == AAUDIO_DIRECTION_INPUT) {
262 AAudioStream_read(mAaudioStream, inputFloatData.data(), maxFrames,
263 count * kNanosPerMillisecond);
264 } else if (direction == AAUDIO_DIRECTION_OUTPUT) {
265 AAudioStream_write(mAaudioStream, inputFloatData.data(), maxFrames,
266 count * kNanosPerMillisecond);
267 }
268 }
269 },
270 [&]() {
271 AAudioStream_waitForStateChange(mAaudioStream, AAUDIO_STREAM_STATE_UNKNOWN, &state,
272 count * kNanosPerMillisecond);
273 },
274 [&]() { (void)AAudio_convertStreamStateToText(state); },
275 [&]() {
276 (void)AAudioStream_getState(mAaudioStream);
277 },
278 [&]() {
279 (void)AAudioStream_getUsage(mAaudioStream);
280 },
281 [&]() {
282 (void)AAudioStream_getSamplesPerFrame(mAaudioStream);
283 },
284 [&]() {
285 (void)AAudioStream_getContentType(mAaudioStream);
286 },
287 [&]() {
288 (void)AAudioStream_getInputPreset(mAaudioStream);
289 },
290 [&]() {
291 (void)AAudioStream_isPrivacySensitive(mAaudioStream);
292 },
293 [&]() {
294 (void)AAudioStream_getAllowedCapturePolicy(mAaudioStream);
295 },
296 [&]() {
297 (void)AAudioStream_getPerformanceMode(mAaudioStream);
298 },
299 [&]() {
300 (void)AAudioStream_getDeviceId(mAaudioStream);
301 },
302 [&]() {
303 (void)AAudioStream_getSharingMode(mAaudioStream);
304 },
305 [&]() {
306 (void)AAudioStream_getSessionId(mAaudioStream);
307 },
308 [&]() {
309 (void)AAudioStream_getFramesRead(mAaudioStream);
310 },
311 [&]() {
312 (void)AAudioStream_getXRunCount(mAaudioStream);
313 },
314 [&]() {
315 (void)AAudioStream_getFramesWritten(mAaudioStream);
316 },
317 [&]() {
318 (void)AAudioStream_getBufferCapacityInFrames(mAaudioStream);
319 },
320 [&]() {
321 (void)AAudioStream_getBufferSizeInFrames(mAaudioStream);
322 },
323 [&]() {
324 char** tags = nullptr;
325 (void)AAudioStream_obtainTags(mAaudioStream, &tags);
326 AAudioStream_releaseTags(mAaudioStream, tags);
327 },
328 [&]() {
329 (void)AAudioStream_isMMapUsed(mAaudioStream);
330 },
331 });
332 AAudioapi();
333 }
334 AAudioStream_release(mAaudioStream);
335 }
336
deInit()337 void LibAaudioFuzzer::deInit() {
338 if (mAaudioBuilder) {
339 AAudioStreamBuilder_delete(mAaudioBuilder);
340 }
341 if (mAaudioStream) {
342 AAudioStream_close(mAaudioStream);
343 }
344 }
345
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)346 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
347 LibAaudioFuzzer libAaudioFuzzer;
348 if (libAaudioFuzzer.init()) {
349 libAaudioFuzzer.process(data, size);
350 }
351 return 0;
352 }
353