diff options
author | John Rummell <jrummell@chromium.org> | 2020-09-10 00:06:45 +0000 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2020-09-28 08:13:39 +0000 |
commit | b627f77e8597044142e7a39a88a3412ebe1c66a7 (patch) | |
tree | b0f9bdd914dd482880c05d108bb12b26b09a4ea6 | |
parent | 9e5518f06ad0eb0ad55f646fb896bac07a9f4539 (diff) | |
download | qtwebengine-chromium-b627f77e8597044142e7a39a88a3412ebe1c66a7.tar.gz |
[Backport] CVE-2020-15964: Insufficient data validation in media
Manual backport of patch originally reviewed on
https://chromium-review.googlesource.com/c/chromium/src/+/2378889:
Check for context destroyed in MediaKeys
Don't allow calls to proceed once the associated content has been
destroyed.
Bug: 1121414
Test: example in the bug no longer crashes
Change-Id: I3bdeb86f2020f684958b624fcc30438babfb5004
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
5 files changed, 53 insertions, 7 deletions
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc index 82a2c622ebe..15cac6bce28 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc @@ -228,6 +228,13 @@ MediaKeySession* MediaKeys::createSession(ScriptState* script_state, DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ") " << session_type_string; + // If the context for MediaKeys has been destroyed, fail. + if (!GetExecutionContext()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError, + "The context provided is invalid."); + return nullptr; + } + // [RuntimeEnabled] does not work with enum values. So we have to check it // here. See https://crbug.com/871867 for details. if (!RuntimeEnabledFeatures:: @@ -274,6 +281,14 @@ ScriptPromise MediaKeys::setServerCertificate( ScriptState* script_state, const DOMArrayPiece& server_certificate, ExceptionState& exception_state) { + // If the context for MediaKeys has been destroyed, fail. + if (!GetExecutionContext()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError, + "The context provided is invalid."); + return ScriptPromise(); + } + + // From https://w3c.github.io/encrypted-media/#setServerCertificate // The setServerCertificate(serverCertificate) method provides a server // certificate to be used to encrypt messages to the license server. @@ -317,6 +332,15 @@ void MediaKeys::SetServerCertificateTask( ContentDecryptionModuleResult* result) { DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ")"; + // If the context has been destroyed, don't proceed. Try to have the promise + // be rejected. + if (!GetExecutionContext()) { + result->CompleteWithError( + kWebContentDecryptionModuleExceptionInvalidStateError, 0, + "The context provided is invalid."); + return; + } + // 5.1 Let cdm be the cdm during the initialization of this object. WebContentDecryptionModule* cdm = ContentDecryptionModule(); @@ -333,7 +357,15 @@ void MediaKeys::SetServerCertificateTask( ScriptPromise MediaKeys::getStatusForPolicy( ScriptState* script_state, - const MediaKeysPolicy* media_keys_policy) { + const MediaKeysPolicy* media_keys_policy, + ExceptionState& exception_state) { + // If the context for MediaKeys has been destroyed, fail. + if (!GetExecutionContext()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError, + "The context provided is invalid."); + return ScriptPromise(); + } + // TODO(xhwang): Pass MediaKeysPolicy classes all the way to Chromium when // we have more than one policy to check. String min_hdcp_version = media_keys_policy->minHdcpVersion(); @@ -358,6 +390,15 @@ void MediaKeys::GetStatusForPolicyTask(const String& min_hdcp_version, ContentDecryptionModuleResult* result) { DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << ": " << min_hdcp_version; + // If the context has been destroyed, don't proceed. Try to have the promise + // be rejected. + if (!GetExecutionContext()) { + result->CompleteWithError( + kWebContentDecryptionModuleExceptionInvalidStateError, 0, + "The context provided is invalid."); + return; + } + WebContentDecryptionModule* cdm = ContentDecryptionModule(); cdm->GetStatusForPolicy(min_hdcp_version, result->Result()); } diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h index ba2d0093ba8..d24ad3d6e39 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h @@ -71,9 +71,11 @@ class MediaKeys : public ScriptWrappable, ScriptPromise setServerCertificate(ScriptState*, const DOMArrayPiece& server_certificate, - ExceptionState& exception_state); + ExceptionState&); - ScriptPromise getStatusForPolicy(ScriptState*, const MediaKeysPolicy*); + ScriptPromise getStatusForPolicy(ScriptState*, + const MediaKeysPolicy*, + ExceptionState&); // Indicates that the provided HTMLMediaElement wants to use this object. // Returns true if no other HTMLMediaElement currently references this diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc index 0b12f4d3a03..c6e7ff4a754 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc @@ -14,10 +14,12 @@ namespace blink { ScriptPromise MediaKeysGetStatusForPolicy::getStatusForPolicy( ScriptState* script_state, MediaKeys& media_keys, - const MediaKeysPolicy* media_keys_policy) { + const MediaKeysPolicy* media_keys_policy, + ExceptionState& exception_state) { DVLOG(1) << __func__; - return media_keys.getStatusForPolicy(script_state, media_keys_policy); + return media_keys.getStatusForPolicy(script_state, media_keys_policy, + exception_state); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h index 246e7a5aac8..62317f6c037 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h @@ -20,7 +20,8 @@ class MediaKeysGetStatusForPolicy { public: static ScriptPromise getStatusForPolicy(ScriptState*, MediaKeys&, - const MediaKeysPolicy*); + const MediaKeysPolicy*, + ExceptionState&); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl index 15a6ca073ec..671ba323111 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl @@ -8,5 +8,5 @@ ImplementedAs=MediaKeysGetStatusForPolicy, SecureContext ] partial interface MediaKeys { - [Measure, CallWith=ScriptState] Promise<MediaKeyStatus> getStatusForPolicy(MediaKeysPolicy policy); + [Measure, CallWith=ScriptState, RaisesException] Promise<MediaKeyStatus> getStatusForPolicy(MediaKeysPolicy policy); }; |