Bug 1265587 - Force keystatuses to be cleared when Widevine keysessions are closed. r=gerald

The Widevine CDM, and I believe the Adobe CDM too probably, do not mark a
session's keys as unusable when a key session is closed. This means that
the CDMCaps' copy of the keys that are usable is wrong, and so if the media
with the same keys is reloaded with the same MediaKeys, Firefox will assume
that the keys are usable before the license for the keys has been
re-negotiated, and so decryption will fail.


MozReview-Commit-ID: 1kTDzwSD8PE

--HG--
extra : rebase_source : 89c480f36bfaec11ceb5ca1e8d798b0ae795eaea
This commit is contained in:
Chris Pearce 2016-04-22 08:31:18 +12:00
parent d4e1cd80bf
commit 0e273ade3c
4 changed files with 32 additions and 0 deletions

View File

@ -5147,6 +5147,9 @@ already_AddRefed<Promise>
HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
ErrorResult& aRv)
{
LOG(LogLevel::Debug, ("%p SetMediaKeys(%p) mMediaKeys=%p mDecoder=%p",
this, aMediaKeys, mMediaKeys.get(), mDecoder.get()));
if (MozAudioCaptured()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;

View File

@ -215,6 +215,19 @@ CDMCallbackProxy::SessionClosed(const nsCString& aSessionId)
{
MOZ_ASSERT(mProxy->IsOnGMPThread());
bool keyStatusesChange = false;
{
CDMCaps::AutoLock caps(mProxy->Capabilites());
keyStatusesChange = caps.RemoveKeysForSession(NS_ConvertUTF8toUTF16(aSessionId));
}
if (keyStatusesChange) {
nsCOMPtr<nsIRunnable> task;
task = NS_NewRunnableMethodWithArg<nsString>(mProxy,
&CDMProxy::OnKeyStatusesChange,
NS_ConvertUTF8toUTF16(aSessionId));
NS_DispatchToMainThread(task);
}
nsCOMPtr<nsIRunnable> task;
task = NS_NewRunnableMethodWithArg<nsString>(mProxy,
&CDMProxy::OnSessionClosed,

View File

@ -243,4 +243,16 @@ CDMCaps::AutoLock::GetSessionIdsForKeyId(const CencKeyId& aKeyId,
}
}
bool
CDMCaps::AutoLock::RemoveKeysForSession(const nsString& aSessionId)
{
bool changed = false;
nsTArray<KeyStatus> statuses;
GetKeyStatusesForSession(aSessionId, statuses);
for (const KeyStatus& status : statuses) {
changed |= SetKeyStatus(status.mId, aSessionId, kGMPUnknown);
}
return changed;
}
} // namespace mozilla

View File

@ -71,6 +71,10 @@ public:
void GetSessionIdsForKeyId(const CencKeyId& aKeyId,
nsTArray<nsCString>& aOutSessionIds);
// Ensures all keys for a session are marked as 'unknown', i.e. removed.
// Returns true if a key status was changed.
bool RemoveKeysForSession(const nsString& aSessionId);
// Sets the capabilities of the CDM. aCaps is the logical OR of the
// GMP_EME_CAP_* flags from gmp-decryption.h.
void SetCaps(uint64_t aCaps);