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 <fuzzer/FuzzedDataProvider.h>
21
22 constexpr int32_t kRandomStringLength = 256;
23
24 constexpr int64_t kNanosPerMillisecond = 1000 * 1000;
25
26 constexpr aaudio_direction_t kDirections[] = {
27 AAUDIO_DIRECTION_OUTPUT, AAUDIO_DIRECTION_INPUT, AAUDIO_UNSPECIFIED};
28
29 constexpr aaudio_performance_mode_t kPerformanceModes[] = {
30 AAUDIO_PERFORMANCE_MODE_NONE, AAUDIO_PERFORMANCE_MODE_POWER_SAVING,
31 AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAUDIO_UNSPECIFIED};
32
33 constexpr aaudio_format_t kFormats[] = {
34 AAUDIO_FORMAT_INVALID, AAUDIO_FORMAT_UNSPECIFIED,
35 AAUDIO_FORMAT_PCM_I16, AAUDIO_FORMAT_PCM_FLOAT,
36 AAUDIO_FORMAT_PCM_I24_PACKED, AAUDIO_FORMAT_PCM_I32};
37
38 constexpr aaudio_sharing_mode_t kSharingModes[] = {
39 AAUDIO_SHARING_MODE_EXCLUSIVE, AAUDIO_SHARING_MODE_SHARED};
40
41 constexpr int32_t kSampleRates[] = {AAUDIO_UNSPECIFIED,
42 8000,
43 11025,
44 16000,
45 22050,
46 32000,
47 44100,
48 48000,
49 88200,
50 96000};
51
52 constexpr aaudio_usage_t kUsages[] = {
53 AAUDIO_USAGE_MEDIA,
54 AAUDIO_USAGE_VOICE_COMMUNICATION,
55 AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
56 AAUDIO_USAGE_ALARM,
57 AAUDIO_USAGE_NOTIFICATION,
58 AAUDIO_USAGE_NOTIFICATION_RINGTONE,
59 AAUDIO_USAGE_NOTIFICATION_EVENT,
60 AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY,
61 AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
62 AAUDIO_USAGE_ASSISTANCE_SONIFICATION,
63 AAUDIO_USAGE_GAME,
64 AAUDIO_USAGE_ASSISTANT,
65 AAUDIO_SYSTEM_USAGE_EMERGENCY,
66 AAUDIO_SYSTEM_USAGE_SAFETY,
67 AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS,
68 AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT,
69 AAUDIO_UNSPECIFIED};
70
71 constexpr aaudio_content_type_t kContentTypes[] = {
72 AAUDIO_CONTENT_TYPE_SPEECH, AAUDIO_CONTENT_TYPE_MUSIC,
73 AAUDIO_CONTENT_TYPE_MOVIE, AAUDIO_CONTENT_TYPE_SONIFICATION,
74 AAUDIO_UNSPECIFIED};
75
76 constexpr aaudio_input_preset_t kInputPresets[] = {
77 AAUDIO_INPUT_PRESET_GENERIC,
78 AAUDIO_INPUT_PRESET_CAMCORDER,
79 AAUDIO_INPUT_PRESET_VOICE_RECOGNITION,
80 AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION,
81 AAUDIO_INPUT_PRESET_UNPROCESSED,
82 AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE,
83 AAUDIO_UNSPECIFIED};
84
85 constexpr aaudio_allowed_capture_policy_t kAllowedCapturePolicies[] = {
86 AAUDIO_ALLOW_CAPTURE_BY_ALL, AAUDIO_ALLOW_CAPTURE_BY_SYSTEM,
87 AAUDIO_ALLOW_CAPTURE_BY_NONE, AAUDIO_UNSPECIFIED};
88
89 constexpr aaudio_session_id_t kSessionIds[] = {
90 AAUDIO_SESSION_ID_NONE, AAUDIO_SESSION_ID_ALLOCATE, AAUDIO_UNSPECIFIED};
91
92 constexpr aaudio_policy_t kPolicies[] = {
93 AAUDIO_POLICY_NEVER, AAUDIO_POLICY_AUTO, AAUDIO_POLICY_ALWAYS,
94 AAUDIO_UNSPECIFIED};
95
96 class LibAaudioFuzzer {
97 public:
~LibAaudioFuzzer()98 ~LibAaudioFuzzer() { deInit(); }
99 bool init();
100 void process(const uint8_t *data, size_t size);
101 void deInit();
102
103 private:
104 AAudioStreamBuilder *mAaudioBuilder = nullptr;
105 AAudioStream *mAaudioStream = nullptr;
106 };
107
init()108 bool LibAaudioFuzzer::init() {
109 aaudio_result_t result = AAudio_createStreamBuilder(&mAaudioBuilder);
110 if ((result != AAUDIO_OK) || (!mAaudioBuilder)) {
111 return false;
112 }
113 return true;
114 }
115
process(const uint8_t * data,size_t size)116 void LibAaudioFuzzer::process(const uint8_t *data, size_t size) {
117 FuzzedDataProvider fdp(data, size);
118 aaudio_performance_mode_t mode =
119 fdp.PickValueInArray({fdp.PickValueInArray(kPerformanceModes),
120 fdp.ConsumeIntegral<int32_t>()});
121 AAudioStreamBuilder_setPerformanceMode(mAaudioBuilder, mode);
122
123 int32_t deviceId = fdp.PickValueInArray(
124 {AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
125 AAudioStreamBuilder_setDeviceId(mAaudioBuilder, deviceId);
126
127 std::string packageName = fdp.PickValueInArray<std::string>(
128 {"android.nativemedia.aaudio", "android.app.appops.cts",
129 fdp.ConsumeRandomLengthString(kRandomStringLength)});
130 AAudioStreamBuilder_setPackageName(mAaudioBuilder, packageName.c_str());
131
132 std::string attributionTag =
133 fdp.ConsumeRandomLengthString(kRandomStringLength);
134 AAudioStreamBuilder_setAttributionTag(mAaudioBuilder, attributionTag.c_str());
135
136 int32_t sampleRate = fdp.PickValueInArray(kSampleRates);
137 AAudioStreamBuilder_setSampleRate(mAaudioBuilder, sampleRate);
138
139 int32_t channelCount = fdp.PickValueInArray(
140 {AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
141 AAudioStreamBuilder_setChannelCount(mAaudioBuilder, channelCount);
142
143 aaudio_direction_t direction = fdp.PickValueInArray(
144 {fdp.PickValueInArray(kDirections), fdp.ConsumeIntegral<int32_t>()});
145 AAudioStreamBuilder_setDirection(mAaudioBuilder, direction);
146
147 aaudio_format_t format = fdp.PickValueInArray(
148 {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 = fdp.PickValueInArray(
156 {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(
171 {AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
172 AAudioStreamBuilder_setBufferCapacityInFrames(mAaudioBuilder, frames);
173
174 aaudio_allowed_capture_policy_t allowedCapturePolicy =
175 fdp.PickValueInArray({fdp.PickValueInArray(kAllowedCapturePolicies),
176 fdp.ConsumeIntegral<int32_t>()});
177 AAudioStreamBuilder_setAllowedCapturePolicy(mAaudioBuilder,
178 allowedCapturePolicy);
179
180 aaudio_session_id_t sessionId = fdp.PickValueInArray(
181 {fdp.PickValueInArray(kSessionIds), fdp.ConsumeIntegral<int32_t>()});
182 AAudioStreamBuilder_setSessionId(mAaudioBuilder, sessionId);
183
184 AAudioStreamBuilder_setDataCallback(mAaudioBuilder, nullptr, nullptr);
185 AAudioStreamBuilder_setErrorCallback(mAaudioBuilder, nullptr, nullptr);
186
187 int32_t framesPerDataCallback = fdp.PickValueInArray(
188 {AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
189 AAudioStreamBuilder_setFramesPerDataCallback(mAaudioBuilder,
190 framesPerDataCallback);
191
192 aaudio_policy_t policy = fdp.PickValueInArray(
193 {fdp.PickValueInArray(kPolicies), fdp.ConsumeIntegral<int32_t>()});
194 AAudio_setMMapPolicy(policy);
195 (void)AAudio_getMMapPolicy();
196
197 aaudio_result_t result =
198 AAudioStreamBuilder_openStream(mAaudioBuilder, &mAaudioStream);
199 if ((result != AAUDIO_OK) || (!mAaudioStream)) {
200 return;
201 }
202
203 int32_t framesPerBurst = AAudioStream_getFramesPerBurst(mAaudioStream);
204 uint8_t numberOfBursts = fdp.ConsumeIntegral<uint8_t>();
205 int32_t maxFrames = numberOfBursts * framesPerBurst;
206 int32_t requestedBufferSize =
207 fdp.ConsumeIntegral<uint16_t>() * framesPerBurst;
208 AAudioStream_setBufferSizeInFrames(mAaudioStream, requestedBufferSize);
209
210 int64_t position = 0, nanoseconds = 0;
211 AAudioStream_getTimestamp(mAaudioStream, CLOCK_MONOTONIC, &position,
212 &nanoseconds);
213
214 AAudioStream_requestStart(mAaudioStream);
215
216 aaudio_format_t actualFormat = AAudioStream_getFormat(mAaudioStream);
217 int32_t actualChannelCount = AAudioStream_getChannelCount(mAaudioStream);
218
219 int32_t count = fdp.ConsumeIntegral<int32_t>();
220 direction = AAudioStream_getDirection(mAaudioStream);
221
222 if (actualFormat == AAUDIO_FORMAT_PCM_I16) {
223 std::vector<int16_t> inputShortData(maxFrames * actualChannelCount, 0x0);
224 if (direction == AAUDIO_DIRECTION_INPUT) {
225 AAudioStream_read(mAaudioStream, inputShortData.data(), maxFrames,
226 count * kNanosPerMillisecond);
227 } else if (direction == AAUDIO_DIRECTION_OUTPUT) {
228 AAudioStream_write(mAaudioStream, inputShortData.data(), maxFrames,
229 count * kNanosPerMillisecond);
230 }
231 } else if (actualFormat == AAUDIO_FORMAT_PCM_FLOAT) {
232 std::vector<float> inputFloatData(maxFrames * actualChannelCount, 0x0);
233 if (direction == AAUDIO_DIRECTION_INPUT) {
234 AAudioStream_read(mAaudioStream, inputFloatData.data(), maxFrames,
235 count * kNanosPerMillisecond);
236 } else if (direction == AAUDIO_DIRECTION_OUTPUT) {
237 AAudioStream_write(mAaudioStream, inputFloatData.data(), maxFrames,
238 count * kNanosPerMillisecond);
239 }
240 }
241
242 aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
243 AAudioStream_waitForStateChange(mAaudioStream, AAUDIO_STREAM_STATE_UNKNOWN,
244 &state, count * kNanosPerMillisecond);
245 (void)AAudio_convertStreamStateToText(state);
246
247 (void)AAudioStream_getUsage(mAaudioStream);
248 (void)AAudioStream_getSampleRate(mAaudioStream);
249 (void)AAudioStream_getState(mAaudioStream);
250 (void)AAudioStream_getSamplesPerFrame(mAaudioStream);
251 (void)AAudioStream_getContentType(mAaudioStream);
252 (void)AAudioStream_getInputPreset(mAaudioStream);
253 (void)AAudioStream_isPrivacySensitive(mAaudioStream);
254 (void)AAudioStream_getAllowedCapturePolicy(mAaudioStream);
255 (void)AAudioStream_getPerformanceMode(mAaudioStream);
256 (void)AAudioStream_getDeviceId(mAaudioStream);
257 (void)AAudioStream_getSharingMode(mAaudioStream);
258 (void)AAudioStream_getSessionId(mAaudioStream);
259 (void)AAudioStream_getFramesRead(mAaudioStream);
260 (void)AAudioStream_getFramesWritten(mAaudioStream);
261 (void)AAudioStream_getXRunCount(mAaudioStream);
262 (void)AAudioStream_getBufferCapacityInFrames(mAaudioStream);
263 (void)AAudioStream_getBufferSizeInFrames(mAaudioStream);
264 (void)AAudioStream_isMMapUsed(mAaudioStream);
265
266 AAudioStream_requestPause(mAaudioStream);
267 AAudioStream_requestFlush(mAaudioStream);
268 AAudioStream_release(mAaudioStream);
269 AAudioStream_requestStop(mAaudioStream);
270 }
271
deInit()272 void LibAaudioFuzzer::deInit() {
273 if (mAaudioBuilder) {
274 AAudioStreamBuilder_delete(mAaudioBuilder);
275 }
276 if (mAaudioStream) {
277 AAudioStream_close(mAaudioStream);
278 }
279 }
280
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)281 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
282 LibAaudioFuzzer libAaudioFuzzer;
283 if (libAaudioFuzzer.init()) {
284 libAaudioFuzzer.process(data, size);
285 }
286 return 0;
287 }
288