From dac1444e4926f94d8d9ac6b6a098ac101ce4a7be Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 1 Dec 2016 15:28:29 -0800 Subject: DO NOT MERGE - improve audio effect framwework thread safety - Reorganize handle effect creation code to make sure the effect engine is created with both thread and effect chain mutex held. - Reorganize handle disconnect code to make sure the effect engine is released with both thread and effect chain mutex held. - Protect IEffect interface methods in EffectHande with a Mutex. - Only pin effect if the session was acquired first. - Do not use strong pointer to EffectModule in EffectHandles: only the EffectChain has a single strong reference to the EffectModule. Bug: 32707507 CVE-2017-0479 CVE-2017-0480 CVE-2017-0499 Change-Id: Ia1098cba2cd32cc2d1c9dfdff4adc2388dfed80e (cherry picked from commit b378b73dd7480b584340b8028802c9ca2d625123) (cherry picked from commit 22e26d8ee73488c58ba3e7928e5da155151abfd0 with backport by ) --- services/audioflinger/Threads.cpp | 51 +++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'services/audioflinger/Threads.cpp') diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index e5e8bdb..d7c9c47 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1159,7 +1159,8 @@ sp AudioFlinger::ThreadBase::createEffect_l( int sessionId, effect_descriptor_t *desc, int *enabled, - status_t *status) + status_t *status, + bool pinned) { sp effect; sp handle; @@ -1253,20 +1254,7 @@ sp AudioFlinger::ThreadBase::createEffect_l( } effectRegistered = true; // create a new effect module if none present in the chain - effect = new EffectModule(this, chain, desc, id, sessionId); - lStatus = effect->status(); - if (lStatus != NO_ERROR) { - goto Exit; - } - - bool setVal = false; - if (mType == OFFLOAD || (mType == DIRECT && mIsDirectPcm)) { - setVal = true; - } - - effect->setOffloaded(setVal, mId); - - lStatus = chain->addEffect_l(effect); + lStatus = chain->createEffect_l(effect, this, desc, id, (audio_session_t)sessionId, pinned); if (lStatus != NO_ERROR) { goto Exit; } @@ -1307,6 +1295,33 @@ Exit: return handle; } +void AudioFlinger::ThreadBase::disconnectEffectHandle(EffectHandle *handle, + bool unpinIfLast) +{ + bool remove = false; + sp effect; + { + Mutex::Autolock _l(mLock); + + effect = handle->effect().promote(); + if (effect == 0) { + return; + } + // restore suspended effects if the disconnected handle was enabled and the last one. + remove = (effect->removeHandle(handle) == 0) && (!effect->isPinned() || unpinIfLast); + if (remove) { + removeEffect_l(effect, true); + } + } + if (remove) { + mAudioFlinger->updateOrphanEffectChains(effect); + AudioSystem::unregisterEffect(effect->id()); + if (handle->enabled()) { + checkSuspendOnEffectEnabled(effect, false, effect->sessionId()); + } + } +} + sp AudioFlinger::ThreadBase::getEffect(int sessionId, int effectId) { Mutex::Autolock _l(mLock); @@ -1371,9 +1386,9 @@ status_t AudioFlinger::ThreadBase::addEffect_l(const sp& effect) return NO_ERROR; } -void AudioFlinger::ThreadBase::removeEffect_l(const sp& effect) { +void AudioFlinger::ThreadBase::removeEffect_l(const sp& effect, bool release) { - ALOGV("removeEffect_l() %p effect %p", this, effect.get()); + ALOGV("%s %p effect %p", __FUNCTION__, this, effect.get()); effect_descriptor_t desc = effect->desc(); if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { detachAuxEffect_l(effect->id()); @@ -1382,7 +1397,7 @@ void AudioFlinger::ThreadBase::removeEffect_l(const sp& effect) { sp chain = effect->chain().promote(); if (chain != 0) { // remove effect chain if removing last effect - if (chain->removeEffect_l(effect) == 0) { + if (chain->removeEffect_l(effect, release) == 0) { removeEffectChain_l(chain); } } else { -- cgit v1.1