mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-04 18:29:29 +02:00
This new backend shares more logic in common with the existing logic in ProcessIsolation for navigations. This means that it will have support for precursor principals and alternative process isolation behaviors like IsolateHighValue on Android. The logic around custom protocols like web+ and ext+ URIs has been removed in the new patch, as these will never be used as the principals for globals. The handling in E10SUtils was just for handling predicting remote types for URIs before the load has started, which is not relevant for Workers. In a future patch we may want to also switch over the prediction logic which still uses E10SUtils to also use the ProcessIsolation backend, however it is more different due to the need to handle arbitrary input URLs, rather than result principals, so the benefit will be smaller. Differential Revision: https://phabricator.services.mozilla.com/D187227
234 lines
9.6 KiB
C++
234 lines
9.6 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "gtest/gtest.h"
|
|
#include "mozilla/BasePrincipal.h"
|
|
#include "mozilla/dom/ProcessIsolation.h"
|
|
#include "mozilla/dom/WorkerPrivate.h"
|
|
#include "mozilla/ExpandedPrincipal.h"
|
|
#include "mozilla/ExtensionPolicyService.h"
|
|
#include "mozilla/gtest/MozAssertions.h"
|
|
#include "mozilla/gtest/MozHelpers.h"
|
|
#include "mozilla/NullPrincipal.h"
|
|
#include "mozilla/SystemPrincipal.h"
|
|
#include "mozilla/StaticPrefs_browser.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
|
|
static nsCOMPtr<nsIPrincipal> MakeTestPrincipal(const char* aURI) {
|
|
nsCOMPtr<nsIURI> uri;
|
|
MOZ_ALWAYS_SUCCEEDS(NS_NewURI(getter_AddRefs(uri), aURI));
|
|
return BasePrincipal::CreateContentPrincipal(uri, {});
|
|
}
|
|
|
|
namespace {
|
|
struct RemoteTypes {
|
|
nsCString mIsolated;
|
|
nsCString mUnisolated;
|
|
};
|
|
|
|
struct WorkerExpectation {
|
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
|
WorkerKind mWorkerKind = WorkerKindShared;
|
|
Result<RemoteTypes, nsresult> mExpected = Err(NS_ERROR_FAILURE);
|
|
nsCString mCurrentRemoteType = "fakeRemoteType"_ns;
|
|
|
|
void Check(bool aUseRemoteSubframes) {
|
|
nsAutoCString origin;
|
|
ASSERT_NS_SUCCEEDED(mPrincipal->GetOrigin(origin));
|
|
|
|
nsPrintfCString describe(
|
|
"origin: %s, workerKind: %s, currentRemoteType: %s, "
|
|
"useRemoteSubframes: %d",
|
|
origin.get(), mWorkerKind == WorkerKindShared ? "shared" : "service",
|
|
mCurrentRemoteType.get(), aUseRemoteSubframes);
|
|
|
|
auto result = IsolationOptionsForWorker(
|
|
mPrincipal, mWorkerKind, mCurrentRemoteType, aUseRemoteSubframes);
|
|
ASSERT_EQ(result.isOk(), mExpected.isOk())
|
|
<< "Unexpected status (expected " << (mExpected.isOk() ? "ok" : "err")
|
|
<< ") for " << describe;
|
|
if (mExpected.isOk()) {
|
|
const nsCString& expected = aUseRemoteSubframes
|
|
? mExpected.inspect().mIsolated
|
|
: mExpected.inspect().mUnisolated;
|
|
ASSERT_EQ(result.inspect().mRemoteType, expected)
|
|
<< "Unexpected remote type (expected " << expected << ") for "
|
|
<< describe;
|
|
}
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
static nsCString WebIsolatedRemoteType(nsIPrincipal* aPrincipal) {
|
|
nsAutoCString origin;
|
|
MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOrigin(origin));
|
|
return FISSION_WEB_REMOTE_TYPE + "="_ns + origin;
|
|
}
|
|
|
|
static nsCString CoopCoepRemoteType(nsIPrincipal* aPrincipal) {
|
|
nsAutoCString origin;
|
|
MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOrigin(origin));
|
|
return WITH_COOP_COEP_REMOTE_TYPE + "="_ns + origin;
|
|
}
|
|
|
|
static nsCString ServiceWorkerIsolatedRemoteType(nsIPrincipal* aPrincipal) {
|
|
nsAutoCString origin;
|
|
MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOrigin(origin));
|
|
return SERVICEWORKER_REMOTE_TYPE + "="_ns + origin;
|
|
}
|
|
|
|
TEST(ProcessIsolationTest, WorkerOptions)
|
|
{
|
|
// Forcibly enable the privileged mozilla content process for the duration of
|
|
// the test.
|
|
MOZ_ALWAYS_SUCCEEDS(Preferences::SetCString(
|
|
"browser.tabs.remote.separatedMozillaDomains", "addons.mozilla.org"));
|
|
MOZ_ALWAYS_SUCCEEDS(Preferences::SetBool(
|
|
"browser.tabs.remote.separatePrivilegedMozillaWebContentProcess", true));
|
|
auto cleanup = MakeScopeExit([&] {
|
|
MOZ_ALWAYS_SUCCEEDS(
|
|
Preferences::ClearUser("browser.tabs.remote.separatedMozillaDomains"));
|
|
MOZ_ALWAYS_SUCCEEDS(Preferences::ClearUser(
|
|
"browser.tabs.remote.separatePrivilegedMozillaWebContentProcess"));
|
|
});
|
|
|
|
nsCOMPtr<nsIPrincipal> systemPrincipal = SystemPrincipal::Get();
|
|
nsCOMPtr<nsIPrincipal> nullPrincipal =
|
|
NullPrincipal::CreateWithoutOriginAttributes();
|
|
nsCOMPtr<nsIPrincipal> secureComPrincipal =
|
|
MakeTestPrincipal("https://example.com");
|
|
nsCOMPtr<nsIPrincipal> secureOrgPrincipal =
|
|
MakeTestPrincipal("https://example.org");
|
|
nsCOMPtr<nsIPrincipal> insecureOrgPrincipal =
|
|
MakeTestPrincipal("http://example.org");
|
|
nsCOMPtr<nsIPrincipal> filePrincipal =
|
|
MakeTestPrincipal("file:///path/to/dir");
|
|
nsCOMPtr<nsIPrincipal> extensionPrincipal =
|
|
MakeTestPrincipal("moz-extension://fake-uuid");
|
|
nsCOMPtr<nsIPrincipal> privilegedMozillaPrincipal =
|
|
MakeTestPrincipal("https://addons.mozilla.org");
|
|
nsCOMPtr<nsIPrincipal> expandedPrincipal = ExpandedPrincipal::Create(
|
|
nsTArray{secureComPrincipal, extensionPrincipal}, {});
|
|
nsCOMPtr<nsIPrincipal> nullSecureComPrecursorPrincipal =
|
|
NullPrincipal::CreateWithInheritedAttributes(secureComPrincipal);
|
|
|
|
nsCString extensionRemoteType =
|
|
ExtensionPolicyService::GetSingleton().UseRemoteExtensions()
|
|
? EXTENSION_REMOTE_TYPE
|
|
: NOT_REMOTE_TYPE;
|
|
nsCString fileRemoteType =
|
|
StaticPrefs::browser_tabs_remote_separateFileUriProcess()
|
|
? FILE_REMOTE_TYPE
|
|
: WEB_REMOTE_TYPE;
|
|
|
|
WorkerExpectation expectations[] = {
|
|
// Neither service not shared workers can have expanded principals
|
|
{.mPrincipal = expandedPrincipal,
|
|
.mWorkerKind = WorkerKindService,
|
|
.mExpected = Err(NS_ERROR_UNEXPECTED)},
|
|
{.mPrincipal = expandedPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = Err(NS_ERROR_UNEXPECTED)},
|
|
|
|
// Service workers cannot have system or null principals
|
|
{.mPrincipal = systemPrincipal,
|
|
.mWorkerKind = WorkerKindService,
|
|
.mExpected = Err(NS_ERROR_UNEXPECTED)},
|
|
{.mPrincipal = nullPrincipal,
|
|
.mWorkerKind = WorkerKindService,
|
|
.mExpected = Err(NS_ERROR_UNEXPECTED)},
|
|
{.mPrincipal = nullSecureComPrecursorPrincipal,
|
|
.mWorkerKind = WorkerKindService,
|
|
.mExpected = Err(NS_ERROR_UNEXPECTED)},
|
|
|
|
// Service workers with various content principals
|
|
{.mPrincipal = secureComPrincipal,
|
|
.mWorkerKind = WorkerKindService,
|
|
.mExpected =
|
|
RemoteTypes{ServiceWorkerIsolatedRemoteType(secureComPrincipal),
|
|
WEB_REMOTE_TYPE}},
|
|
{.mPrincipal = secureOrgPrincipal,
|
|
.mWorkerKind = WorkerKindService,
|
|
.mExpected =
|
|
RemoteTypes{ServiceWorkerIsolatedRemoteType(secureOrgPrincipal),
|
|
WEB_REMOTE_TYPE}},
|
|
{.mPrincipal = extensionPrincipal,
|
|
.mWorkerKind = WorkerKindService,
|
|
.mExpected = RemoteTypes{extensionRemoteType, extensionRemoteType}},
|
|
{.mPrincipal = privilegedMozillaPrincipal,
|
|
.mWorkerKind = WorkerKindService,
|
|
.mExpected = RemoteTypes{PRIVILEGEDMOZILLA_REMOTE_TYPE,
|
|
PRIVILEGEDMOZILLA_REMOTE_TYPE}},
|
|
|
|
// Shared Worker loaded from within a webCOOP+COEP remote type process,
|
|
// should load elsewhere.
|
|
{.mPrincipal = secureComPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{WebIsolatedRemoteType(secureComPrincipal),
|
|
WEB_REMOTE_TYPE},
|
|
.mCurrentRemoteType = CoopCoepRemoteType(secureComPrincipal)},
|
|
|
|
// Even precursorless null principal should load elsewhere.
|
|
{.mPrincipal = nullPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{WEB_REMOTE_TYPE, WEB_REMOTE_TYPE},
|
|
.mCurrentRemoteType = CoopCoepRemoteType(secureComPrincipal)},
|
|
|
|
// System principal shared workers can only load in the parent process or
|
|
// the privilegedabout remote type.
|
|
{.mPrincipal = systemPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{NOT_REMOTE_TYPE, NOT_REMOTE_TYPE},
|
|
.mCurrentRemoteType = NOT_REMOTE_TYPE},
|
|
{.mPrincipal = systemPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{PRIVILEGEDABOUT_REMOTE_TYPE,
|
|
PRIVILEGEDABOUT_REMOTE_TYPE},
|
|
.mCurrentRemoteType = PRIVILEGEDABOUT_REMOTE_TYPE},
|
|
{.mPrincipal = systemPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = Err(NS_ERROR_UNEXPECTED)},
|
|
{.mPrincipal = systemPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = Err(NS_ERROR_UNEXPECTED)},
|
|
|
|
// Content principals should load in the appropriate remote types,
|
|
// ignoring the current remote type.
|
|
{.mPrincipal = secureComPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{WebIsolatedRemoteType(secureComPrincipal),
|
|
WEB_REMOTE_TYPE}},
|
|
{.mPrincipal = secureOrgPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{WebIsolatedRemoteType(secureOrgPrincipal),
|
|
WEB_REMOTE_TYPE}},
|
|
{.mPrincipal = insecureOrgPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{WebIsolatedRemoteType(insecureOrgPrincipal),
|
|
WEB_REMOTE_TYPE}},
|
|
{.mPrincipal = filePrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{fileRemoteType, fileRemoteType}},
|
|
{.mPrincipal = extensionPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{extensionRemoteType, extensionRemoteType}},
|
|
{.mPrincipal = privilegedMozillaPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{PRIVILEGEDMOZILLA_REMOTE_TYPE,
|
|
PRIVILEGEDMOZILLA_REMOTE_TYPE}},
|
|
{.mPrincipal = nullSecureComPrecursorPrincipal,
|
|
.mWorkerKind = WorkerKindShared,
|
|
.mExpected = RemoteTypes{WebIsolatedRemoteType(secureComPrincipal),
|
|
WEB_REMOTE_TYPE}},
|
|
};
|
|
|
|
for (auto& expectation : expectations) {
|
|
expectation.Check(true);
|
|
expectation.Check(false);
|
|
}
|
|
}
|