diff options
Diffstat (limited to 'dom')
-rw-r--r-- | dom/base/Document.cpp | 1 | ||||
-rw-r--r-- | dom/media/gmp/ChromiumCDMProxy.cpp | 9 | ||||
-rw-r--r-- | dom/media/gmp/GMPChild.cpp | 11 | ||||
-rw-r--r-- | dom/media/gmp/moz.build | 2 | ||||
-rw-r--r-- | dom/quota/ActorsParent.cpp | 16 | ||||
-rw-r--r-- | dom/security/nsHTTPSOnlyUtils.cpp | 6 | ||||
-rw-r--r-- | dom/security/nsHTTPSOnlyUtils.h | 12 | ||||
-rw-r--r-- | dom/security/test/https-first/browser.ini | 4 | ||||
-rw-r--r-- | dom/security/test/https-first/browser_subdocument_downgrade.js | 60 | ||||
-rw-r--r-- | dom/security/test/https-first/file_empty.html | 1 | ||||
-rw-r--r-- | dom/security/test/https-first/file_subdocument_downgrade.sjs | 8 | ||||
-rw-r--r-- | dom/workers/ScriptLoader.cpp | 25 |
12 files changed, 130 insertions, 25 deletions
diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 3a1575b7df..b510686b1d 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -196,6 +196,7 @@ #include "mozilla/dom/NetErrorInfoBinding.h" #include "mozilla/dom/NodeInfo.h" #include "mozilla/dom/NodeIterator.h" +#include "mozilla/dom/nsHTTPSOnlyUtils.h" #include "mozilla/dom/PContentChild.h" #include "mozilla/dom/PWindowGlobalChild.h" #include "mozilla/dom/PageTransitionEvent.h" diff --git a/dom/media/gmp/ChromiumCDMProxy.cpp b/dom/media/gmp/ChromiumCDMProxy.cpp index 26d0475ad8..debcb71b6f 100644 --- a/dom/media/gmp/ChromiumCDMProxy.cpp +++ b/dom/media/gmp/ChromiumCDMProxy.cpp @@ -7,6 +7,7 @@ #include "ChromiumCDMProxy.h" #include "ChromiumCDMCallbackProxy.h" #include "MediaResult.h" +#include "mozilla/StaticPrefs_media.h" #include "mozilla/dom/MediaKeySession.h" #include "GMPUtils.h" #include "nsPrintfCString.h" @@ -381,13 +382,19 @@ void ChromiumCDMProxy::NotifyOutputProtectionStatus( } uint32_t linkMask{}; - uint32_t protectionMask{}; // Unused/always zeroed. + uint32_t protectionMask{}; if (aCheckStatus == OutputProtectionCheckStatus::CheckSuccessful && aCaptureStatus == OutputProtectionCaptureStatus::CapturePossilbe) { // The result indicates the capture is possible, so set the mask // to indicate this. linkMask |= cdm::OutputLinkTypes::kLinkTypeNetwork; } + // `kProtectionNone` can cause playback to stop if HDCP_V1 is required. Report + // HDCP protection if there's no potential capturing. + if (linkMask == cdm::OutputLinkTypes::kLinkTypeNone && + StaticPrefs::media_widevine_hdcp_protection_mask()) { + protectionMask = cdm::OutputProtectionMethods::kProtectionHDCP; + } mGMPThread->Dispatch(NewRunnableMethod<bool, uint32_t, uint32_t>( "gmp::ChromiumCDMParent::NotifyOutputProtectionStatus", cdm, &gmp::ChromiumCDMParent::NotifyOutputProtectionStatus, diff --git a/dom/media/gmp/GMPChild.cpp b/dom/media/gmp/GMPChild.cpp index 0d485345bc..8cc6503f9c 100644 --- a/dom/media/gmp/GMPChild.cpp +++ b/dom/media/gmp/GMPChild.cpp @@ -38,6 +38,7 @@ #include "nsThreadManager.h" #include "nsXULAppAPI.h" #include "nsIXULRuntime.h" +#include "nsXPCOMPrivate.h" // for XUL_DLL #include "prio.h" #ifdef XP_WIN # include <stdlib.h> // for _exit() @@ -283,15 +284,11 @@ static bool IsFileLeafEqualToASCII(const nsCOMPtr<nsIFile>& aFile, #endif #if defined(XP_WIN) -# define FIREFOX_FILE u"firefox.exe"_ns -# define XUL_LIB_FILE u"xul.dll"_ns -#elif defined(XP_MACOSX) -# define FIREFOX_FILE u"firefox"_ns -# define XUL_LIB_FILE u"XUL"_ns +# define FIREFOX_FILE MOZ_APP_NAME u".exe"_ns #else -# define FIREFOX_FILE u"firefox"_ns -# define XUL_LIB_FILE u"libxul.so"_ns +# define FIREFOX_FILE MOZ_APP_NAME u""_ns #endif +#define XUL_LIB_FILE XUL_DLL u""_ns static nsCOMPtr<nsIFile> GetFirefoxAppPath( nsCOMPtr<nsIFile> aPluginContainerPath) { diff --git a/dom/media/gmp/moz.build b/dom/media/gmp/moz.build index 4557793b4a..cea2951f02 100644 --- a/dom/media/gmp/moz.build +++ b/dom/media/gmp/moz.build @@ -129,6 +129,8 @@ PREPROCESSED_IPDL_SOURCES += [ if CONFIG["OS_TARGET"] in ["WINNT", "Darwin"]: DEFINES["SUPPORT_STORAGE_ID"] = 1 +DEFINES["MOZ_APP_NAME"] = '"%s"' % CONFIG["MOZ_APP_NAME"] + include("/ipc/chromium/chromium-config.mozbuild") if CONFIG["MOZ_SANDBOX"]: diff --git a/dom/quota/ActorsParent.cpp b/dom/quota/ActorsParent.cpp index eb0f8706fd..0d903b490e 100644 --- a/dom/quota/ActorsParent.cpp +++ b/dom/quota/ActorsParent.cpp @@ -3541,13 +3541,25 @@ void QuotaManager::Shutdown() { ScopedLogExtraInfo scope{ScopedLogExtraInfo::kTagContext, "dom::quota::QuotaManager::Shutdown"_ns}; + // We always need to ensure that firefox does not shutdown with a private + // repository still on disk. They are ideally cleaned up on PBM session end + // but, in some cases like PBM autostart (i.e. + // browser.privatebrowsing.autostart), private repository could only be + // cleaned up on shutdown. ClearPrivateRepository below runs a async op and is + // better to do it before we run the ShutdownStorageOp since it expects all + // cleanup operations to be done by that point. We don't need to use the + // returned promise here because `ClearPrivateRepository` registers the + // underlying `ClearPrivateRepositoryOp` in `gNormalOriginOps`. + ClearPrivateRepository(); + // This must be called before `flagShutdownStarted`, it would fail otherwise. // `ShutdownStorageOp` needs to acquire an exclusive directory lock over // entire <profile>/storage which will abort any existing operations and wait // for all existing directory locks to be released. So the shutdown operation // will effectively run after all existing operations. - // We don't need to use the returned promise here because `ShutdownStorage` - // registers `ShudownStorageOp` in `gNormalOriginOps`. + // Similar, to ClearPrivateRepository operation above, ShutdownStorageOp also + // registers it's operation in `gNormalOriginOps` so we don't need to assign + // returned promise. ShutdownStorage(); flagShutdownStarted(); diff --git a/dom/security/nsHTTPSOnlyUtils.cpp b/dom/security/nsHTTPSOnlyUtils.cpp index 8efbaea9ad..1eb5d057d9 100644 --- a/dom/security/nsHTTPSOnlyUtils.cpp +++ b/dom/security/nsHTTPSOnlyUtils.cpp @@ -808,6 +808,12 @@ bool nsHTTPSOnlyUtils::IsEqualURIExceptSchemeAndRef(nsIURI* aHTTPSSchemeURI, return uriEquals; } +/* static */ +uint32_t nsHTTPSOnlyUtils::GetStatusForSubresourceLoad( + uint32_t aHttpsOnlyStatus) { + return aHttpsOnlyStatus & ~nsILoadInfo::HTTPS_ONLY_UPGRADED_HTTPS_FIRST; +} + /*static*/ void nsHTTPSOnlyUtils::PotentiallyClearExemptFlag(nsILoadInfo* aLoadInfo) { // if neither HTTPS-Only nor HTTPS-First mode is enabled, then there is diff --git a/dom/security/nsHTTPSOnlyUtils.h b/dom/security/nsHTTPSOnlyUtils.h index 5cf94ae6a9..b25ef1fa96 100644 --- a/dom/security/nsHTTPSOnlyUtils.h +++ b/dom/security/nsHTTPSOnlyUtils.h @@ -164,6 +164,18 @@ class nsHTTPSOnlyUtils { nsILoadInfo* aLoadInfo); /** + * Determines which HTTPS-Only status flags should get propagated to + * sub-resources or sub-documents. As sub-resources and sub-documents are + * exempt when the top-level document is exempt, we need to copy the "exempt" + * flag. The HTTPS-First "upgraded" flag should not be copied to prevent a + * unwanted downgrade (Bug 1885949). + * @param aHttpsOnlyStatus The HTTPS-Only status of the top-level document. + * @return The HTTPS-Only status that the sub-resource/document should + * receive. + */ + static uint32_t GetStatusForSubresourceLoad(uint32_t aHttpsOnlyStatus); + + /** * Checks a top-level load, if it is exempt by HTTPS-First/ Only * clear exemption flag. * @param aLoadInfo nsILoadInfo of the request diff --git a/dom/security/test/https-first/browser.ini b/dom/security/test/https-first/browser.ini index 9e355423dc..3beeab3766 100644 --- a/dom/security/test/https-first/browser.ini +++ b/dom/security/test/https-first/browser.ini @@ -33,3 +33,7 @@ support-files = test.wav [browser_beforeunload_permit_http.js] support-files = file_beforeunload_permit_http.html +[browser_subdocument_downgrade.js] +support-files = + file_empty.html + file_subdocument_downgrade.sjs diff --git a/dom/security/test/https-first/browser_subdocument_downgrade.js b/dom/security/test/https-first/browser_subdocument_downgrade.js new file mode 100644 index 0000000000..4cb5b4ed2e --- /dev/null +++ b/dom/security/test/https-first/browser_subdocument_downgrade.js @@ -0,0 +1,60 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const EMPTY_URL = + "http://example.com/browser/dom/security/test/https-first/file_empty.html"; +const SUBDOCUMENT_URL = + "https://example.com/browser/dom/security/test/https-first/file_subdocument_downgrade.sjs"; + +add_task(async function test_subdocument_downgrade() { + await SpecialPowers.pushPrefEnv({ + set: [ + // We want to test HTTPS-First + ["dom.security.https_first", true], + // Makes it easier to detect the error + ["security.mixed_content.block_active_content", false], + ], + }); + + // Open a empty document with origin http://example.com, which gets upgraded + // to https://example.com by HTTPS-First and thus is marked as + // HTTPS_ONLY_UPGRADED_HTTPS_FIRST. + await BrowserTestUtils.withNewTab(EMPTY_URL, async browser => { + await SpecialPowers.spawn( + browser, + [SUBDOCUMENT_URL], + async SUBDOCUMENT_URL => { + function isCrossOriginIframe(iframe) { + try { + return !iframe.contentDocument; + } catch (e) { + return true; + } + } + const subdocument = content.document.createElement("iframe"); + // We open https://example.com/.../file_subdocument_downgrade.sjs in a + // iframe, which sends a invalid response if the scheme is https. Thus + // we should get an error. But if we accidentally copy the + // HTTPS_ONLY_UPGRADED_HTTPS_FIRST flag from the parent into the iframe + // loadinfo, HTTPS-First will try to downgrade the iframe. We test that + // this doesn't happen. + subdocument.src = SUBDOCUMENT_URL; + const loadPromise = new Promise(resolve => { + subdocument.addEventListener("load", () => { + ok( + // If the iframe got downgraded, it should now have the origin + // http://example.com, which we can detect as being cross-origin. + !isCrossOriginIframe(subdocument), + "Subdocument should not be downgraded" + ); + resolve(); + }); + }); + content.document.body.appendChild(subdocument); + await loadPromise; + } + ); + }); +}); diff --git a/dom/security/test/https-first/file_empty.html b/dom/security/test/https-first/file_empty.html new file mode 100644 index 0000000000..39d495653e --- /dev/null +++ b/dom/security/test/https-first/file_empty.html @@ -0,0 +1 @@ +<!doctype html><html><body></body></html> diff --git a/dom/security/test/https-first/file_subdocument_downgrade.sjs b/dom/security/test/https-first/file_subdocument_downgrade.sjs new file mode 100644 index 0000000000..53ced94ba8 --- /dev/null +++ b/dom/security/test/https-first/file_subdocument_downgrade.sjs @@ -0,0 +1,8 @@ +function handleRequest(request, response) { + if (request.scheme === "https") { + response.setStatusLine("1.1", 429, "Too Many Requests"); + } else { + response.setHeader("Content-Type", "text/html", false); + response.write("<!doctype html><html><body></body></html>"); + } +} diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index 315be95ffe..2cf48d8498 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -1764,12 +1764,6 @@ void ReportLoadError(ErrorResult& aRv, nsresult aLoadResult, NS_ConvertUTF16toUTF8(aScriptURL).get()); switch (aLoadResult) { - case NS_ERROR_FILE_NOT_FOUND: - case NS_ERROR_NOT_AVAILABLE: - case NS_ERROR_CORRUPTED_CONTENT: - aRv.Throw(NS_ERROR_DOM_NETWORK_ERR); - break; - case NS_ERROR_MALFORMED_URI: case NS_ERROR_DOM_SYNTAX_ERR: aRv.ThrowSyntaxError(err); @@ -1785,7 +1779,7 @@ void ReportLoadError(ErrorResult& aRv, nsresult aLoadResult, // make it impossible for consumers to realize that our error was // NS_BINDING_ABORTED. aRv.Throw(aLoadResult); - return; + break; case NS_ERROR_DOM_BAD_URI: // This is actually a security error. @@ -1793,15 +1787,16 @@ void ReportLoadError(ErrorResult& aRv, nsresult aLoadResult, aRv.ThrowSecurityError(err); break; + case NS_ERROR_FILE_NOT_FOUND: + case NS_ERROR_NOT_AVAILABLE: + case NS_ERROR_CORRUPTED_CONTENT: + case NS_ERROR_DOM_NETWORK_ERR: + // For lack of anything better, go ahead and throw a NetworkError here. + // We don't want to throw a JS exception, because for toplevel script + // loads that would get squelched. default: - // For lack of anything better, go ahead and throw a NetworkError here. - // We don't want to throw a JS exception, because for toplevel script - // loads that would get squelched. - aRv.ThrowNetworkError(nsPrintfCString( - "Failed to load worker script at %s (nsresult = 0x%" PRIx32 ")", - NS_ConvertUTF16toUTF8(aScriptURL).get(), - static_cast<uint32_t>(aLoadResult))); - return; + aRv.Throw(NS_ERROR_DOM_NETWORK_ERR); + break; } } |