Protect Session ID List With a Lock
(This is a merge of https://widevine-internal-review.googlesource.com/#/c/11405 from the Widevine CDM Repo.) AUPT is revealing a crash when destructing WVDrmPlugin due to multi-threaded contention over the session map. As a fix, we are now protecting access to the map via a mutex. Bug: 17761616 Change-Id: Iddeca657effd3c7f3ff35ce334d7979291667cef
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "utils/Errors.h"
|
||||
#include "utils/KeyedVector.h"
|
||||
#include "utils/List.h"
|
||||
#include "utils/Mutex.h"
|
||||
#include "utils/String8.h"
|
||||
#include "utils/Vector.h"
|
||||
#include "wv_cdm_event_listener.h"
|
||||
@@ -26,6 +27,7 @@ namespace wvdrm {
|
||||
|
||||
using android::KeyedVector;
|
||||
using android::List;
|
||||
using android::Mutex;
|
||||
using android::status_t;
|
||||
using android::String8;
|
||||
using android::Vector;
|
||||
@@ -229,6 +231,7 @@ class WVDrmPlugin : public android::DrmPlugin,
|
||||
|
||||
WvContentDecryptionModule* mCDM;
|
||||
WVGenericCryptoInterface* mCrypto;
|
||||
Mutex mCryptoSessionsMutex;
|
||||
map<CdmSessionId, CryptoSession> mCryptoSessions;
|
||||
|
||||
status_t mapAndNotifyOfCdmResponseType(const Vector<uint8_t>& sessionId,
|
||||
|
||||
@@ -35,17 +35,18 @@ using namespace wvcdm;
|
||||
|
||||
WVDrmPlugin::WVDrmPlugin(WvContentDecryptionModule* cdm,
|
||||
WVGenericCryptoInterface* crypto)
|
||||
: mCDM(cdm), mCrypto(crypto) {}
|
||||
: mCDM(cdm), mCrypto(crypto), mCryptoSessionsMutex(), mCryptoSessions() {}
|
||||
|
||||
WVDrmPlugin::~WVDrmPlugin() {
|
||||
typedef map<CdmSessionId, CryptoSession>::iterator mapIterator;
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
for (mapIterator iter = mCryptoSessions.begin();
|
||||
iter != mCryptoSessions.end();
|
||||
++iter) {
|
||||
bool bRes = mCDM->DetachEventListener(iter->first, this);
|
||||
|
||||
if (!bRes) {
|
||||
ALOGE("Received failure when trying to detach WVDrmPlugin as an event"
|
||||
ALOGE("Received failure when trying to detach WVDrmPlugin as an event "
|
||||
"listener.");
|
||||
}
|
||||
|
||||
@@ -82,7 +83,10 @@ status_t WVDrmPlugin::openSession(Vector<uint8_t>& sessionId) {
|
||||
OEMCrypto_SESSION oecSessionId;
|
||||
istringstream(info[QUERY_KEY_OEMCRYPTO_SESSION_ID]) >> oecSessionId;
|
||||
|
||||
mCryptoSessions[cdmSessionId] = CryptoSession(oecSessionId);
|
||||
{
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
mCryptoSessions[cdmSessionId] = CryptoSession(oecSessionId);
|
||||
}
|
||||
|
||||
success = true;
|
||||
} else {
|
||||
@@ -123,6 +127,7 @@ status_t WVDrmPlugin::closeSession(const Vector<uint8_t>& sessionId) {
|
||||
CdmResponseType res = mCDM->CloseSession(cdmSessionId);
|
||||
|
||||
if (isCdmResponseTypeSuccess(res)) {
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
mCryptoSessions.erase(cdmSessionId);
|
||||
}
|
||||
|
||||
@@ -559,7 +564,12 @@ status_t WVDrmPlugin::getPropertyByteArray(const String8& name,
|
||||
status_t WVDrmPlugin::setPropertyString(const String8& name,
|
||||
const String8& value) {
|
||||
if (name == "securityLevel") {
|
||||
if (mCryptoSessions.size() == 0) {
|
||||
size_t sessionCount = 0;
|
||||
{
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
sessionCount = mCryptoSessions.size();
|
||||
}
|
||||
if (sessionCount == 0) {
|
||||
if (value == QUERY_VALUE_SECURITY_LEVEL_L3.c_str()) {
|
||||
mPropertySet.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3);
|
||||
} else if (value == QUERY_VALUE_SECURITY_LEVEL_L1.c_str()) {
|
||||
@@ -600,7 +610,12 @@ status_t WVDrmPlugin::setPropertyString(const String8& name,
|
||||
return android::BAD_VALUE;
|
||||
}
|
||||
} else if (name == "sessionSharing") {
|
||||
if (mCryptoSessions.size() == 0) {
|
||||
size_t sessionCount = 0;
|
||||
{
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
sessionCount = mCryptoSessions.size();
|
||||
}
|
||||
if (sessionCount == 0) {
|
||||
if (value == kEnable) {
|
||||
mPropertySet.set_is_session_sharing_enabled(true);
|
||||
} else if (value == kDisable) {
|
||||
@@ -637,6 +652,7 @@ status_t WVDrmPlugin::setPropertyByteArray(const String8& name,
|
||||
status_t WVDrmPlugin::setCipherAlgorithm(const Vector<uint8_t>& sessionId,
|
||||
const String8& algorithm) {
|
||||
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
|
||||
if (!mCryptoSessions.count(cdmSessionId)) {
|
||||
return android::ERROR_DRM_SESSION_NOT_OPENED;
|
||||
@@ -656,6 +672,7 @@ status_t WVDrmPlugin::setCipherAlgorithm(const Vector<uint8_t>& sessionId,
|
||||
status_t WVDrmPlugin::setMacAlgorithm(const Vector<uint8_t>& sessionId,
|
||||
const String8& algorithm) {
|
||||
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
|
||||
if (!mCryptoSessions.count(cdmSessionId)) {
|
||||
return android::ERROR_DRM_SESSION_NOT_OPENED;
|
||||
@@ -678,6 +695,7 @@ status_t WVDrmPlugin::encrypt(const Vector<uint8_t>& sessionId,
|
||||
const Vector<uint8_t>& iv,
|
||||
Vector<uint8_t>& output) {
|
||||
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
|
||||
if (!mCryptoSessions.count(cdmSessionId)) {
|
||||
return android::ERROR_DRM_SESSION_NOT_OPENED;
|
||||
@@ -717,6 +735,7 @@ status_t WVDrmPlugin::decrypt(const Vector<uint8_t>& sessionId,
|
||||
const Vector<uint8_t>& iv,
|
||||
Vector<uint8_t>& output) {
|
||||
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
|
||||
if (!mCryptoSessions.count(cdmSessionId)) {
|
||||
return android::ERROR_DRM_SESSION_NOT_OPENED;
|
||||
@@ -755,6 +774,7 @@ status_t WVDrmPlugin::sign(const Vector<uint8_t>& sessionId,
|
||||
const Vector<uint8_t>& message,
|
||||
Vector<uint8_t>& signature) {
|
||||
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
|
||||
if (!mCryptoSessions.count(cdmSessionId)) {
|
||||
return android::ERROR_DRM_SESSION_NOT_OPENED;
|
||||
@@ -810,6 +830,7 @@ status_t WVDrmPlugin::verify(const Vector<uint8_t>& sessionId,
|
||||
const Vector<uint8_t>& signature,
|
||||
bool& match) {
|
||||
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
|
||||
Mutex::Autolock lock(mCryptoSessionsMutex);
|
||||
|
||||
if (!mCryptoSessions.count(cdmSessionId)) {
|
||||
return android::ERROR_DRM_SESSION_NOT_OPENED;
|
||||
|
||||
Reference in New Issue
Block a user