From 49e593d12702a3ffd671402e585dc271cc72d65b Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Fri, 25 Oct 2013 10:50:02 -0700 Subject: [PATCH] Stop policy timer before invoking session destructor The CDM session was being destroyed before the policy timer was stopped and before the session was removed from a list of active sessions. This allowed race conditions, where the policy timer would try to evaluate policy for a closed session. This led to segfaults. b/11338324 Merge of https://widevine-internal-review.googlesource.com/#/c/8240/1 from the widevine cdm repo. Change-Id: Ib159ccfdb763a47da573f5c06c0793c2c63886c4 --- libwvdrmengine/cdm/core/include/cdm_engine.h | 2 +- libwvdrmengine/cdm/core/src/cdm_engine.cpp | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index ca5487b9..96095c87 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -114,7 +114,7 @@ class CdmEngine : public TimerHandler { // timer related methods to drive policy decisions virtual void EnablePolicyTimer(); - virtual void DisablePolicyTimer(); + virtual void DisablePolicyTimer(bool force); virtual void OnTimerEvent(); virtual void OnKeyReleaseEvent(const CdmKeySetId& key_set_id); diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index ccfa0fcb..76543e34 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -29,6 +29,7 @@ CdmEngine::CdmEngine() CdmEngine::~CdmEngine() { CancelSessions(); + DisablePolicyTimer(true); CdmSessionMap::iterator i(sessions_.begin()); for (; i != sessions_.end(); ++i) delete i->second; @@ -98,9 +99,10 @@ CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) { return KEY_ERROR; } - delete iter->second; + CdmSession* session = iter->second; sessions_.erase(session_id); - DisablePolicyTimer(); + DisablePolicyTimer(false); + delete session; return NO_ERROR; } @@ -295,7 +297,7 @@ CdmResponseType CdmEngine::CancelKeyRequest(const CdmSessionId& session_id) { } // TODO(edwinwong, rfrias): unload keys here - DisablePolicyTimer(); + DisablePolicyTimer(false); return NO_ERROR; } @@ -675,8 +677,8 @@ void CdmEngine::EnablePolicyTimer() { policy_timer_.Start(this, kCdmPolicyTimerDurationSeconds); } -void CdmEngine::DisablePolicyTimer() { - if (sessions_.size() == 0 && policy_timer_.IsRunning()) +void CdmEngine::DisablePolicyTimer(bool force) { + if ((sessions_.size() == 0 || force) && policy_timer_.IsRunning()) policy_timer_.Stop(); }