Bug 1706121 - part5 : prevent using MFCDM under the private browsing mode. r=media-playback-reviewers,padenot

For GMP CDM, we will use in-memory storage for it under the private
browsing mode, but we can't do that for MFCDM.

Therefore, we should disable it under the private browsing mode to
prevent any user data leak.

Differential Revision: https://phabricator.services.mozilla.com/D210070
This commit is contained in:
alwu 2024-05-14 18:37:14 +00:00
parent b8619b6348
commit 1f5d7f95bc
10 changed files with 46 additions and 21 deletions

View file

@ -295,8 +295,8 @@ void KeySystemConfig::GetGMPKeySystemConfigs(dom::Promise* aPromise) {
continue; continue;
} }
#endif #endif
requests.AppendElement( requests.AppendElement(KeySystemConfigRequest{
KeySystemConfigRequest{keySystem, DecryptionInfo::Software}); keySystem, DecryptionInfo::Software, false /* IsPrivateBrowsing */});
} }
// Get supported configs // Get supported configs

View file

@ -202,10 +202,14 @@ struct KeySystemConfig {
struct KeySystemConfigRequest final { struct KeySystemConfigRequest final {
KeySystemConfigRequest(const nsAString& aKeySystem, KeySystemConfigRequest(const nsAString& aKeySystem,
KeySystemConfig::DecryptionInfo aDecryption) KeySystemConfig::DecryptionInfo aDecryption,
: mKeySystem(aKeySystem), mDecryption(aDecryption) {} bool aIsPrivateBrowsing)
: mKeySystem(aKeySystem),
mDecryption(aDecryption),
mIsPrivateBrowsing(aIsPrivateBrowsing) {}
const nsString mKeySystem; const nsString mKeySystem;
const KeySystemConfig::DecryptionInfo mDecryption; const KeySystemConfig::DecryptionInfo mDecryption;
const bool mIsPrivateBrowsing;
}; };
KeySystemConfig::SessionType ConvertToKeySystemConfigSessionType( KeySystemConfig::SessionType ConvertToKeySystemConfigSessionType(

View file

@ -62,7 +62,11 @@ MediaKeySession::MediaKeySession(nsPIDOMWindowInner* aParent, MediaKeys* aKeys,
mUninitialized(true), mUninitialized(true),
mKeyStatusMap(new MediaKeyStatusMap(aParent)), mKeyStatusMap(new MediaKeyStatusMap(aParent)),
mExpiration(JS::GenericNaN()), mExpiration(JS::GenericNaN()),
mHardwareDecryption(aHardwareDecryption) { mHardwareDecryption(aHardwareDecryption),
mIsPrivateBrowsing(
aParent->GetExtantDoc() &&
aParent->GetExtantDoc()->NodePrincipal()->GetPrivateBrowsingId() >
0) {
EME_LOG("MediaKeySession[%p,''] ctor", this); EME_LOG("MediaKeySession[%p,''] ctor", this);
MOZ_ASSERT(aParent); MOZ_ASSERT(aParent);
@ -250,8 +254,8 @@ already_AddRefed<Promise> MediaKeySession::GenerateRequest(
// cdm implementation value does not support initDataType as an // cdm implementation value does not support initDataType as an
// Initialization Data Type, return a promise rejected with a // Initialization Data Type, return a promise rejected with a
// NotSupportedError. String comparison is case-sensitive. // NotSupportedError. String comparison is case-sensitive.
MediaKeySystemAccess::KeySystemSupportsInitDataType(mKeySystem, aInitDataType, MediaKeySystemAccess::KeySystemSupportsInitDataType(
mHardwareDecryption) mKeySystem, aInitDataType, mHardwareDecryption, mIsPrivateBrowsing)
->Then(GetMainThreadSerialEventTarget(), __func__, ->Then(GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr<MediaKeySession>{this}, this, [self = RefPtr<MediaKeySession>{this}, this,
initDataType = nsString{aInitDataType}, initDataType = nsString{aInitDataType},

View file

@ -141,6 +141,9 @@ class MediaKeySession final : public DOMEventTargetHelper,
// True if this key session is related with hardware decryption. // True if this key session is related with hardware decryption.
bool mHardwareDecryption; bool mHardwareDecryption;
// True if this media key session is created under a private browsing mode.
const bool mIsPrivateBrowsing;
}; };
} // namespace dom } // namespace dom

View file

@ -233,14 +233,15 @@ static KeySystemConfig::EMECodecString ToEMEAPICodecString(
static RefPtr<KeySystemConfig::SupportedConfigsPromise> static RefPtr<KeySystemConfig::SupportedConfigsPromise>
GetSupportedKeySystemConfigs(const nsAString& aKeySystem, GetSupportedKeySystemConfigs(const nsAString& aKeySystem,
bool aIsHardwareDecryption) { bool aIsHardwareDecryption,
bool aIsPrivateBrowsing) {
using DecryptionInfo = KeySystemConfig::DecryptionInfo; using DecryptionInfo = KeySystemConfig::DecryptionInfo;
nsTArray<KeySystemConfigRequest> requests; nsTArray<KeySystemConfigRequest> requests;
// Software Widevine and Clearkey // Software Widevine and Clearkey
if (IsWidevineKeySystem(aKeySystem) || IsClearkeyKeySystem(aKeySystem)) { if (IsWidevineKeySystem(aKeySystem) || IsClearkeyKeySystem(aKeySystem)) {
requests.AppendElement( requests.AppendElement(KeySystemConfigRequest{
KeySystemConfigRequest{aKeySystem, DecryptionInfo::Software}); aKeySystem, DecryptionInfo::Software, aIsPrivateBrowsing});
} }
#ifdef MOZ_WMF_CDM #ifdef MOZ_WMF_CDM
if (IsPlayReadyEnabled()) { if (IsPlayReadyEnabled()) {
@ -249,21 +250,21 @@ GetSupportedKeySystemConfigs(const nsAString& aKeySystem,
aKeySystem.EqualsLiteral(kPlayReadyKeySystemHardware)) { aKeySystem.EqualsLiteral(kPlayReadyKeySystemHardware)) {
requests.AppendElement( requests.AppendElement(
KeySystemConfigRequest{NS_ConvertUTF8toUTF16(kPlayReadyKeySystemName), KeySystemConfigRequest{NS_ConvertUTF8toUTF16(kPlayReadyKeySystemName),
DecryptionInfo::Software}); DecryptionInfo::Software, aIsPrivateBrowsing});
if (aIsHardwareDecryption) { if (aIsHardwareDecryption) {
requests.AppendElement(KeySystemConfigRequest{ requests.AppendElement(KeySystemConfigRequest{
NS_ConvertUTF8toUTF16(kPlayReadyKeySystemName), NS_ConvertUTF8toUTF16(kPlayReadyKeySystemName),
DecryptionInfo::Hardware}); DecryptionInfo::Hardware, aIsPrivateBrowsing});
requests.AppendElement(KeySystemConfigRequest{ requests.AppendElement(KeySystemConfigRequest{
NS_ConvertUTF8toUTF16(kPlayReadyKeySystemHardware), NS_ConvertUTF8toUTF16(kPlayReadyKeySystemHardware),
DecryptionInfo::Hardware}); DecryptionInfo::Hardware, aIsPrivateBrowsing});
} }
} }
// PlayReady clearlead // PlayReady clearlead
if (aKeySystem.EqualsLiteral(kPlayReadyHardwareClearLeadKeySystemName)) { if (aKeySystem.EqualsLiteral(kPlayReadyHardwareClearLeadKeySystemName)) {
requests.AppendElement(KeySystemConfigRequest{ requests.AppendElement(KeySystemConfigRequest{
NS_ConvertUTF8toUTF16(kPlayReadyHardwareClearLeadKeySystemName), NS_ConvertUTF8toUTF16(kPlayReadyHardwareClearLeadKeySystemName),
DecryptionInfo::Hardware}); DecryptionInfo::Hardware, aIsPrivateBrowsing});
} }
} }
@ -273,13 +274,13 @@ GetSupportedKeySystemConfigs(const nsAString& aKeySystem,
(IsWidevineKeySystem(aKeySystem) && aIsHardwareDecryption)) { (IsWidevineKeySystem(aKeySystem) && aIsHardwareDecryption)) {
requests.AppendElement(KeySystemConfigRequest{ requests.AppendElement(KeySystemConfigRequest{
NS_ConvertUTF8toUTF16(kWidevineExperimentKeySystemName), NS_ConvertUTF8toUTF16(kWidevineExperimentKeySystemName),
DecryptionInfo::Hardware}); DecryptionInfo::Hardware, aIsPrivateBrowsing});
} }
// Widevine clearlead // Widevine clearlead
if (aKeySystem.EqualsLiteral(kWidevineExperiment2KeySystemName)) { if (aKeySystem.EqualsLiteral(kWidevineExperiment2KeySystemName)) {
requests.AppendElement(KeySystemConfigRequest{ requests.AppendElement(KeySystemConfigRequest{
NS_ConvertUTF8toUTF16(kWidevineExperiment2KeySystemName), NS_ConvertUTF8toUTF16(kWidevineExperiment2KeySystemName),
DecryptionInfo::Hardware}); DecryptionInfo::Hardware, aIsPrivateBrowsing});
} }
} }
#endif #endif
@ -289,10 +290,11 @@ GetSupportedKeySystemConfigs(const nsAString& aKeySystem,
/* static */ /* static */
RefPtr<GenericPromise> MediaKeySystemAccess::KeySystemSupportsInitDataType( RefPtr<GenericPromise> MediaKeySystemAccess::KeySystemSupportsInitDataType(
const nsAString& aKeySystem, const nsAString& aInitDataType, const nsAString& aKeySystem, const nsAString& aInitDataType,
bool aIsHardwareDecryption) { bool aIsHardwareDecryption, bool aIsPrivateBrowsing) {
RefPtr<GenericPromise::Private> promise = RefPtr<GenericPromise::Private> promise =
new GenericPromise::Private(__func__); new GenericPromise::Private(__func__);
GetSupportedKeySystemConfigs(aKeySystem, aIsHardwareDecryption) GetSupportedKeySystemConfigs(aKeySystem, aIsHardwareDecryption,
aIsPrivateBrowsing)
->Then(GetMainThreadSerialEventTarget(), __func__, ->Then(GetMainThreadSerialEventTarget(), __func__,
[promise, initDataType = nsString{std::move(aInitDataType)}]( [promise, initDataType = nsString{std::move(aInitDataType)}](
const KeySystemConfig::SupportedConfigsPromise:: const KeySystemConfig::SupportedConfigsPromise::
@ -1068,7 +1070,7 @@ MediaKeySystemAccess::GetSupportedConfig(MediaKeySystemAccessRequest* aRequest,
RefPtr<KeySystemConfig::KeySystemConfigPromise::Private> promise = RefPtr<KeySystemConfig::KeySystemConfigPromise::Private> promise =
new KeySystemConfig::KeySystemConfigPromise::Private(__func__); new KeySystemConfig::KeySystemConfigPromise::Private(__func__);
GetSupportedKeySystemConfigs(aRequest->mKeySystem, GetSupportedKeySystemConfigs(aRequest->mKeySystem,
isHardwareDecryptionRequest) isHardwareDecryptionRequest, aIsPrivateBrowsing)
->Then(GetMainThreadSerialEventTarget(), __func__, ->Then(GetMainThreadSerialEventTarget(), __func__,
[promise, aRequest, document = RefPtr<const Document>{aDocument}]( [promise, aRequest, document = RefPtr<const Document>{aDocument}](
const KeySystemConfig::SupportedConfigsPromise:: const KeySystemConfig::SupportedConfigsPromise::

View file

@ -66,7 +66,7 @@ class MediaKeySystemAccess final : public nsISupports, public nsWrapperCache {
static RefPtr<GenericPromise> KeySystemSupportsInitDataType( static RefPtr<GenericPromise> KeySystemSupportsInitDataType(
const nsAString& aKeySystem, const nsAString& aInitDataType, const nsAString& aKeySystem, const nsAString& aInitDataType,
bool aIsHardwareDecryption); bool aIsHardwareDecryption, bool aIsPrivateBrowsing);
static nsCString ToCString( static nsCString ToCString(
const Sequence<MediaKeySystemConfiguration>& aConfig); const Sequence<MediaKeySystemConfiguration>& aConfig);

View file

@ -60,7 +60,8 @@ WMFCDMCapabilites::GetCapabilities(
RefPtr<MFCDMChild> cdm = new MFCDMChild(request.mKeySystem); RefPtr<MFCDMChild> cdm = new MFCDMChild(request.mKeySystem);
promises.AppendElement(cdm->GetCapabilities(MFCDMCapabilitiesRequest{ promises.AppendElement(cdm->GetCapabilities(MFCDMCapabilitiesRequest{
nsString{request.mKeySystem}, nsString{request.mKeySystem},
request.mDecryption == KeySystemConfig::DecryptionInfo::Hardware})); request.mDecryption == KeySystemConfig::DecryptionInfo::Hardware,
request.mIsPrivateBrowsing}));
mCDMs.AppendElement(std::move(cdm)); mCDMs.AppendElement(std::move(cdm));
} }

View file

@ -774,6 +774,12 @@ void MFCDMParent::GetCapabilities(const nsString& aKeySystem,
return; return;
} }
// MFCDM requires persistent storage, and can't use in-memory storage, it
// can't be used in private browsing.
if (aFlags.contains(CapabilitesFlag::IsPrivateBrowsing)) {
return;
}
ComPtr<IMFContentDecryptionModuleFactory> factory = aFactory; ComPtr<IMFContentDecryptionModuleFactory> factory = aFactory;
if (!factory) { if (!factory) {
RETURN_VOID_IF_FAILED(GetOrCreateFactory(aKeySystem, factory)); RETURN_VOID_IF_FAILED(GetOrCreateFactory(aKeySystem, factory));
@ -1005,6 +1011,9 @@ mozilla::ipc::IPCResult MFCDMParent::RecvGetCapabilities(
if (RequireClearLead(aRequest.keySystem())) { if (RequireClearLead(aRequest.keySystem())) {
flags += CapabilitesFlag::NeedClearLeadCheck; flags += CapabilitesFlag::NeedClearLeadCheck;
} }
if (aRequest.isPrivateBrowsing()) {
flags += CapabilitesFlag::IsPrivateBrowsing;
}
GetCapabilities(aRequest.keySystem(), flags, mFactory.Get(), capabilities); GetCapabilities(aRequest.keySystem(), flags, mFactory.Get(), capabilities);
aResolver(std::move(capabilities)); aResolver(std::move(capabilities));
return IPC_OK(); return IPC_OK();

View file

@ -102,6 +102,7 @@ class MFCDMParent final : public PMFCDMParent {
HarewareDecryption, HarewareDecryption,
NeedHDCPCheck, NeedHDCPCheck,
NeedClearLeadCheck, NeedClearLeadCheck,
IsPrivateBrowsing,
}; };
using CapabilitesFlagSet = EnumSet<CapabilitesFlag, uint8_t>; using CapabilitesFlagSet = EnumSet<CapabilitesFlag, uint8_t>;

View file

@ -100,6 +100,7 @@ union MFCDMSessionResult {
struct MFCDMCapabilitiesRequest { struct MFCDMCapabilitiesRequest {
nsString keySystem; nsString keySystem;
bool isHardwareDecryption; bool isHardwareDecryption;
bool isPrivateBrowsing;
}; };
[ManualDealloc] [ManualDealloc]