/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /** * NOTE * 1) The input to AudioFlinger binder calls are fuzzed in this fuzzer * 2) AudioFlinger crashes due to the fuzzer are detected by the Binder DeathRecipient, where the fuzzer aborts if AudioFlinger dies */ #include #include #include #include #include #include #include #include #include #include #include "fuzzer/FuzzedDataProvider.h" #define MAX_STRING_LENGTH 256 #define MAX_ARRAY_LENGTH 256 constexpr int32_t kMinSampleRateHz = 4000; constexpr int32_t kMaxSampleRateHz = 192000; constexpr int32_t kSampleRateUnspecified = 0; using namespace std; using namespace android; namespace xsd { using namespace ::android::audio::policy::configuration::V7_0; } using android::content::AttributionSourceState; constexpr audio_unique_id_use_t kUniqueIds[] = { AUDIO_UNIQUE_ID_USE_UNSPECIFIED, AUDIO_UNIQUE_ID_USE_SESSION, AUDIO_UNIQUE_ID_USE_MODULE, AUDIO_UNIQUE_ID_USE_EFFECT, AUDIO_UNIQUE_ID_USE_PATCH, AUDIO_UNIQUE_ID_USE_OUTPUT, AUDIO_UNIQUE_ID_USE_INPUT, AUDIO_UNIQUE_ID_USE_CLIENT, AUDIO_UNIQUE_ID_USE_MAX, }; constexpr audio_mode_t kModes[] = { AUDIO_MODE_INVALID, AUDIO_MODE_CURRENT, AUDIO_MODE_NORMAL, AUDIO_MODE_RINGTONE, AUDIO_MODE_IN_CALL, AUDIO_MODE_IN_COMMUNICATION, AUDIO_MODE_CALL_SCREEN}; constexpr audio_session_t kSessionId[] = {AUDIO_SESSION_NONE, AUDIO_SESSION_OUTPUT_STAGE, AUDIO_SESSION_DEVICE}; constexpr audio_encapsulation_mode_t kEncapsulation[] = { AUDIO_ENCAPSULATION_MODE_NONE, AUDIO_ENCAPSULATION_MODE_ELEMENTARY_STREAM, AUDIO_ENCAPSULATION_MODE_HANDLE, }; constexpr audio_port_role_t kPortRoles[] = { AUDIO_PORT_ROLE_NONE, AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_ROLE_SINK, }; constexpr audio_port_type_t kPortTypes[] = { AUDIO_PORT_TYPE_NONE, AUDIO_PORT_TYPE_DEVICE, AUDIO_PORT_TYPE_MIX, AUDIO_PORT_TYPE_SESSION, }; template std::vector getFlags(const xsdc_enum_range &range, const FUNC &func, const std::string &findString = {}) { std::vector vec; for (const auto &xsdEnumVal : range) { T enumVal; std::string enumString = toString(xsdEnumVal); if (enumString.find(findString) != std::string::npos && func(enumString.c_str(), &enumVal)) { vec.push_back(enumVal); } } return vec; } static const std::vector kStreamtypes = getFlags( xsdc_enum_range{}, audio_stream_type_from_string); static const std::vector kFormats = getFlags( xsdc_enum_range{}, audio_format_from_string); static const std::vector kChannelMasks = getFlags( xsdc_enum_range{}, audio_channel_mask_from_string); static const std::vector kUsages = getFlags( xsdc_enum_range{}, audio_usage_from_string); static const std::vector kContentType = getFlags( xsdc_enum_range{}, audio_content_type_from_string); static const std::vector kInputSources = getFlags( xsdc_enum_range{}, audio_source_from_string); static const std::vector kGainModes = getFlags( xsdc_enum_range{}, audio_gain_mode_from_string); static const std::vector kDevices = getFlags( xsdc_enum_range{}, audio_device_from_string); static const std::vector kInputFlags = getFlags( xsdc_enum_range{}, audio_input_flag_from_string, "_INPUT_"); static const std::vector kOutputFlags = getFlags( xsdc_enum_range{}, audio_output_flag_from_string, "_OUTPUT_"); template T getValue(FuzzedDataProvider *fdp, const T (&arr)[size]) { return arr[fdp->ConsumeIntegralInRange(0, size - 1)]; } template T getValue(FuzzedDataProvider *fdp, std::vector vec) { return vec[fdp->ConsumeIntegralInRange(0, vec.size() - 1)]; } int32_t getSampleRate(FuzzedDataProvider *fdp) { if (fdp->ConsumeBool()) { return fdp->ConsumeIntegralInRange(kMinSampleRateHz, kMaxSampleRateHz); } return kSampleRateUnspecified; } class DeathNotifier : public IBinder::DeathRecipient { public: void binderDied(const wp &) { abort(); } }; class AudioFlingerFuzzer { public: AudioFlingerFuzzer(const uint8_t *data, size_t size); void process(); private: FuzzedDataProvider mFdp; void invokeAudioTrack(); void invokeAudioRecord(); status_t invokeAudioEffect(); void invokeAudioSystem(); status_t invokeAudioInputDevice(); status_t invokeAudioOutputDevice(); void invokeAudioPatch(); sp mDeathNotifier; }; AudioFlingerFuzzer::AudioFlingerFuzzer(const uint8_t *data, size_t size) : mFdp(data, size) { sp sm = defaultServiceManager(); sp binder = sm->getService(String16("media.audio_flinger")); if (binder == nullptr) { return; } mDeathNotifier = new DeathNotifier(); binder->linkToDeath(mDeathNotifier); } void AudioFlingerFuzzer::invokeAudioTrack() { uint32_t sampleRate = getSampleRate(&mFdp); audio_format_t format = getValue(&mFdp, kFormats); audio_channel_mask_t channelMask = getValue(&mFdp, kChannelMasks); size_t frameCount = static_cast(mFdp.ConsumeIntegral()); int32_t notificationFrames = mFdp.ConsumeIntegral(); uint32_t useSharedBuffer = mFdp.ConsumeBool(); audio_output_flags_t flags = getValue(&mFdp, kOutputFlags); audio_session_t sessionId = getValue(&mFdp, kSessionId); audio_usage_t usage = getValue(&mFdp, kUsages); audio_content_type_t contentType = getValue(&mFdp, kContentType); audio_attributes_t attributes = {}; sp sharedBuffer; sp heap = nullptr; audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; bool offload = false; bool fast = ((flags & AUDIO_OUTPUT_FLAG_FAST) != 0); if (useSharedBuffer != 0) { size_t heapSize = audio_channel_count_from_out_mask(channelMask) * audio_bytes_per_sample(format) * frameCount; heap = new MemoryDealer(heapSize, "AudioTrack Heap Base"); sharedBuffer = heap->allocate(heapSize); frameCount = 0; notificationFrames = 0; } if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { offloadInfo.sample_rate = sampleRate; offloadInfo.channel_mask = channelMask; offloadInfo.format = format; offload = true; } attributes.content_type = contentType; attributes.usage = usage; sp track = new AudioTrack(); // TODO b/182392769: use attribution source util AttributionSourceState attributionSource; attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid())); attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid())); attributionSource.token = sp::make(); track->set(AUDIO_STREAM_DEFAULT, sampleRate, format, channelMask, frameCount, flags, nullptr, nullptr, notificationFrames, sharedBuffer, false, sessionId, ((fast && sharedBuffer == 0) || offload) ? AudioTrack::TRANSFER_CALLBACK : AudioTrack::TRANSFER_DEFAULT, offload ? &offloadInfo : nullptr, attributionSource, &attributes, false, 1.0f, AUDIO_PORT_HANDLE_NONE); status_t status = track->initCheck(); if (status != NO_ERROR) { track.clear(); return; } track->getSampleRate(); track->latency(); track->getUnderrunCount(); track->streamType(); track->channelCount(); track->getNotificationPeriodInFrames(); uint32_t bufferSizeInFrames = mFdp.ConsumeIntegral(); track->setBufferSizeInFrames(bufferSizeInFrames); track->getBufferSizeInFrames(); int64_t duration = mFdp.ConsumeIntegral(); track->getBufferDurationInUs(&duration); sp sharedBuffer2 = track->sharedBuffer(); track->setCallerName(mFdp.ConsumeRandomLengthString(MAX_STRING_LENGTH)); track->setVolume(mFdp.ConsumeFloatingPoint(), mFdp.ConsumeFloatingPoint()); track->setVolume(mFdp.ConsumeFloatingPoint()); track->setAuxEffectSendLevel(mFdp.ConsumeFloatingPoint()); float auxEffectSendLevel; track->getAuxEffectSendLevel(&auxEffectSendLevel); track->setSampleRate(getSampleRate(&mFdp)); track->getSampleRate(); track->getOriginalSampleRate(); AudioPlaybackRate playbackRate = {}; playbackRate.mSpeed = mFdp.ConsumeFloatingPoint(); playbackRate.mPitch = mFdp.ConsumeFloatingPoint(); track->setPlaybackRate(playbackRate); track->getPlaybackRate(); track->setLoop(mFdp.ConsumeIntegral(), mFdp.ConsumeIntegral(), mFdp.ConsumeIntegral()); track->setMarkerPosition(mFdp.ConsumeIntegral()); uint32_t marker = {}; track->getMarkerPosition(&marker); track->setPositionUpdatePeriod(mFdp.ConsumeIntegral()); uint32_t updatePeriod = {}; track->getPositionUpdatePeriod(&updatePeriod); track->setPosition(mFdp.ConsumeIntegral()); uint32_t position = {}; track->getPosition(&position); track->getBufferPosition(&position); track->reload(); track->start(); track->pause(); track->flush(); track->stop(); track->stopped(); } void AudioFlingerFuzzer::invokeAudioRecord() { int32_t notificationFrames = mFdp.ConsumeIntegral(); uint32_t sampleRate = getSampleRate(&mFdp); size_t frameCount = static_cast(mFdp.ConsumeIntegral()); audio_format_t format = getValue(&mFdp, kFormats); audio_channel_mask_t channelMask = getValue(&mFdp, kChannelMasks); audio_input_flags_t flags = getValue(&mFdp, kInputFlags); audio_session_t sessionId = getValue(&mFdp, kSessionId); audio_source_t inputSource = getValue(&mFdp, kInputSources); audio_attributes_t attributes = {}; bool fast = ((flags & AUDIO_OUTPUT_FLAG_FAST) != 0); attributes.source = inputSource; // TODO b/182392769: use attribution source util AttributionSourceState attributionSource; attributionSource.packageName = std::string(mFdp.ConsumeRandomLengthString().c_str()); attributionSource.token = sp::make(); sp record = new AudioRecord(attributionSource); record->set(AUDIO_SOURCE_DEFAULT, sampleRate, format, channelMask, frameCount, nullptr, nullptr, notificationFrames, false, sessionId, fast ? AudioRecord::TRANSFER_CALLBACK : AudioRecord::TRANSFER_DEFAULT, flags, getuid(), getpid(), &attributes, AUDIO_PORT_HANDLE_NONE); status_t status = record->initCheck(); if (status != NO_ERROR) { return; } record->latency(); record->format(); record->channelCount(); record->frameCount(); record->frameSize(); record->inputSource(); record->getNotificationPeriodInFrames(); record->start(); record->stop(); record->stopped(); uint32_t marker = mFdp.ConsumeIntegral(); record->setMarkerPosition(marker); record->getMarkerPosition(&marker); uint32_t updatePeriod = mFdp.ConsumeIntegral(); record->setPositionUpdatePeriod(updatePeriod); record->getPositionUpdatePeriod(&updatePeriod); uint32_t position; record->getPosition(&position); ExtendedTimestamp timestamp; record->getTimestamp(×tamp); record->getSessionId(); record->getCallerName(); android::AudioRecord::Buffer audioBuffer; int32_t waitCount = mFdp.ConsumeIntegral(); size_t nonContig = static_cast(mFdp.ConsumeIntegral()); audioBuffer.frameCount = static_cast(mFdp.ConsumeIntegral()); record->obtainBuffer(&audioBuffer, waitCount, &nonContig); bool blocking = false; record->read(audioBuffer.raw, audioBuffer.size, blocking); record->getInputFramesLost(); record->getFlags(); std::vector activeMicrophones; record->getActiveMicrophones(&activeMicrophones); record->releaseBuffer(&audioBuffer); audio_port_handle_t deviceId = static_cast(mFdp.ConsumeIntegral()); record->setInputDevice(deviceId); record->getInputDevice(); record->getRoutedDeviceId(); record->getPortId(); } struct EffectClient : public android::media::BnEffectClient { EffectClient() {} binder::Status controlStatusChanged(bool controlGranted __unused) override { return binder::Status::ok(); } binder::Status enableStatusChanged(bool enabled __unused) override { return binder::Status::ok(); } binder::Status commandExecuted(int32_t cmdCode __unused, const std::vector &cmdData __unused, const std::vector &replyData __unused) override { return binder::Status::ok(); } }; status_t AudioFlingerFuzzer::invokeAudioEffect() { effect_uuid_t type; type.timeLow = mFdp.ConsumeIntegral(); type.timeMid = mFdp.ConsumeIntegral(); type.timeHiAndVersion = mFdp.ConsumeIntegral(); type.clockSeq = mFdp.ConsumeIntegral(); for (int i = 0; i < 6; ++i) { type.node[i] = mFdp.ConsumeIntegral(); } effect_descriptor_t descriptor = {}; descriptor.type = type; descriptor.uuid = *EFFECT_UUID_NULL; sp effectClient(new EffectClient()); const int32_t priority = mFdp.ConsumeIntegral(); audio_session_t sessionId = static_cast(mFdp.ConsumeIntegral()); const audio_io_handle_t io = mFdp.ConsumeIntegral(); std::string opPackageName = static_cast(mFdp.ConsumeRandomLengthString().c_str()); AudioDeviceTypeAddr device; sp af = AudioSystem::get_audio_flinger(); if (!af) { return NO_ERROR; } media::CreateEffectRequest request{}; request.desc = VALUE_OR_RETURN_STATUS(legacy2aidl_effect_descriptor_t_EffectDescriptor(descriptor)); request.client = effectClient; request.priority = priority; request.output = io; request.sessionId = sessionId; request.device = VALUE_OR_RETURN_STATUS(legacy2aidl_AudioDeviceTypeAddress(device)); // TODO b/182392769: use attribution source util request.attributionSource.packageName = opPackageName; request.attributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(getpid())); request.probe = false; media::CreateEffectResponse response{}; status_t status = af->createEffect(request, &response); if (status != OK) { return NO_ERROR; } descriptor = VALUE_OR_RETURN_STATUS(aidl2legacy_EffectDescriptor_effect_descriptor_t(response.desc)); uint32_t numEffects; af->queryNumberEffects(&numEffects); uint32_t queryIndex = mFdp.ConsumeIntegral(); af->queryEffect(queryIndex, &descriptor); effect_descriptor_t getDescriptor; uint32_t preferredTypeFlag = mFdp.ConsumeIntegral(); af->getEffectDescriptor(&descriptor.uuid, &descriptor.type, preferredTypeFlag, &getDescriptor); sessionId = static_cast(mFdp.ConsumeIntegral()); audio_io_handle_t srcOutput = mFdp.ConsumeIntegral(); audio_io_handle_t dstOutput = mFdp.ConsumeIntegral(); af->moveEffects(sessionId, srcOutput, dstOutput); int effectId = mFdp.ConsumeIntegral(); sessionId = static_cast(mFdp.ConsumeIntegral()); af->setEffectSuspended(effectId, sessionId, mFdp.ConsumeBool()); return NO_ERROR; } void AudioFlingerFuzzer::invokeAudioSystem() { AudioSystem::muteMicrophone(mFdp.ConsumeBool()); AudioSystem::setMasterMute(mFdp.ConsumeBool()); AudioSystem::setMasterVolume(mFdp.ConsumeFloatingPoint()); AudioSystem::setMasterBalance(mFdp.ConsumeFloatingPoint()); AudioSystem::setVoiceVolume(mFdp.ConsumeFloatingPoint()); float volume; AudioSystem::getMasterVolume(&volume); bool state; AudioSystem::getMasterMute(&state); AudioSystem::isMicrophoneMuted(&state); audio_stream_type_t stream = getValue(&mFdp, kStreamtypes); AudioSystem::setStreamMute(getValue(&mFdp, kStreamtypes), mFdp.ConsumeBool()); stream = getValue(&mFdp, kStreamtypes); AudioSystem::setStreamVolume(stream, mFdp.ConsumeFloatingPoint(), mFdp.ConsumeIntegral()); audio_mode_t mode = getValue(&mFdp, kModes); AudioSystem::setMode(mode); size_t frameCount; stream = getValue(&mFdp, kStreamtypes); AudioSystem::getOutputFrameCount(&frameCount, stream); uint32_t latency; stream = getValue(&mFdp, kStreamtypes); AudioSystem::getOutputLatency(&latency, stream); stream = getValue(&mFdp, kStreamtypes); AudioSystem::getStreamVolume(stream, &volume, mFdp.ConsumeIntegral()); stream = getValue(&mFdp, kStreamtypes); AudioSystem::getStreamMute(stream, &state); uint32_t samplingRate; AudioSystem::getSamplingRate(mFdp.ConsumeIntegral(), &samplingRate); AudioSystem::getFrameCount(mFdp.ConsumeIntegral(), &frameCount); AudioSystem::getLatency(mFdp.ConsumeIntegral(), &latency); AudioSystem::setVoiceVolume(mFdp.ConsumeFloatingPoint()); uint32_t halFrames; uint32_t dspFrames; AudioSystem::getRenderPosition(mFdp.ConsumeIntegral(), &halFrames, &dspFrames); AudioSystem::getInputFramesLost(mFdp.ConsumeIntegral()); AudioSystem::getInputFramesLost(mFdp.ConsumeIntegral()); audio_unique_id_use_t uniqueIdUse = getValue(&mFdp, kUniqueIds); AudioSystem::newAudioUniqueId(uniqueIdUse); audio_session_t sessionId = getValue(&mFdp, kSessionId); pid_t pid = mFdp.ConsumeBool() ? getpid() : mFdp.ConsumeIntegral(); uid_t uid = mFdp.ConsumeBool() ? getuid() : mFdp.ConsumeIntegral(); AudioSystem::acquireAudioSessionId(sessionId, pid, uid); pid = mFdp.ConsumeBool() ? getpid() : mFdp.ConsumeIntegral(); sessionId = getValue(&mFdp, kSessionId); AudioSystem::releaseAudioSessionId(sessionId, pid); sessionId = getValue(&mFdp, kSessionId); AudioSystem::getAudioHwSyncForSession(sessionId); AudioSystem::systemReady(); AudioSystem::getFrameCountHAL(mFdp.ConsumeIntegral(), &frameCount); size_t buffSize; uint32_t sampleRate = getSampleRate(&mFdp); audio_format_t format = getValue(&mFdp, kFormats); audio_channel_mask_t channelMask = getValue(&mFdp, kChannelMasks); AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &buffSize); AudioSystem::getPrimaryOutputSamplingRate(); AudioSystem::getPrimaryOutputFrameCount(); AudioSystem::setLowRamDevice(mFdp.ConsumeBool(), mFdp.ConsumeIntegral()); std::vector microphones; AudioSystem::getMicrophones(µphones); std::vector pids; pids.insert(pids.begin(), getpid()); for (int i = 1; i < mFdp.ConsumeIntegralInRange(2, MAX_ARRAY_LENGTH); ++i) { pids.insert(pids.begin() + i, static_cast(mFdp.ConsumeIntegral())); } AudioSystem::setAudioHalPids(pids); sp af = AudioSystem::get_audio_flinger(); if (!af) { return; } af->setRecordSilenced(mFdp.ConsumeIntegral(), mFdp.ConsumeBool()); float balance = mFdp.ConsumeFloatingPoint(); af->getMasterBalance(&balance); af->invalidateStream(static_cast(mFdp.ConsumeIntegral())); } status_t AudioFlingerFuzzer::invokeAudioInputDevice() { sp af = AudioSystem::get_audio_flinger(); if (!af) { return NO_ERROR; } audio_config_t config = {}; audio_module_handle_t module = mFdp.ConsumeIntegral(); audio_io_handle_t input = mFdp.ConsumeIntegral(); config.frame_count = mFdp.ConsumeIntegral(); String8 address = static_cast(mFdp.ConsumeRandomLengthString().c_str()); config.channel_mask = getValue(&mFdp, kChannelMasks); config.format = getValue(&mFdp, kFormats); config.offload_info = AUDIO_INFO_INITIALIZER; config.offload_info.bit_rate = mFdp.ConsumeIntegral(); config.offload_info.bit_width = mFdp.ConsumeIntegral(); config.offload_info.content_id = mFdp.ConsumeIntegral(); config.offload_info.channel_mask = getValue(&mFdp, kChannelMasks); config.offload_info.duration_us = mFdp.ConsumeIntegral(); config.offload_info.encapsulation_mode = getValue(&mFdp, kEncapsulation); config.offload_info.format = getValue(&mFdp, kFormats); config.offload_info.has_video = mFdp.ConsumeBool(); config.offload_info.is_streaming = mFdp.ConsumeBool(); config.offload_info.sample_rate = getSampleRate(&mFdp); config.offload_info.sync_id = mFdp.ConsumeIntegral(); config.offload_info.stream_type = getValue(&mFdp, kStreamtypes); config.offload_info.usage = getValue(&mFdp, kUsages); config.sample_rate = getSampleRate(&mFdp); audio_devices_t device = getValue(&mFdp, kDevices); audio_source_t source = getValue(&mFdp, kInputSources); audio_input_flags_t flags = getValue(&mFdp, kInputFlags); AudioDeviceTypeAddr deviceTypeAddr(device, address.c_str()); media::OpenInputRequest request{}; request.module = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_module_handle_t_int32_t(module)); request.input = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(input)); request.config = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_config_t_AudioConfig(config)); request.device = VALUE_OR_RETURN_STATUS(legacy2aidl_AudioDeviceTypeAddress(deviceTypeAddr)); request.source = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_source_t_AudioSourceType(source)); request.flags = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_input_flags_t_int32_t_mask(flags)); media::OpenInputResponse response{}; status_t status = af->openInput(request, &response); if (status != NO_ERROR) { return NO_ERROR; } input = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_module_handle_t(response.input)); af->closeInput(input); return NO_ERROR; } status_t AudioFlingerFuzzer::invokeAudioOutputDevice() { sp af = AudioSystem::get_audio_flinger(); if (!af) { return NO_ERROR; } audio_config_t config = {}; audio_module_handle_t module = mFdp.ConsumeIntegral(); audio_io_handle_t output = mFdp.ConsumeIntegral(); config.frame_count = mFdp.ConsumeIntegral(); String8 address = static_cast(mFdp.ConsumeRandomLengthString().c_str()); config.channel_mask = getValue(&mFdp, kChannelMasks); config.offload_info = AUDIO_INFO_INITIALIZER; config.offload_info.bit_rate = mFdp.ConsumeIntegral(); config.offload_info.bit_width = mFdp.ConsumeIntegral(); config.offload_info.channel_mask = getValue(&mFdp, kChannelMasks); config.offload_info.content_id = mFdp.ConsumeIntegral(); config.offload_info.duration_us = mFdp.ConsumeIntegral(); config.offload_info.encapsulation_mode = getValue(&mFdp, kEncapsulation); config.offload_info.format = getValue(&mFdp, kFormats); config.offload_info.has_video = mFdp.ConsumeBool(); config.offload_info.is_streaming = mFdp.ConsumeBool(); config.offload_info.sample_rate = getSampleRate(&mFdp); config.offload_info.stream_type = getValue(&mFdp, kStreamtypes); config.offload_info.sync_id = mFdp.ConsumeIntegral(); config.offload_info.usage = getValue(&mFdp, kUsages); config.format = getValue(&mFdp, kFormats); config.sample_rate = getSampleRate(&mFdp); sp device = new DeviceDescriptorBase(getValue(&mFdp, kDevices)); audio_output_flags_t flags = getValue(&mFdp, kOutputFlags); media::OpenOutputRequest request{}; media::OpenOutputResponse response{}; request.module = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_module_handle_t_int32_t(module)); request.config = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_config_t_AudioConfig(config)); request.device = VALUE_OR_RETURN_STATUS(legacy2aidl_DeviceDescriptorBase(device)); request.flags = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_output_flags_t_int32_t_mask(flags)); status_t status = af->openOutput(request, &response); if (status != NO_ERROR) { return NO_ERROR; } output = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_io_handle_t(response.output)); audio_io_handle_t output1 = mFdp.ConsumeIntegral(); af->openDuplicateOutput(output, output1); af->suspendOutput(output); af->restoreOutput(output); af->closeOutput(output); return NO_ERROR; } void AudioFlingerFuzzer::invokeAudioPatch() { sp af = AudioSystem::get_audio_flinger(); if (!af) { return; } struct audio_patch patch = {}; audio_patch_handle_t handle = mFdp.ConsumeIntegral(); patch.id = mFdp.ConsumeIntegral(); patch.num_sources = mFdp.ConsumeIntegral(); patch.num_sinks = mFdp.ConsumeIntegral(); for (int i = 0; i < AUDIO_PATCH_PORTS_MAX; ++i) { patch.sources[i].config_mask = mFdp.ConsumeIntegral(); patch.sources[i].channel_mask = getValue(&mFdp, kChannelMasks); patch.sources[i].format = getValue(&mFdp, kFormats); patch.sources[i].gain.channel_mask = getValue(&mFdp, kChannelMasks); patch.sources[i].gain.index = mFdp.ConsumeIntegral(); patch.sources[i].gain.mode = getValue(&mFdp, kGainModes); patch.sources[i].gain.ramp_duration_ms = mFdp.ConsumeIntegral(); patch.sources[i].id = static_cast(mFdp.ConsumeIntegral()); patch.sources[i].role = getValue(&mFdp, kPortRoles); patch.sources[i].sample_rate = getSampleRate(&mFdp); patch.sources[i].type = getValue(&mFdp, kPortTypes); patch.sinks[i].config_mask = mFdp.ConsumeIntegral(); patch.sinks[i].channel_mask = getValue(&mFdp, kChannelMasks); patch.sinks[i].format = getValue(&mFdp, kFormats); patch.sinks[i].gain.channel_mask = getValue(&mFdp, kChannelMasks); patch.sinks[i].gain.index = mFdp.ConsumeIntegral(); patch.sinks[i].gain.mode = getValue(&mFdp, kGainModes); patch.sinks[i].gain.ramp_duration_ms = mFdp.ConsumeIntegral(); patch.sinks[i].id = static_cast(mFdp.ConsumeIntegral()); patch.sinks[i].role = getValue(&mFdp, kPortRoles); patch.sinks[i].sample_rate = getSampleRate(&mFdp); patch.sinks[i].type = getValue(&mFdp, kPortTypes); } status_t status = af->createAudioPatch(&patch, &handle); if (status != NO_ERROR) { return; } unsigned int num_patches = mFdp.ConsumeIntegral(); struct audio_patch patches = {}; af->listAudioPatches(&num_patches, &patches); af->releaseAudioPatch(handle); } void AudioFlingerFuzzer::process() { invokeAudioEffect(); invokeAudioInputDevice(); invokeAudioOutputDevice(); invokeAudioPatch(); invokeAudioRecord(); invokeAudioSystem(); invokeAudioTrack(); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (size < 1) { return 0; } AudioFlingerFuzzer audioFuzzer(data, size); audioFuzzer.process(); return 0; }