morgan pushed to branch tor-browser-128.3.0esr-14.0-1 at The Tor Project / Applications / Tor Browser
Commits: a662a454 by Fatih at 2024-10-17T22:22:51+02:00 Bug 1436226: Ignore user prefs and hardware support for media capabilities when RFPTarget::MediaCapabilities is enabled. r=tjr,media-playback-reviewers,padenot
This patch mostly targeted Android, as media.mediasource.vp9.enabled is disabled on only Android and HW support takes precedence over pref, hence leaking HW support for VP9. However, we ended up modifying the patch to ignore prefs or HW support, fixing both possible user pref leak and HW support leak.
Differential Revision: https://phabricator.services.mozilla.com/D221338
- - - - -
5 changed files:
- dom/media/eme/MediaKeySystemAccess.cpp - dom/media/mediacapabilities/MediaCapabilities.cpp - dom/media/mediasource/MediaSource.cpp - dom/media/mediasource/MediaSource.h - dom/media/mediasource/SourceBuffer.cpp
Changes:
===================================== dom/media/eme/MediaKeySystemAccess.cpp ===================================== @@ -319,8 +319,8 @@ static bool CanDecryptAndDecode( CodecType aCodecType, const KeySystemConfig::ContainerSupport& aContainerSupport, const nsTArrayKeySystemConfig::EMECodecString& aCodecs, - const Maybe<CryptoScheme>& aScheme, - DecoderDoctorDiagnostics* aDiagnostics) { + const Maybe<CryptoScheme>& aScheme, DecoderDoctorDiagnostics* aDiagnostics, + Maybe<bool> aShouldResistFingerprinting) { MOZ_ASSERT(aCodecType != Invalid); for (const KeySystemConfig::EMECodecString& codec : aCodecs) { MOZ_ASSERT(!codec.IsEmpty()); @@ -332,7 +332,8 @@ static bool CanDecryptAndDecode(
if (aContainerSupport.Decrypts(codec, aScheme)) { IgnoredErrorResult rv; - MediaSource::IsTypeSupported(aContentType, aDiagnostics, rv); + MediaSource::IsTypeSupported(aContentType, aDiagnostics, rv, + aShouldResistFingerprinting); if (!rv.Failed()) { // GMP can decrypt and is allowed to return compressed samples to // Gecko to decode, and Gecko has a decoder. @@ -709,9 +710,13 @@ static Sequence<MediaKeySystemMediaCapability> GetSupportedCapabilities( // restrictions... const auto& containerSupport = supportedInMP4 ? aKeySystem.mMP4 : aKeySystem.mWebM; + Maybe<bool> shouldResistFingerprinting = + aDocument ? Some(aDocument->ShouldResistFingerprinting( + RFPTarget::MediaCapabilities)) + : Nothing(); if (!CanDecryptAndDecode(aKeySystem.mKeySystem, contentTypeString, majorType, containerSupport, codecs, scheme, - aDiagnostics)) { + aDiagnostics, shouldResistFingerprinting)) { EME_LOG( "MediaKeySystemConfiguration (label='%s') " "MediaKeySystemMediaCapability('%s','%s','%s') unsupported; "
===================================== dom/media/mediacapabilities/MediaCapabilities.cpp ===================================== @@ -577,8 +577,9 @@ Maybe<MediaContainerType> MediaCapabilities::CheckAudioConfiguration(
bool MediaCapabilities::CheckTypeForMediaSource(const nsAString& aType) { IgnoredErrorResult rv; - MediaSource::IsTypeSupported(aType, nullptr /* DecoderDoctorDiagnostics */, - rv); + MediaSource::IsTypeSupported( + aType, nullptr /* DecoderDoctorDiagnostics */, rv, + Some(mParent->ShouldResistFingerprinting(RFPTarget::MediaCapabilities)));
return !rv.Failed(); }
===================================== dom/media/mediasource/MediaSource.cpp ===================================== @@ -23,6 +23,7 @@ #include "mozilla/Sprintf.h" #include "mozilla/StaticPrefs_media.h" #include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/dom/Document.h" #include "mozilla/dom/HTMLMediaElement.h" #include "mozilla/gfx/gfxVars.h" #include "mozilla/mozalloc.h" @@ -133,7 +134,8 @@ static void RecordTypeForTelemetry(const nsAString& aType, /* static */ void MediaSource::IsTypeSupported(const nsAString& aType, DecoderDoctorDiagnostics* aDiagnostics, - ErrorResult& aRv) { + ErrorResult& aRv, + Maybe<bool> aShouldResistFingerprinting) { if (aType.IsEmpty()) { return aRv.ThrowTypeError("Empty type"); } @@ -159,16 +161,25 @@ void MediaSource::IsTypeSupported(const nsAString& aType,
// Now we know that this media type could be played. // MediaSource imposes extra restrictions, and some prefs. + // Avoid leaking information about the fact that it's pref-disabled, + // or that HW acceleration is available (only applicable to VP9 on Android). + bool shouldResistFingerprinting = + aShouldResistFingerprinting.isSome() + ? aShouldResistFingerprinting.value() + : nsContentUtils::ShouldResistFingerprinting( + "Couldn't drill down ShouldResistFingerprinting", + RFPTarget::MediaCapabilities); const MediaMIMEType& mimeType = containerType->Type(); if (mimeType == MEDIAMIMETYPE("video/mp4") || mimeType == MEDIAMIMETYPE("audio/mp4")) { - if (!StaticPrefs::media_mediasource_mp4_enabled()) { + if (!StaticPrefs::media_mediasource_mp4_enabled() && + !shouldResistFingerprinting) { // Don't leak information about the fact that it's pref-disabled; just act // like we can't play it. Or should this throw "Unknown type"? return aRv.ThrowNotSupportedError("Can't play type"); } if (!StaticPrefs::media_mediasource_vp9_enabled() && hasVP9 && - !IsVP9Forced(aDiagnostics)) { + !IsVP9Forced(aDiagnostics) && !shouldResistFingerprinting) { // Don't leak information about the fact that it's pref-disabled; just act // like we can't play it. Or should this throw "Unknown type"? return aRv.ThrowNotSupportedError("Can't play type"); @@ -177,13 +188,14 @@ void MediaSource::IsTypeSupported(const nsAString& aType, return; } if (mimeType == MEDIAMIMETYPE("video/webm")) { - if (!StaticPrefs::media_mediasource_webm_enabled()) { + if (!StaticPrefs::media_mediasource_webm_enabled() && + !shouldResistFingerprinting) { // Don't leak information about the fact that it's pref-disabled; just act // like we can't play it. Or should this throw "Unknown type"? return aRv.ThrowNotSupportedError("Can't play type"); } if (!StaticPrefs::media_mediasource_vp9_enabled() && hasVP9 && - !IsVP9Forced(aDiagnostics)) { + !IsVP9Forced(aDiagnostics) && !shouldResistFingerprinting) { // Don't leak information about the fact that it's pref-disabled; just act // like we can't play it. Or should this throw "Unknown type"? return aRv.ThrowNotSupportedError("Can't play type"); @@ -191,7 +203,8 @@ void MediaSource::IsTypeSupported(const nsAString& aType, return; } if (mimeType == MEDIAMIMETYPE("audio/webm")) { - if (!StaticPrefs::media_mediasource_webm_enabled()) { + if (!StaticPrefs::media_mediasource_webm_enabled() && + !shouldResistFingerprinting) { // Don't leak information about the fact that it's pref-disabled; just act // like we can't play it. Or should this throw "Unknown type"? return aRv.ThrowNotSupportedError("Can't play type"); @@ -280,13 +293,16 @@ void MediaSource::SetDuration(const media::TimeUnit& aDuration) { already_AddRefed<SourceBuffer> MediaSource::AddSourceBuffer( const nsAString& aType, ErrorResult& aRv) { MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr<nsPIDOMWindowInner> window = GetOwner(); + Document* doc = window ? window->GetExtantDoc() : nullptr; DecoderDoctorDiagnostics diagnostics; - IsTypeSupported(aType, &diagnostics, aRv); - RecordTypeForTelemetry(aType, GetOwner()); + IsTypeSupported( + aType, &diagnostics, aRv, + doc ? Some(doc->ShouldResistFingerprinting(RFPTarget::MediaCapabilities)) + : Nothing()); + RecordTypeForTelemetry(aType, window); bool supported = !aRv.Failed(); - diagnostics.StoreFormatDiagnostics( - GetOwner() ? GetOwner()->GetExtantDoc() : nullptr, aType, supported, - __func__); + diagnostics.StoreFormatDiagnostics(doc, aType, supported, __func__); MSE_API("AddSourceBuffer(aType=%s)%s", NS_ConvertUTF16toUTF8(aType).get(), supported ? "" : " [not supported]"); if (!supported) { @@ -433,13 +449,16 @@ bool MediaSource::IsTypeSupported(const GlobalObject& aOwner, MOZ_ASSERT(NS_IsMainThread()); DecoderDoctorDiagnostics diagnostics; IgnoredErrorResult rv; - IsTypeSupported(aType, &diagnostics, rv); - bool supported = !rv.Failed(); nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aOwner.GetAsSupports()); + Document* doc = window ? window->GetExtantDoc() : nullptr; + IsTypeSupported( + aType, &diagnostics, rv, + doc ? Some(doc->ShouldResistFingerprinting(RFPTarget::MediaCapabilities)) + : Nothing()); + bool supported = !rv.Failed(); RecordTypeForTelemetry(aType, window); - diagnostics.StoreFormatDiagnostics(window ? window->GetExtantDoc() : nullptr, - aType, supported, __func__); + diagnostics.StoreFormatDiagnostics(doc, aType, supported, __func__); MOZ_LOG(GetMediaSourceAPILog(), mozilla::LogLevel::Debug, ("MediaSource::%s: IsTypeSupported(aType=%s) %s", __func__, NS_ConvertUTF16toUTF8(aType).get(),
===================================== dom/media/mediasource/MediaSource.h ===================================== @@ -83,7 +83,8 @@ class MediaSource final : public DOMEventTargetHelper, // Throws on aRv if not supported. static void IsTypeSupported(const nsAString& aType, DecoderDoctorDiagnostics* aDiagnostics, - ErrorResult& aRv); + ErrorResult& aRv, + Maybe<bool> aShouldResistFingerprinting);
IMPL_EVENT_HANDLER(sourceopen); IMPL_EVENT_HANDLER(sourceended);
===================================== dom/media/mediasource/SourceBuffer.cpp ===================================== @@ -13,6 +13,7 @@ #include "mozilla/ErrorResult.h" #include "mozilla/FloatingPoint.h" #include "mozilla/Preferences.h" +#include "mozilla/dom/Document.h" #include "mozilla/dom/MediaSourceBinding.h" #include "mozilla/dom/TimeRanges.h" #include "mozilla/dom/TypedArray.h" @@ -385,13 +386,16 @@ void SourceBuffer::ChangeType(const nsAString& aType, ErrorResult& aRv) { // previously) of SourceBuffer objects in the sourceBuffers attribute of // the parent media source , then throw a NotSupportedError exception and // abort these steps. + Document* doc = mMediaSource->GetOwner() + ? mMediaSource->GetOwner()->GetExtantDoc() + : nullptr; DecoderDoctorDiagnostics diagnostics; - MediaSource::IsTypeSupported(aType, &diagnostics, aRv); + MediaSource::IsTypeSupported( + aType, &diagnostics, aRv, + doc ? Some(doc->ShouldResistFingerprinting(RFPTarget::MediaCapabilities)) + : Nothing()); bool supported = !aRv.Failed(); - diagnostics.StoreFormatDiagnostics( - mMediaSource->GetOwner() ? mMediaSource->GetOwner()->GetExtantDoc() - : nullptr, - aType, supported, __func__); + diagnostics.StoreFormatDiagnostics(doc, aType, supported, __func__); MSE_API("ChangeType(aType=%s)%s", NS_ConvertUTF16toUTF8(aType).get(), supported ? "" : " [not supported]"); if (!supported) {
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/a662a454...
tbb-commits@lists.torproject.org