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