1 /******************************************************************************
2 *
3 * Copyright (C) 2020 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <fuzzer/FuzzedDataProvider.h>
21 #include <stdio.h>
22
23 #include <AAudioService.h>
24 #include <aaudio/AAudio.h>
25 #include "aaudio/BnAAudioClient.h"
26 #include <android/content/AttributionSourceState.h>
27
28 #define UNUSED_PARAM __attribute__((unused))
29
30 using namespace android;
31 using namespace aaudio;
32
33 aaudio_format_t kAAudioFormats[] = {
34 AAUDIO_FORMAT_UNSPECIFIED,
35 AAUDIO_FORMAT_PCM_I16,
36 AAUDIO_FORMAT_PCM_FLOAT,
37 AAUDIO_FORMAT_PCM_I24_PACKED,
38 AAUDIO_FORMAT_PCM_I32,
39 AAUDIO_FORMAT_IEC61937
40 };
41
42 aaudio_usage_t kAAudioUsages[] = {
43 AAUDIO_USAGE_MEDIA,
44 AAUDIO_USAGE_VOICE_COMMUNICATION,
45 AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
46 AAUDIO_USAGE_ALARM,
47 AAUDIO_USAGE_NOTIFICATION,
48 AAUDIO_USAGE_NOTIFICATION_RINGTONE,
49 AAUDIO_USAGE_NOTIFICATION_EVENT,
50 AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY,
51 AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
52 AAUDIO_USAGE_ASSISTANCE_SONIFICATION,
53 AAUDIO_USAGE_GAME,
54 AAUDIO_USAGE_ASSISTANT,
55 AAUDIO_SYSTEM_USAGE_EMERGENCY,
56 AAUDIO_SYSTEM_USAGE_SAFETY,
57 AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS,
58 AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT,
59 };
60
61 aaudio_content_type_t kAAudioContentTypes[] = {
62 AAUDIO_CONTENT_TYPE_SPEECH,
63 AAUDIO_CONTENT_TYPE_MUSIC,
64 AAUDIO_CONTENT_TYPE_MOVIE,
65 AAUDIO_CONTENT_TYPE_SONIFICATION,
66 };
67
68 aaudio_input_preset_t kAAudioInputPresets[] = {
69 AAUDIO_INPUT_PRESET_GENERIC, AAUDIO_INPUT_PRESET_CAMCORDER,
70 AAUDIO_INPUT_PRESET_VOICE_RECOGNITION, AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION,
71 AAUDIO_INPUT_PRESET_UNPROCESSED, AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE,
72 };
73
74 aaudio_channel_mask_t kAAudioChannelMasks[] = {
75 AAUDIO_UNSPECIFIED,
76 AAUDIO_CHANNEL_INDEX_MASK_1,
77 AAUDIO_CHANNEL_INDEX_MASK_2,
78 AAUDIO_CHANNEL_INDEX_MASK_3,
79 AAUDIO_CHANNEL_INDEX_MASK_4,
80 AAUDIO_CHANNEL_INDEX_MASK_5,
81 AAUDIO_CHANNEL_INDEX_MASK_6,
82 AAUDIO_CHANNEL_INDEX_MASK_7,
83 AAUDIO_CHANNEL_INDEX_MASK_8,
84 AAUDIO_CHANNEL_INDEX_MASK_9,
85 AAUDIO_CHANNEL_INDEX_MASK_10,
86 AAUDIO_CHANNEL_INDEX_MASK_11,
87 AAUDIO_CHANNEL_INDEX_MASK_12,
88 AAUDIO_CHANNEL_INDEX_MASK_13,
89 AAUDIO_CHANNEL_INDEX_MASK_14,
90 AAUDIO_CHANNEL_INDEX_MASK_15,
91 AAUDIO_CHANNEL_INDEX_MASK_16,
92 AAUDIO_CHANNEL_INDEX_MASK_17,
93 AAUDIO_CHANNEL_INDEX_MASK_18,
94 AAUDIO_CHANNEL_INDEX_MASK_19,
95 AAUDIO_CHANNEL_INDEX_MASK_20,
96 AAUDIO_CHANNEL_INDEX_MASK_21,
97 AAUDIO_CHANNEL_INDEX_MASK_22,
98 AAUDIO_CHANNEL_INDEX_MASK_23,
99 AAUDIO_CHANNEL_INDEX_MASK_24,
100 AAUDIO_CHANNEL_MONO,
101 AAUDIO_CHANNEL_STEREO,
102 AAUDIO_CHANNEL_FRONT_BACK,
103 AAUDIO_CHANNEL_2POINT0POINT2,
104 AAUDIO_CHANNEL_2POINT1POINT2,
105 AAUDIO_CHANNEL_3POINT0POINT2,
106 AAUDIO_CHANNEL_3POINT1POINT2,
107 AAUDIO_CHANNEL_5POINT1,
108 AAUDIO_CHANNEL_MONO,
109 AAUDIO_CHANNEL_STEREO,
110 AAUDIO_CHANNEL_2POINT1,
111 AAUDIO_CHANNEL_TRI,
112 AAUDIO_CHANNEL_TRI_BACK,
113 AAUDIO_CHANNEL_3POINT1,
114 AAUDIO_CHANNEL_2POINT0POINT2,
115 AAUDIO_CHANNEL_2POINT1POINT2,
116 AAUDIO_CHANNEL_3POINT0POINT2,
117 AAUDIO_CHANNEL_3POINT1POINT2,
118 AAUDIO_CHANNEL_QUAD,
119 AAUDIO_CHANNEL_QUAD_SIDE,
120 AAUDIO_CHANNEL_SURROUND,
121 AAUDIO_CHANNEL_PENTA,
122 AAUDIO_CHANNEL_5POINT1,
123 AAUDIO_CHANNEL_5POINT1_SIDE,
124 AAUDIO_CHANNEL_5POINT1POINT2,
125 AAUDIO_CHANNEL_5POINT1POINT4,
126 AAUDIO_CHANNEL_6POINT1,
127 AAUDIO_CHANNEL_7POINT1,
128 AAUDIO_CHANNEL_7POINT1POINT2,
129 AAUDIO_CHANNEL_7POINT1POINT4,
130 AAUDIO_CHANNEL_9POINT1POINT4,
131 AAUDIO_CHANNEL_9POINT1POINT6,
132 };
133
134 const size_t kNumAAudioFormats = std::size(kAAudioFormats);
135 const size_t kNumAAudioUsages = std::size(kAAudioUsages);
136 const size_t kNumAAudioContentTypes = std::size(kAAudioContentTypes);
137 const size_t kNumAAudioInputPresets = std::size(kAAudioInputPresets);
138 const size_t kNumAAudioChannelMasks = std::size(kAAudioChannelMasks);
139
140 class FuzzAAudioClient : public virtual RefBase, public AAudioServiceInterface {
141 public:
142 FuzzAAudioClient(sp<AAudioService> service);
143
144 virtual ~FuzzAAudioClient();
145
146 AAudioServiceInterface *getAAudioService();
147
148 void dropAAudioService();
149
registerClient(const sp<IAAudioClient> & client UNUSED_PARAM)150 void registerClient(const sp<IAAudioClient> &client UNUSED_PARAM) override {}
151
152 AAudioHandleInfo openStream(const AAudioStreamRequest &request,
153 AAudioStreamConfiguration &configurationOutput) override;
154
155 aaudio_result_t closeStream(const AAudioHandleInfo& streamHandleInfo) override;
156
157 aaudio_result_t getStreamDescription(const AAudioHandleInfo& streamHandleInfo,
158 AudioEndpointParcelable &parcelable) override;
159
160 aaudio_result_t startStream(const AAudioHandleInfo& streamHandleInfo) override;
161
162 aaudio_result_t pauseStream(const AAudioHandleInfo& streamHandleInfo) override;
163
164 aaudio_result_t stopStream(const AAudioHandleInfo& streamHandleInfo) override;
165
166 aaudio_result_t flushStream(const AAudioHandleInfo& streamHandleInfo) override;
167
168 aaudio_result_t registerAudioThread(const AAudioHandleInfo& streamHandleInfo,
169 pid_t clientThreadId,
170 int64_t periodNanoseconds) override;
171
172 aaudio_result_t unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo,
173 pid_t clientThreadId) override;
174
startClient(const AAudioHandleInfo & streamHandleInfo UNUSED_PARAM,const AudioClient & client UNUSED_PARAM,const audio_attributes_t * attr UNUSED_PARAM,audio_port_handle_t * clientHandle UNUSED_PARAM)175 aaudio_result_t startClient(const AAudioHandleInfo& streamHandleInfo UNUSED_PARAM,
176 const AudioClient &client UNUSED_PARAM,
177 const audio_attributes_t *attr UNUSED_PARAM,
178 audio_port_handle_t *clientHandle UNUSED_PARAM) override {
179 return AAUDIO_ERROR_UNAVAILABLE;
180 }
181
stopClient(const AAudioHandleInfo & streamHandleInfo UNUSED_PARAM,audio_port_handle_t clientHandle UNUSED_PARAM)182 aaudio_result_t stopClient(const AAudioHandleInfo& streamHandleInfo UNUSED_PARAM,
183 audio_port_handle_t clientHandle UNUSED_PARAM) override {
184 return AAUDIO_ERROR_UNAVAILABLE;
185 }
186
exitStandby(const AAudioHandleInfo & streamHandleInfo UNUSED_PARAM,AudioEndpointParcelable & parcelable UNUSED_PARAM)187 aaudio_result_t exitStandby(const AAudioHandleInfo& streamHandleInfo UNUSED_PARAM,
188 AudioEndpointParcelable &parcelable UNUSED_PARAM) override {
189 return AAUDIO_ERROR_UNAVAILABLE;
190 }
191
onStreamChange(aaudio_handle_t handle,int32_t opcode,int32_t value)192 void onStreamChange(aaudio_handle_t handle, int32_t opcode, int32_t value) {}
193
getDeathCount()194 int getDeathCount() { return mDeathCount; }
195
incDeathCount()196 void incDeathCount() { ++mDeathCount; }
197
198 class AAudioClient : public IBinder::DeathRecipient, public BnAAudioClient {
199 public:
AAudioClient(wp<FuzzAAudioClient> fuzzAAudioClient)200 AAudioClient(wp<FuzzAAudioClient> fuzzAAudioClient) : mBinderClient(fuzzAAudioClient) {}
201
binderDied(const wp<IBinder> & who UNUSED_PARAM)202 virtual void binderDied(const wp<IBinder> &who UNUSED_PARAM) {
203 sp<FuzzAAudioClient> client = mBinderClient.promote();
204 if (client.get()) {
205 client->dropAAudioService();
206 client->incDeathCount();
207 }
208 }
209
onStreamChange(int32_t handle,int32_t opcode,int32_t value)210 android::binder::Status onStreamChange(int32_t handle, int32_t opcode, int32_t value) {
211 static_assert(std::is_same_v<aaudio_handle_t, int32_t>);
212 android::sp<FuzzAAudioClient> client = mBinderClient.promote();
213 if (client.get() != nullptr) {
214 client->onStreamChange(handle, opcode, value);
215 }
216 return android::binder::Status::ok();
217 }
218
219 private:
220 wp<FuzzAAudioClient> mBinderClient;
221 };
222
223 private:
224 sp<AAudioService> mAAudioService;
225 sp<AAudioClient> mAAudioClient;
226 AAudioServiceInterface *mAAudioServiceInterface;
227 int mDeathCount;
228 };
229
FuzzAAudioClient(sp<AAudioService> service)230 FuzzAAudioClient::FuzzAAudioClient(sp<AAudioService> service) : AAudioServiceInterface() {
231 mAAudioService = service;
232 mAAudioServiceInterface = &service->asAAudioServiceInterface();
233 mAAudioClient = new AAudioClient(this);
234 mDeathCount = 0;
235 if (mAAudioClient.get() && mAAudioService.get()) {
236 mAAudioService->linkToDeath(mAAudioClient);
237 mAAudioService->registerClient(mAAudioClient);
238 }
239 }
240
~FuzzAAudioClient()241 FuzzAAudioClient::~FuzzAAudioClient() { dropAAudioService(); }
242
getAAudioService()243 AAudioServiceInterface *FuzzAAudioClient::getAAudioService() {
244 if (!mAAudioServiceInterface && mAAudioService.get()) {
245 mAAudioServiceInterface = &mAAudioService->asAAudioServiceInterface();
246 }
247 return mAAudioServiceInterface;
248 }
249
dropAAudioService()250 void FuzzAAudioClient::dropAAudioService() {
251 mAAudioService.clear();
252 }
253
openStream(const AAudioStreamRequest & request,AAudioStreamConfiguration & configurationOutput)254 AAudioHandleInfo FuzzAAudioClient::openStream(const AAudioStreamRequest &request,
255 AAudioStreamConfiguration &configurationOutput) {
256 for (int i = 0; i < 2; ++i) {
257 AAudioServiceInterface *service = getAAudioService();
258 if (!service) {
259 return {-1, AAUDIO_ERROR_NO_SERVICE};
260 }
261
262 auto streamHandleInfo = service->openStream(request, configurationOutput);
263
264 if (streamHandleInfo.getHandle() == AAUDIO_ERROR_NO_SERVICE) {
265 dropAAudioService();
266 } else {
267 return streamHandleInfo;
268 }
269 }
270 return {-1, AAUDIO_ERROR_NO_SERVICE};
271 }
272
closeStream(const AAudioHandleInfo & streamHandleInfo)273 aaudio_result_t FuzzAAudioClient::closeStream(const AAudioHandleInfo& streamHandleInfo) {
274 AAudioServiceInterface *service = getAAudioService();
275 if (!service) {
276 return AAUDIO_ERROR_NO_SERVICE;
277 }
278 return service->closeStream(streamHandleInfo);
279 }
280
getStreamDescription(const AAudioHandleInfo & streamHandleInfo,AudioEndpointParcelable & parcelable)281 aaudio_result_t FuzzAAudioClient::getStreamDescription(const AAudioHandleInfo& streamHandleInfo,
282 AudioEndpointParcelable &parcelable) {
283 AAudioServiceInterface *service = getAAudioService();
284 if (!service) {
285 return AAUDIO_ERROR_NO_SERVICE;
286 }
287 return service->getStreamDescription(streamHandleInfo, parcelable);
288 }
289
startStream(const AAudioHandleInfo & streamHandleInfo)290 aaudio_result_t FuzzAAudioClient::startStream(const AAudioHandleInfo& streamHandleInfo) {
291 AAudioServiceInterface *service = getAAudioService();
292 if (!service) {
293 return AAUDIO_ERROR_NO_SERVICE;
294 }
295 return service->startStream(streamHandleInfo);
296 }
297
pauseStream(const AAudioHandleInfo & streamHandleInfo)298 aaudio_result_t FuzzAAudioClient::pauseStream(const AAudioHandleInfo& streamHandleInfo) {
299 AAudioServiceInterface *service = getAAudioService();
300 if (!service) {
301 return AAUDIO_ERROR_NO_SERVICE;
302 }
303 return service->pauseStream(streamHandleInfo);
304 }
305
stopStream(const AAudioHandleInfo & streamHandleInfo)306 aaudio_result_t FuzzAAudioClient::stopStream(const AAudioHandleInfo& streamHandleInfo) {
307 AAudioServiceInterface *service = getAAudioService();
308 if (!service) {
309 return AAUDIO_ERROR_NO_SERVICE;
310 }
311 return service->stopStream(streamHandleInfo);
312 }
313
flushStream(const AAudioHandleInfo & streamHandleInfo)314 aaudio_result_t FuzzAAudioClient::flushStream(const AAudioHandleInfo& streamHandleInfo) {
315 AAudioServiceInterface *service = getAAudioService();
316 if (!service) {
317 return AAUDIO_ERROR_NO_SERVICE;
318 }
319 return service->flushStream(streamHandleInfo);
320 }
321
registerAudioThread(const AAudioHandleInfo & streamHandleInfo,pid_t clientThreadId,int64_t periodNanoseconds)322 aaudio_result_t FuzzAAudioClient::registerAudioThread(const AAudioHandleInfo& streamHandleInfo,
323 pid_t clientThreadId,
324 int64_t periodNanoseconds) {
325 AAudioServiceInterface *service = getAAudioService();
326 if (!service) {
327 return AAUDIO_ERROR_NO_SERVICE;
328 }
329 return service->registerAudioThread(streamHandleInfo, clientThreadId, periodNanoseconds);
330 }
331
unregisterAudioThread(const AAudioHandleInfo & streamHandleInfo,pid_t clientThreadId)332 aaudio_result_t FuzzAAudioClient::unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo,
333 pid_t clientThreadId) {
334 AAudioServiceInterface *service = getAAudioService();
335 if (!service) {
336 return AAUDIO_ERROR_NO_SERVICE;
337 }
338 return service->unregisterAudioThread(streamHandleInfo, clientThreadId);
339 }
340
341 class OboeserviceFuzzer {
342 public:
343 OboeserviceFuzzer();
344 ~OboeserviceFuzzer() = default;
345 void process(const uint8_t *data, size_t size);
346
347 private:
348 sp<FuzzAAudioClient> mClient;
349 };
350
OboeserviceFuzzer()351 OboeserviceFuzzer::OboeserviceFuzzer() {
352 sp<AAudioService> service = new AAudioService();
353 mClient = new FuzzAAudioClient(service);
354 }
355
process(const uint8_t * data,size_t size)356 void OboeserviceFuzzer::process(const uint8_t *data, size_t size) {
357 FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
358 AAudioStreamRequest request;
359 AAudioStreamConfiguration configurationOutput;
360
361 // Initialize stream request
362 request.getConfiguration().setFormat((audio_format_t)(
363 fdp.ConsumeBool()
364 ? fdp.ConsumeIntegral<int32_t>()
365 : kAAudioFormats[fdp.ConsumeIntegralInRange<int32_t>(0, kNumAAudioFormats - 1)]));
366
367 // TODO b/182392769: use attribution source util
368 android::content::AttributionSourceState attributionSource;
369 attributionSource.uid = getuid();
370 attributionSource.pid = getpid();
371 attributionSource.token = sp<BBinder>::make();
372 request.setAttributionSource(attributionSource);
373 request.setInService(fdp.ConsumeBool());
374
375 request.getConfiguration().setDeviceId(fdp.ConsumeIntegral<int32_t>());
376 request.getConfiguration().setSampleRate(fdp.ConsumeIntegral<int32_t>());
377 request.getConfiguration().setChannelMask((aaudio_channel_mask_t)(
378 fdp.ConsumeBool()
379 ? fdp.ConsumeIntegral<int32_t>()
380 : kAAudioChannelMasks[fdp.ConsumeIntegralInRange<int32_t>(
381 0, kNumAAudioChannelMasks - 1)]));
382 request.getConfiguration().setDirection(
383 fdp.ConsumeBool() ? fdp.ConsumeIntegral<int32_t>()
384 : (fdp.ConsumeBool() ? AAUDIO_DIRECTION_OUTPUT : AAUDIO_DIRECTION_INPUT));
385 request.getConfiguration().setSharingMode(
386 fdp.ConsumeBool()
387 ? fdp.ConsumeIntegral<int32_t>()
388 : (fdp.ConsumeBool() ? AAUDIO_SHARING_MODE_EXCLUSIVE : AAUDIO_SHARING_MODE_SHARED));
389
390 request.getConfiguration().setUsage(
391 fdp.ConsumeBool()
392 ? fdp.ConsumeIntegral<int32_t>()
393 : kAAudioUsages[fdp.ConsumeIntegralInRange<int32_t>(0, kNumAAudioUsages - 1)]);
394 request.getConfiguration().setContentType(
395 fdp.ConsumeBool() ? fdp.ConsumeIntegral<int32_t>()
396 : kAAudioContentTypes[fdp.ConsumeIntegralInRange<int32_t>(
397 0, kNumAAudioContentTypes - 1)]);
398 request.getConfiguration().setInputPreset(
399 fdp.ConsumeBool() ? fdp.ConsumeIntegral<int32_t>()
400 : kAAudioInputPresets[fdp.ConsumeIntegralInRange<int32_t>(
401 0, kNumAAudioInputPresets - 1)]);
402 request.getConfiguration().setPrivacySensitive(fdp.ConsumeBool());
403
404 request.getConfiguration().setBufferCapacity(fdp.ConsumeIntegral<int32_t>());
405
406 auto streamHandleInfo = mClient->openStream(request, configurationOutput);
407 if (streamHandleInfo.getHandle() < 0) {
408 // invalid request, stream not opened.
409 return;
410 }
411 while (fdp.remaining_bytes()) {
412 AudioEndpointParcelable audioEndpointParcelable;
413 int action = fdp.ConsumeIntegralInRange<int32_t>(0, 4);
414 switch (action) {
415 case 0:
416 mClient->getStreamDescription(streamHandleInfo, audioEndpointParcelable);
417 break;
418 case 1:
419 mClient->startStream(streamHandleInfo);
420 break;
421 case 2:
422 mClient->pauseStream(streamHandleInfo);
423 break;
424 case 3:
425 mClient->stopStream(streamHandleInfo);
426 break;
427 case 4:
428 mClient->flushStream(streamHandleInfo);
429 break;
430 }
431 }
432 mClient->closeStream(streamHandleInfo);
433 assert(mClient->getDeathCount() == 0);
434 }
435
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)436 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
437 if (size < 1) {
438 return 0;
439 }
440 OboeserviceFuzzer oboeserviceFuzzer;
441 oboeserviceFuzzer.process(data, size);
442 return 0;
443 }
444