• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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