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