ProcessIsolationTest.cpp (9789B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "gtest/gtest.h" 8 #include "mozilla/BasePrincipal.h" 9 #include "mozilla/ExpandedPrincipal.h" 10 #include "mozilla/ExtensionPolicyService.h" 11 #include "mozilla/NullPrincipal.h" 12 #include "mozilla/StaticPrefs_browser.h" 13 #include "mozilla/SystemPrincipal.h" 14 #include "mozilla/dom/ProcessIsolation.h" 15 #include "mozilla/dom/WorkerPrivate.h" 16 #include "mozilla/gtest/MozAssertions.h" 17 #include "mozilla/gtest/MozHelpers.h" 18 19 using namespace mozilla; 20 using namespace mozilla::dom; 21 22 static nsCOMPtr<nsIPrincipal> MakeTestPrincipal(const char* aURI) { 23 nsCOMPtr<nsIURI> uri; 24 MOZ_ALWAYS_SUCCEEDS(NS_NewURI(getter_AddRefs(uri), aURI)); 25 return BasePrincipal::CreateContentPrincipal(uri, {}); 26 } 27 28 namespace { 29 struct RemoteTypes { 30 nsCString mIsolated; 31 nsCString mUnisolated; 32 }; 33 34 struct WorkerExpectation { 35 nsCOMPtr<nsIPrincipal> mPrincipal; 36 WorkerKind mWorkerKind = WorkerKindShared; 37 Result<RemoteTypes, nsresult> mExpected = Err(NS_ERROR_FAILURE); 38 nsCString mCurrentRemoteType = "fakeRemoteType"_ns; 39 40 void Check(bool aUseRemoteSubframes) { 41 nsAutoCString origin; 42 ASSERT_NS_SUCCEEDED(mPrincipal->GetOrigin(origin)); 43 44 nsPrintfCString describe( 45 "origin: %s, workerKind: %s, currentRemoteType: %s, " 46 "useRemoteSubframes: %d", 47 origin.get(), mWorkerKind == WorkerKindShared ? "shared" : "service", 48 mCurrentRemoteType.get(), aUseRemoteSubframes); 49 50 auto result = IsolationOptionsForWorker( 51 mPrincipal, mWorkerKind, mCurrentRemoteType, aUseRemoteSubframes); 52 ASSERT_EQ(result.isOk(), mExpected.isOk()) 53 << "Unexpected status (expected " << (mExpected.isOk() ? "ok" : "err") 54 << ") for " << describe; 55 if (mExpected.isOk()) { 56 const nsCString& expected = aUseRemoteSubframes 57 ? mExpected.inspect().mIsolated 58 : mExpected.inspect().mUnisolated; 59 ASSERT_EQ(result.inspect().mRemoteType, expected) 60 << "Unexpected remote type (expected " << expected << ") for " 61 << describe; 62 } 63 } 64 }; 65 } // namespace 66 67 static nsCString WebIsolatedRemoteType(nsIPrincipal* aPrincipal) { 68 nsAutoCString origin; 69 MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOrigin(origin)); 70 return FISSION_WEB_REMOTE_TYPE + "="_ns + origin; 71 } 72 73 static nsCString CoopCoepRemoteType(nsIPrincipal* aPrincipal) { 74 nsAutoCString origin; 75 MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOrigin(origin)); 76 return WITH_COOP_COEP_REMOTE_TYPE + "="_ns + origin; 77 } 78 79 static nsCString ServiceWorkerIsolatedRemoteType(nsIPrincipal* aPrincipal) { 80 nsAutoCString origin; 81 MOZ_ALWAYS_SUCCEEDS(aPrincipal->GetSiteOrigin(origin)); 82 return SERVICEWORKER_REMOTE_TYPE + "="_ns + origin; 83 } 84 85 TEST(ProcessIsolationTest, WorkerOptions) 86 { 87 // Forcibly enable the privileged mozilla content process for the duration of 88 // the test. 89 MOZ_ALWAYS_SUCCEEDS(Preferences::SetCString( 90 "browser.tabs.remote.separatedMozillaDomains", "addons.mozilla.org")); 91 MOZ_ALWAYS_SUCCEEDS(Preferences::SetBool( 92 "browser.tabs.remote.separatePrivilegedMozillaWebContentProcess", true)); 93 auto cleanup = MakeScopeExit([&] { 94 MOZ_ALWAYS_SUCCEEDS( 95 Preferences::ClearUser("browser.tabs.remote.separatedMozillaDomains")); 96 MOZ_ALWAYS_SUCCEEDS(Preferences::ClearUser( 97 "browser.tabs.remote.separatePrivilegedMozillaWebContentProcess")); 98 }); 99 100 nsCOMPtr<nsIPrincipal> systemPrincipal = SystemPrincipal::Get(); 101 nsCOMPtr<nsIPrincipal> nullPrincipal = 102 NullPrincipal::CreateWithoutOriginAttributes(); 103 nsCOMPtr<nsIPrincipal> secureComPrincipal = 104 MakeTestPrincipal("https://example.com"); 105 nsCOMPtr<nsIPrincipal> secureOrgPrincipal = 106 MakeTestPrincipal("https://example.org"); 107 nsCOMPtr<nsIPrincipal> insecureOrgPrincipal = 108 MakeTestPrincipal("http://example.org"); 109 nsCOMPtr<nsIPrincipal> filePrincipal = 110 MakeTestPrincipal("file:///path/to/dir"); 111 nsCOMPtr<nsIPrincipal> extensionPrincipal = 112 MakeTestPrincipal("moz-extension://fake-uuid"); 113 nsCOMPtr<nsIPrincipal> privilegedMozillaPrincipal = 114 MakeTestPrincipal("https://addons.mozilla.org"); 115 nsCOMPtr<nsIPrincipal> expandedPrincipal = ExpandedPrincipal::Create( 116 nsTArray{secureComPrincipal, extensionPrincipal}, {}); 117 nsCOMPtr<nsIPrincipal> nullSecureComPrecursorPrincipal = 118 NullPrincipal::CreateWithInheritedAttributes(secureComPrincipal); 119 120 nsCString extensionRemoteType = 121 ExtensionPolicyService::GetSingleton().UseRemoteExtensions() 122 ? EXTENSION_REMOTE_TYPE 123 : NOT_REMOTE_TYPE; 124 nsCString fileRemoteType = 125 StaticPrefs::browser_tabs_remote_separateFileUriProcess() 126 ? FILE_REMOTE_TYPE 127 : WEB_REMOTE_TYPE; 128 129 WorkerExpectation expectations[] = { 130 // Neither service not shared workers can have expanded principals 131 {.mPrincipal = expandedPrincipal, 132 .mWorkerKind = WorkerKindService, 133 .mExpected = Err(NS_ERROR_UNEXPECTED)}, 134 {.mPrincipal = expandedPrincipal, 135 .mWorkerKind = WorkerKindShared, 136 .mExpected = Err(NS_ERROR_UNEXPECTED)}, 137 138 // Service workers cannot have system or null principals 139 {.mPrincipal = systemPrincipal, 140 .mWorkerKind = WorkerKindService, 141 .mExpected = Err(NS_ERROR_UNEXPECTED)}, 142 {.mPrincipal = nullPrincipal, 143 .mWorkerKind = WorkerKindService, 144 .mExpected = Err(NS_ERROR_UNEXPECTED)}, 145 {.mPrincipal = nullSecureComPrecursorPrincipal, 146 .mWorkerKind = WorkerKindService, 147 .mExpected = Err(NS_ERROR_UNEXPECTED)}, 148 149 // Service workers with various content principals 150 {.mPrincipal = secureComPrincipal, 151 .mWorkerKind = WorkerKindService, 152 .mExpected = 153 RemoteTypes{ServiceWorkerIsolatedRemoteType(secureComPrincipal), 154 WEB_REMOTE_TYPE}}, 155 {.mPrincipal = secureOrgPrincipal, 156 .mWorkerKind = WorkerKindService, 157 .mExpected = 158 RemoteTypes{ServiceWorkerIsolatedRemoteType(secureOrgPrincipal), 159 WEB_REMOTE_TYPE}}, 160 {.mPrincipal = extensionPrincipal, 161 .mWorkerKind = WorkerKindService, 162 .mExpected = RemoteTypes{extensionRemoteType, extensionRemoteType}}, 163 {.mPrincipal = privilegedMozillaPrincipal, 164 .mWorkerKind = WorkerKindService, 165 .mExpected = RemoteTypes{PRIVILEGEDMOZILLA_REMOTE_TYPE, 166 PRIVILEGEDMOZILLA_REMOTE_TYPE}}, 167 168 // Shared Worker loaded from within a webCOOP+COEP remote type process, 169 // should load elsewhere. 170 {.mPrincipal = secureComPrincipal, 171 .mWorkerKind = WorkerKindShared, 172 .mExpected = RemoteTypes{WebIsolatedRemoteType(secureComPrincipal), 173 WEB_REMOTE_TYPE}, 174 .mCurrentRemoteType = CoopCoepRemoteType(secureComPrincipal)}, 175 176 // Even precursorless null principal should load elsewhere. 177 {.mPrincipal = nullPrincipal, 178 .mWorkerKind = WorkerKindShared, 179 .mExpected = RemoteTypes{WEB_REMOTE_TYPE, WEB_REMOTE_TYPE}, 180 .mCurrentRemoteType = CoopCoepRemoteType(secureComPrincipal)}, 181 182 // System principal shared workers can only load in the parent process or 183 // the privilegedabout remote type. 184 {.mPrincipal = systemPrincipal, 185 .mWorkerKind = WorkerKindShared, 186 .mExpected = RemoteTypes{NOT_REMOTE_TYPE, NOT_REMOTE_TYPE}, 187 .mCurrentRemoteType = NOT_REMOTE_TYPE}, 188 {.mPrincipal = systemPrincipal, 189 .mWorkerKind = WorkerKindShared, 190 .mExpected = RemoteTypes{PRIVILEGEDABOUT_REMOTE_TYPE, 191 PRIVILEGEDABOUT_REMOTE_TYPE}, 192 .mCurrentRemoteType = PRIVILEGEDABOUT_REMOTE_TYPE}, 193 {.mPrincipal = systemPrincipal, 194 .mWorkerKind = WorkerKindShared, 195 .mExpected = Err(NS_ERROR_UNEXPECTED)}, 196 {.mPrincipal = systemPrincipal, 197 .mWorkerKind = WorkerKindShared, 198 .mExpected = Err(NS_ERROR_UNEXPECTED)}, 199 200 // Content principals should load in the appropriate remote types, 201 // ignoring the current remote type. 202 {.mPrincipal = secureComPrincipal, 203 .mWorkerKind = WorkerKindShared, 204 .mExpected = RemoteTypes{WebIsolatedRemoteType(secureComPrincipal), 205 WEB_REMOTE_TYPE}}, 206 {.mPrincipal = secureOrgPrincipal, 207 .mWorkerKind = WorkerKindShared, 208 .mExpected = RemoteTypes{WebIsolatedRemoteType(secureOrgPrincipal), 209 WEB_REMOTE_TYPE}}, 210 {.mPrincipal = insecureOrgPrincipal, 211 .mWorkerKind = WorkerKindShared, 212 .mExpected = RemoteTypes{WebIsolatedRemoteType(insecureOrgPrincipal), 213 WEB_REMOTE_TYPE}}, 214 {.mPrincipal = filePrincipal, 215 .mWorkerKind = WorkerKindShared, 216 .mExpected = RemoteTypes{fileRemoteType, fileRemoteType}}, 217 {.mPrincipal = extensionPrincipal, 218 .mWorkerKind = WorkerKindShared, 219 .mExpected = RemoteTypes{extensionRemoteType, extensionRemoteType}}, 220 {.mPrincipal = privilegedMozillaPrincipal, 221 .mWorkerKind = WorkerKindShared, 222 .mExpected = RemoteTypes{PRIVILEGEDMOZILLA_REMOTE_TYPE, 223 PRIVILEGEDMOZILLA_REMOTE_TYPE}}, 224 {.mPrincipal = nullSecureComPrecursorPrincipal, 225 .mWorkerKind = WorkerKindShared, 226 .mExpected = RemoteTypes{WebIsolatedRemoteType(secureComPrincipal), 227 WEB_REMOTE_TYPE}}, 228 }; 229 230 for (auto& expectation : expectations) { 231 expectation.Check(true); 232 expectation.Check(false); 233 } 234 }