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/Effects.h | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'services/audioflinger/Effects.h') diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h index 6f93f81..4d53c0d 100644 --- a/services/audioflinger/Effects.h +++ b/services/audioflinger/Effects.h @@ -45,7 +45,8 @@ public: const wp& chain, effect_descriptor_t *desc, int id, - int sessionId); + audio_session_t sessionId, + bool pinned); virtual ~EffectModule(); enum effect_state { @@ -93,8 +94,9 @@ public: const wp& thread() { return mThread; } status_t addHandle(EffectHandle *handle); - size_t disconnect(EffectHandle *handle, bool unpinIfLast); - size_t removeHandle(EffectHandle *handle); + ssize_t disconnectHandle(EffectHandle *handle, bool unpinIfLast); + ssize_t removeHandle(EffectHandle *handle); + ssize_t removeHandle_l(EffectHandle *handle); const effect_descriptor_t& desc() const { return mDescriptor; } wp& chain() { return mChain; } @@ -120,6 +122,7 @@ public: status_t setOffloaded(bool offloaded, audio_io_handle_t io); bool isOffloaded() const; void addEffectToHal_l(); + void release_l(); void dump(int fd, const Vector& args); @@ -204,12 +207,17 @@ public: bool enabled() const { return mEnabled; } // Getters - int id() const { return mEffect->id(); } + wp effect() const { return mEffect; } + int id() const { + sp effect = mEffect.promote(); + if (effect == 0) { + return 0; + } + return effect->id(); + } int priority() const { return mPriority; } bool hasControl() const { return mHasControl; } - sp effect() const { return mEffect; } - // destroyed_l() must be called with the associated EffectModule mLock held - bool destroyed_l() const { return mDestroyed; } + bool disconnected() const { return mDisconnected; } void dumpToBuffer(char* buffer, size_t size); @@ -218,7 +226,8 @@ protected: EffectHandle(const EffectHandle&); EffectHandle& operator =(const EffectHandle&); - sp mEffect; // pointer to controlled EffectModule + Mutex mLock; // protects IEffect method calls + wp mEffect; // pointer to controlled EffectModule sp mEffectClient; // callback interface for client notifications /*const*/ sp mClient; // client for shared memory allocation, see disconnect() sp mCblkMemory; // shared memory for control block @@ -229,8 +238,7 @@ protected: bool mHasControl; // true if this handle is controlling the effect bool mEnabled; // cached enable state: needed when the effect is // restored after being suspended - bool mDestroyed; // Set to true by destructor. Access with EffectModule - // mLock held + bool mDisconnected; // Set to true by disconnect() }; // the EffectChain class represents a group of effects associated to one audio session. @@ -263,8 +271,15 @@ public: mLock.unlock(); } + status_t createEffect_l(sp& effect, + ThreadBase *thread, + effect_descriptor_t *desc, + int id, + audio_session_t sessionId, + bool pinned); status_t addEffect_l(const sp& handle); - size_t removeEffect_l(const sp& handle); + status_t addEffect_ll(const sp& handle); + size_t removeEffect_l(const sp& handle, bool release = false); int sessionId() const { return mSessionId; } void setSessionId(int sessionId) { mSessionId = sessionId; } -- cgit v1.1