blob: 6dc6eff4cbd6efe4dd20f185fff99c3ccbb67577 [file] [log] [blame]
Mufaddal Chakera3fde8702020-11-18 14:08:12 +05301/******************************************************************************
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"
Svet Ganov33761132021-05-13 22:51:08 +000026#include <android/content/AttributionSourceState.h>
Mufaddal Chakera3fde8702020-11-18 14:08:12 +053027
28#define UNUSED_PARAM __attribute__((unused))
29
30using namespace android;
31using namespace aaudio;
32
33aaudio_format_t kAAudioFormats[] = {
34 AAUDIO_FORMAT_UNSPECIFIED,
35 AAUDIO_FORMAT_PCM_I16,
36 AAUDIO_FORMAT_PCM_FLOAT,
Robert Wu310037a2022-09-06 21:48:18 +000037 AAUDIO_FORMAT_PCM_I24_PACKED,
38 AAUDIO_FORMAT_PCM_I32,
39 AAUDIO_FORMAT_IEC61937
Mufaddal Chakera3fde8702020-11-18 14:08:12 +053040};
41
42aaudio_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
61aaudio_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
68aaudio_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
jiabina9094092021-06-28 20:36:45 +000074aaudio_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
Mufaddal Chakera3fde8702020-11-18 14:08:12 +0530134const size_t kNumAAudioFormats = std::size(kAAudioFormats);
135const size_t kNumAAudioUsages = std::size(kAAudioUsages);
136const size_t kNumAAudioContentTypes = std::size(kAAudioContentTypes);
137const size_t kNumAAudioInputPresets = std::size(kAAudioInputPresets);
jiabina9094092021-06-28 20:36:45 +0000138const size_t kNumAAudioChannelMasks = std::size(kAAudioChannelMasks);
Mufaddal Chakera3fde8702020-11-18 14:08:12 +0530139
140class 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
150 void registerClient(const sp<IAAudioClient> &client UNUSED_PARAM) override {}
151
152 aaudio_handle_t openStream(const AAudioStreamRequest &request,
153 AAudioStreamConfiguration &configurationOutput) override;
154
155 aaudio_result_t closeStream(aaudio_handle_t streamHandle) override;
156
157 aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
158 AudioEndpointParcelable &parcelable) override;
159
160 aaudio_result_t startStream(aaudio_handle_t streamHandle) override;
161
162 aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override;
163
164 aaudio_result_t stopStream(aaudio_handle_t streamHandle) override;
165
166 aaudio_result_t flushStream(aaudio_handle_t streamHandle) override;
167
168 aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, pid_t clientThreadId,
169 int64_t periodNanoseconds) override;
170
171 aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
172 pid_t clientThreadId) override;
173
174 aaudio_result_t startClient(aaudio_handle_t streamHandle UNUSED_PARAM,
175 const AudioClient &client UNUSED_PARAM,
176 const audio_attributes_t *attr UNUSED_PARAM,
177 audio_port_handle_t *clientHandle UNUSED_PARAM) override {
178 return AAUDIO_ERROR_UNAVAILABLE;
179 }
180
181 aaudio_result_t stopClient(aaudio_handle_t streamHandle UNUSED_PARAM,
182 audio_port_handle_t clientHandle UNUSED_PARAM) override {
183 return AAUDIO_ERROR_UNAVAILABLE;
184 }
185
jiabinf7f06152021-11-22 18:10:14 +0000186 aaudio_result_t exitStandby(aaudio_handle_t streamHandle UNUSED_PARAM,
187 AudioEndpointParcelable &parcelable UNUSED_PARAM) override {
188 return AAUDIO_ERROR_UNAVAILABLE;
189 }
190
Mufaddal Chakera3fde8702020-11-18 14:08:12 +0530191 void onStreamChange(aaudio_handle_t handle, int32_t opcode, int32_t value) {}
192
193 int getDeathCount() { return mDeathCount; }
194
195 void incDeathCount() { ++mDeathCount; }
196
197 class AAudioClient : public IBinder::DeathRecipient, public BnAAudioClient {
198 public:
199 AAudioClient(wp<FuzzAAudioClient> fuzzAAudioClient) : mBinderClient(fuzzAAudioClient) {}
200
201 virtual void binderDied(const wp<IBinder> &who UNUSED_PARAM) {
202 sp<FuzzAAudioClient> client = mBinderClient.promote();
203 if (client.get()) {
204 client->dropAAudioService();
205 client->incDeathCount();
206 }
207 }
208
209 android::binder::Status onStreamChange(int32_t handle, int32_t opcode, int32_t value) {
210 static_assert(std::is_same_v<aaudio_handle_t, int32_t>);
211 android::sp<FuzzAAudioClient> client = mBinderClient.promote();
212 if (client.get() != nullptr) {
213 client->onStreamChange(handle, opcode, value);
214 }
215 return android::binder::Status::ok();
216 }
217
218 private:
219 wp<FuzzAAudioClient> mBinderClient;
220 };
221
222 private:
223 sp<AAudioService> mAAudioService;
224 sp<AAudioClient> mAAudioClient;
225 AAudioServiceInterface *mAAudioServiceInterface;
226 int mDeathCount;
227};
228
229FuzzAAudioClient::FuzzAAudioClient(sp<AAudioService> service) : AAudioServiceInterface() {
230 mAAudioService = service;
231 mAAudioServiceInterface = &service->asAAudioServiceInterface();
232 mAAudioClient = new AAudioClient(this);
233 mDeathCount = 0;
234 if (mAAudioClient.get() && mAAudioService.get()) {
235 mAAudioService->linkToDeath(mAAudioClient);
236 mAAudioService->registerClient(mAAudioClient);
237 }
238}
239
240FuzzAAudioClient::~FuzzAAudioClient() { dropAAudioService(); }
241
242AAudioServiceInterface *FuzzAAudioClient::getAAudioService() {
243 if (!mAAudioServiceInterface && mAAudioService.get()) {
244 mAAudioServiceInterface = &mAAudioService->asAAudioServiceInterface();
245 }
246 return mAAudioServiceInterface;
247}
248
249void FuzzAAudioClient::dropAAudioService() {
250 mAAudioService.clear();
251}
252
253aaudio_handle_t FuzzAAudioClient::openStream(const AAudioStreamRequest &request,
254 AAudioStreamConfiguration &configurationOutput) {
255 aaudio_handle_t stream;
256 for (int i = 0; i < 2; ++i) {
257 AAudioServiceInterface *service = getAAudioService();
258 if (!service) {
259 return AAUDIO_ERROR_NO_SERVICE;
260 }
261
262 stream = service->openStream(request, configurationOutput);
263
264 if (stream == AAUDIO_ERROR_NO_SERVICE) {
265 dropAAudioService();
266 } else {
267 break;
268 }
269 }
270 return stream;
271}
272
273aaudio_result_t FuzzAAudioClient::closeStream(aaudio_handle_t streamHandle) {
274 AAudioServiceInterface *service = getAAudioService();
275 if (!service) {
276 return AAUDIO_ERROR_NO_SERVICE;
277 }
278 return service->closeStream(streamHandle);
279}
280
281aaudio_result_t FuzzAAudioClient::getStreamDescription(aaudio_handle_t streamHandle,
282 AudioEndpointParcelable &parcelable) {
283 AAudioServiceInterface *service = getAAudioService();
284 if (!service) {
285 return AAUDIO_ERROR_NO_SERVICE;
286 }
287 return service->getStreamDescription(streamHandle, parcelable);
288}
289
290aaudio_result_t FuzzAAudioClient::startStream(aaudio_handle_t streamHandle) {
291 AAudioServiceInterface *service = getAAudioService();
292 if (!service) {
293 return AAUDIO_ERROR_NO_SERVICE;
294 }
295 return service->startStream(streamHandle);
296}
297
298aaudio_result_t FuzzAAudioClient::pauseStream(aaudio_handle_t streamHandle) {
299 AAudioServiceInterface *service = getAAudioService();
300 if (!service) {
301 return AAUDIO_ERROR_NO_SERVICE;
302 }
303 return service->pauseStream(streamHandle);
304}
305
306aaudio_result_t FuzzAAudioClient::stopStream(aaudio_handle_t streamHandle) {
307 AAudioServiceInterface *service = getAAudioService();
308 if (!service) {
309 return AAUDIO_ERROR_NO_SERVICE;
310 }
311 return service->stopStream(streamHandle);
312}
313
314aaudio_result_t FuzzAAudioClient::flushStream(aaudio_handle_t streamHandle) {
315 AAudioServiceInterface *service = getAAudioService();
316 if (!service) {
317 return AAUDIO_ERROR_NO_SERVICE;
318 }
319 return service->flushStream(streamHandle);
320}
321
322aaudio_result_t FuzzAAudioClient::registerAudioThread(aaudio_handle_t streamHandle,
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(streamHandle, clientThreadId, periodNanoseconds);
330}
331
332aaudio_result_t FuzzAAudioClient::unregisterAudioThread(aaudio_handle_t streamHandle,
333 pid_t clientThreadId) {
334 AAudioServiceInterface *service = getAAudioService();
335 if (!service) {
336 return AAUDIO_ERROR_NO_SERVICE;
337 }
338 return service->unregisterAudioThread(streamHandle, clientThreadId);
339}
340
341class 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
351OboeserviceFuzzer::OboeserviceFuzzer() {
352 sp<AAudioService> service = new AAudioService();
353 mClient = new FuzzAAudioClient(service);
354}
355
356void 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
Svet Ganov33761132021-05-13 22:51:08 +0000367 // 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);
Mufaddal Chakera3fde8702020-11-18 14:08:12 +0530373 request.setInService(fdp.ConsumeBool());
374
375 request.getConfiguration().setDeviceId(fdp.ConsumeIntegral<int32_t>());
376 request.getConfiguration().setSampleRate(fdp.ConsumeIntegral<int32_t>());
jiabina9094092021-06-28 20:36:45 +0000377 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)]));
Mufaddal Chakera3fde8702020-11-18 14:08:12 +0530382 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
Robert Wu310037a2022-09-06 21:48:18 +0000406 request.getConfiguration().setHardwareSampleRate(fdp.ConsumeIntegral<int32_t>());
407 request.getConfiguration().setHardwareSamplesPerFrame(fdp.ConsumeIntegral<int32_t>());
408 request.getConfiguration().setHardwareFormat((audio_format_t)(
409 fdp.ConsumeBool()
410 ? fdp.ConsumeIntegral<int32_t>()
411 : kAAudioFormats[fdp.ConsumeIntegralInRange<int32_t>(0, kNumAAudioFormats - 1)]));
412
Mufaddal Chakera3fde8702020-11-18 14:08:12 +0530413 aaudio_handle_t stream = mClient->openStream(request, configurationOutput);
414 if (stream < 0) {
415 // invalid request, stream not opened.
416 return;
417 }
418 while (fdp.remaining_bytes()) {
419 AudioEndpointParcelable audioEndpointParcelable;
420 int action = fdp.ConsumeIntegralInRange<int32_t>(0, 4);
421 switch (action) {
422 case 0:
423 mClient->getStreamDescription(stream, audioEndpointParcelable);
424 break;
425 case 1:
426 mClient->startStream(stream);
427 break;
428 case 2:
429 mClient->pauseStream(stream);
430 break;
431 case 3:
432 mClient->stopStream(stream);
433 break;
434 case 4:
435 mClient->flushStream(stream);
436 break;
437 }
438 }
439 mClient->closeStream(stream);
440 assert(mClient->getDeathCount() == 0);
441}
442
443extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
444 if (size < 1) {
445 return 0;
446 }
447 OboeserviceFuzzer oboeserviceFuzzer;
448 oboeserviceFuzzer.process(data, size);
449 return 0;
450}