From 58b9e7d73c9e2a7a7ff11a4584fd1e1105669831 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Fri, 24 Aug 2018 14:49:33 -0700 Subject: Fix race condition for cas sessions -- DO NOT MERGE Change the session to shared_ptr and use atomic_load/store. Test: POC; CTS MediaCasTest; CTS MediaDrmClearkeyTest# testClearKeyPlaybackMpeg2ts bug: 113027383 Change-Id: I75f4cb33a022f28d45918442d64c5c46df2640ef --- .../plugins/clearkey/ClearKeyCasPlugin.cpp | 24 ++++++++++++---------- drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h | 2 +- .../plugins/clearkey/ClearKeySessionLibrary.cpp | 8 ++++---- .../plugins/clearkey/ClearKeySessionLibrary.h | 10 +++++---- 4 files changed, 24 insertions(+), 20 deletions(-) (limited to 'drm') diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp index e27631fc53..50acc1dab5 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp +++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp @@ -118,9 +118,9 @@ status_t ClearKeyCasPlugin::openSession(CasSessionId* sessionId) { status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) { ALOGV("closeSession: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_CAS_SESSION_NOT_OPENED; } @@ -132,9 +132,9 @@ status_t ClearKeyCasPlugin::setSessionPrivateData( const CasSessionId &sessionId, const CasData & /*data*/) { ALOGV("setSessionPrivateData: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_CAS_SESSION_NOT_OPENED; } return OK; @@ -143,9 +143,9 @@ status_t ClearKeyCasPlugin::setSessionPrivateData( status_t ClearKeyCasPlugin::processEcm( const CasSessionId &sessionId, const CasEcm& ecm) { ALOGV("processEcm: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_CAS_SESSION_NOT_OPENED; } @@ -415,15 +415,15 @@ status_t ClearKeyDescramblerPlugin::setMediaCasSession( const CasSessionId &sessionId) { ALOGV("setMediaCasSession: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { ALOGE("ClearKeyDescramblerPlugin: session not found"); return ERROR_CAS_SESSION_NOT_OPENED; } - mCASSession = session; + std::atomic_store(&mCASSession, session); return OK; } @@ -444,12 +444,14 @@ ssize_t ClearKeyDescramblerPlugin::descramble( subSamplesToString(subSamples, numSubSamples).string(), srcPtr, dstPtr, srcOffset, dstOffset); - if (mCASSession == NULL) { + std::shared_ptr session = std::atomic_load(&mCASSession); + + if (session.get() == nullptr) { ALOGE("Uninitialized CAS session!"); return ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED; } - return mCASSession->decrypt( + return session->decrypt( secure, scramblingControl, numSubSamples, subSamples, (uint8_t*)srcPtr + srcOffset, diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h index b7134e4038..8a9ea83686 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h +++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h @@ -120,7 +120,7 @@ public: AString *errorDetailMsg) override; private: - sp mCASSession; + std::shared_ptr mCASSession; String8 subSamplesToString( SubSample const *subSamples, diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp index faea00816c..9fd2d4de9d 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp +++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp @@ -56,7 +56,7 @@ status_t ClearKeySessionLibrary::addSession( Mutex::Autolock lock(mSessionsLock); - sp session = new ClearKeyCasSession(plugin); + std::shared_ptr session(new ClearKeyCasSession(plugin)); uint8_t *byteArray = (uint8_t *) &mNextSessionId; sessionId->push_back(byteArray[3]); @@ -69,7 +69,7 @@ status_t ClearKeySessionLibrary::addSession( return OK; } -sp ClearKeySessionLibrary::findSession( +std::shared_ptr ClearKeySessionLibrary::findSession( const CasSessionId& sessionId) { Mutex::Autolock lock(mSessionsLock); @@ -88,7 +88,7 @@ void ClearKeySessionLibrary::destroySession(const CasSessionId& sessionId) { return; } - sp session = mIDToSessionMap.valueAt(index); + std::shared_ptr session = mIDToSessionMap.valueAt(index); mIDToSessionMap.removeItemsAt(index); } @@ -96,7 +96,7 @@ void ClearKeySessionLibrary::destroyPlugin(CasPlugin *plugin) { Mutex::Autolock lock(mSessionsLock); for (ssize_t index = mIDToSessionMap.size() - 1; index >= 0; index--) { - sp session = mIDToSessionMap.valueAt(index); + std::shared_ptr session = mIDToSessionMap.valueAt(index); if (session->getPlugin() == plugin) { mIDToSessionMap.removeItemsAt(index); } diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h index 01f5f477e2..a537e63bc0 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h +++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h @@ -32,6 +32,10 @@ class KeyFetcher; class ClearKeyCasSession : public RefBase { public: + explicit ClearKeyCasSession(CasPlugin *plugin); + + virtual ~ClearKeyCasSession(); + ssize_t decrypt( bool secure, DescramblerPlugin::ScramblingControl scramblingControl, @@ -58,8 +62,6 @@ private: friend class ClearKeySessionLibrary; - explicit ClearKeyCasSession(CasPlugin *plugin); - virtual ~ClearKeyCasSession(); CasPlugin* getPlugin() const { return mPlugin; } status_t decryptPayload( const AES_KEY& key, size_t length, size_t offset, char* buffer) const; @@ -73,7 +75,7 @@ public: status_t addSession(CasPlugin *plugin, CasSessionId *sessionId); - sp findSession(const CasSessionId& sessionId); + std::shared_ptr findSession(const CasSessionId& sessionId); void destroySession(const CasSessionId& sessionId); @@ -85,7 +87,7 @@ private: Mutex mSessionsLock; uint32_t mNextSessionId; - KeyedVector> mIDToSessionMap; + KeyedVector> mIDToSessionMap; ClearKeySessionLibrary(); DISALLOW_EVIL_CONSTRUCTORS(ClearKeySessionLibrary); -- cgit v1.2.3