|
110 | 110 | #include "mozilla/Unused.h" |
111 | 111 | #include "mozilla/HangDetails.h" |
112 | 112 | #include "nsAnonymousTemporaryFile.h" |
| 113 | +#include "nsAppDirectoryServiceDefs.h" |
113 | 114 | #include "nsAppRunner.h" |
114 | 115 | #include "nsCDefaultURIFixup.h" |
115 | 116 | #include "nsCExternalHandlerService.h" |
|
119 | 120 | #include "nsConsoleService.h" |
120 | 121 | #include "nsContentUtils.h" |
121 | 122 | #include "nsDebugImpl.h" |
| 123 | +#include "nsDirectoryService.h" |
122 | 124 | #include "nsDirectoryServiceDefs.h" |
123 | 125 | #include "nsEmbedCID.h" |
124 | 126 | #include "nsFrameLoader.h" |
|
214 | 216 | #include "signaling/src/peerconnection/WebrtcGlobalParent.h" |
215 | 217 | #endif |
216 | 218 |
|
| 219 | +#if defined(XP_MACOSX) |
| 220 | +#include "nsMacUtilsImpl.h" |
| 221 | +#endif |
| 222 | + |
217 | 223 | #if defined(ANDROID) || defined(LINUX) |
218 | 224 | #include "nsSystemInfo.h" |
219 | 225 | #endif |
@@ -609,6 +615,10 @@ static const char* sObserverTopics[] = { |
609 | 615 | "clear-site-data-reload-needed", |
610 | 616 | }; |
611 | 617 |
|
| 618 | +#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) |
| 619 | +bool ContentParent::sEarlySandboxInit = false; |
| 620 | +#endif |
| 621 | + |
612 | 622 | // PreallocateProcess is called by the PreallocatedProcessManager. |
613 | 623 | // ContentParent then takes this process back within GetNewOrUsedBrowserProcess. |
614 | 624 | /*static*/ already_AddRefed<ContentParent> |
@@ -2145,6 +2155,115 @@ ContentParent::GetTestShellSingleton() |
2145 | 2155 | return static_cast<TestShellParent*>(p); |
2146 | 2156 | } |
2147 | 2157 |
|
| 2158 | +#ifdef XP_MACOSX |
| 2159 | +void |
| 2160 | +ContentParent::AppendSandboxParams(std::vector<std::string> &aArgs) |
| 2161 | +{ |
| 2162 | + nsCOMPtr<nsIProperties> |
| 2163 | + directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID)); |
| 2164 | + if (!directoryService) { |
| 2165 | + MOZ_CRASH("Failed to get the directory service"); |
| 2166 | + } |
| 2167 | + |
| 2168 | + // Indicates the child should startup the sandbox |
| 2169 | + aArgs.push_back("-sbStartup"); |
| 2170 | + |
| 2171 | + // The content sandbox level |
| 2172 | + int contentSandboxLevel = |
| 2173 | + Preferences::GetInt("security.sandbox.content.level"); |
| 2174 | + std::ostringstream os; |
| 2175 | + os << contentSandboxLevel; |
| 2176 | + std::string contentSandboxLevelString = os.str(); |
| 2177 | + aArgs.push_back("-sbLevel"); |
| 2178 | + aArgs.push_back(contentSandboxLevelString); |
| 2179 | + |
| 2180 | + // Sandbox logging |
| 2181 | + if (Preferences::GetBool("security.sandbox.logging.enabled") || |
| 2182 | + PR_GetEnv("MOZ_SANDBOX_LOGGING")) { |
| 2183 | + aArgs.push_back("-sbLogging"); |
| 2184 | + } |
| 2185 | + |
| 2186 | + // For file content processes |
| 2187 | + if (GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE)) { |
| 2188 | + aArgs.push_back("-sbAllowFileAccess"); |
| 2189 | + } |
| 2190 | + |
| 2191 | + // Audio access |
| 2192 | + if (!Preferences::GetBool("media.cubeb.sandbox")) { |
| 2193 | + aArgs.push_back("-sbAllowAudio"); |
| 2194 | + } |
| 2195 | + |
| 2196 | + // .app path (normalized) |
| 2197 | + nsAutoCString appPath; |
| 2198 | + if (!nsMacUtilsImpl::GetAppPath(appPath)) { |
| 2199 | + MOZ_CRASH("Failed to get app dir paths"); |
| 2200 | + } |
| 2201 | + aArgs.push_back("-sbAppPath"); |
| 2202 | + aArgs.push_back(appPath.get()); |
| 2203 | + |
| 2204 | + // TESTING_READ_PATH1 |
| 2205 | + nsAutoCString testingReadPath1; |
| 2206 | + Preferences::GetCString("security.sandbox.content.mac.testing_read_path1", |
| 2207 | + testingReadPath1); |
| 2208 | + if (!testingReadPath1.IsEmpty()) { |
| 2209 | + aArgs.push_back("-sbTestingReadPath"); |
| 2210 | + aArgs.push_back(testingReadPath1.get()); |
| 2211 | + } |
| 2212 | + |
| 2213 | + // TESTING_READ_PATH2 |
| 2214 | + nsAutoCString testingReadPath2; |
| 2215 | + Preferences::GetCString("security.sandbox.content.mac.testing_read_path2", |
| 2216 | + testingReadPath2); |
| 2217 | + if (!testingReadPath2.IsEmpty()) { |
| 2218 | + aArgs.push_back("-sbTestingReadPath"); |
| 2219 | + aArgs.push_back(testingReadPath2.get()); |
| 2220 | + } |
| 2221 | + |
| 2222 | + // TESTING_READ_PATH3, TESTING_READ_PATH4. In development builds, |
| 2223 | + // these are used to whitelist the repo dir and object dir respectively. |
| 2224 | + nsresult rv; |
| 2225 | + if (mozilla::IsDevelopmentBuild()) { |
| 2226 | + // Repo dir |
| 2227 | + nsCOMPtr<nsIFile> repoDir; |
| 2228 | + rv = mozilla::GetRepoDir(getter_AddRefs(repoDir)); |
| 2229 | + if (NS_FAILED(rv)) { |
| 2230 | + MOZ_CRASH("Failed to get path to repo dir"); |
| 2231 | + } |
| 2232 | + nsCString repoDirPath; |
| 2233 | + Unused << repoDir->GetNativePath(repoDirPath); |
| 2234 | + aArgs.push_back("-sbTestingReadPath"); |
| 2235 | + aArgs.push_back(repoDirPath.get()); |
| 2236 | + |
| 2237 | + // Object dir |
| 2238 | + nsCOMPtr<nsIFile> objDir; |
| 2239 | + rv = mozilla::GetObjDir(getter_AddRefs(objDir)); |
| 2240 | + if (NS_FAILED(rv)) { |
| 2241 | + MOZ_CRASH("Failed to get path to build object dir"); |
| 2242 | + } |
| 2243 | + nsCString objDirPath; |
| 2244 | + Unused << objDir->GetNativePath(objDirPath); |
| 2245 | + aArgs.push_back("-sbTestingReadPath"); |
| 2246 | + aArgs.push_back(objDirPath.get()); |
| 2247 | + } |
| 2248 | + |
| 2249 | + // DEBUG_WRITE_DIR |
| 2250 | +#ifdef DEBUG |
| 2251 | + // When a content process dies intentionally (|NoteIntentionalCrash|), for |
| 2252 | + // tests it wants to log that it did this. Allow writing to this location |
| 2253 | + // that the testrunner wants. |
| 2254 | + char *bloatLog = PR_GetEnv("XPCOM_MEM_BLOAT_LOG"); |
| 2255 | + if (bloatLog != nullptr) { |
| 2256 | + // |bloatLog| points to a specific file, but we actually write to a sibling |
| 2257 | + // of that path. |
| 2258 | + nsAutoCString bloatDirectoryPath = |
| 2259 | + nsMacUtilsImpl::GetDirectoryPath(bloatLog); |
| 2260 | + aArgs.push_back("-sbDebugWriteDir"); |
| 2261 | + aArgs.push_back(bloatDirectoryPath.get()); |
| 2262 | + } |
| 2263 | +#endif // DEBUG |
| 2264 | +} |
| 2265 | +#endif // XP_MACOSX |
| 2266 | + |
2148 | 2267 | bool |
2149 | 2268 | ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */) |
2150 | 2269 | { |
@@ -2233,6 +2352,12 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR |
2233 | 2352 | extraArgs.push_back("-safeMode"); |
2234 | 2353 | } |
2235 | 2354 |
|
| 2355 | +#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) |
| 2356 | + if (sEarlySandboxInit && IsContentSandboxEnabled()) { |
| 2357 | + AppendSandboxParams(extraArgs); |
| 2358 | + } |
| 2359 | +#endif |
| 2360 | + |
2236 | 2361 | nsCString parentBuildID(mozilla::PlatformBuildID()); |
2237 | 2362 | extraArgs.push_back("-parentBuildID"); |
2238 | 2363 | extraArgs.push_back(parentBuildID.get()); |
@@ -2352,6 +2477,17 @@ ContentParent::ContentParent(ContentParent* aOpener, |
2352 | 2477 | NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
2353 | 2478 | bool isFile = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE); |
2354 | 2479 | mSubprocess = new ContentProcessHost(this, isFile); |
| 2480 | + |
| 2481 | +#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) |
| 2482 | + // sEarlySandboxInit is statically initialized to false. |
| 2483 | + // Once we've set it to true due to the pref, avoid checking the |
| 2484 | + // pref on subsequent calls. As a result, changing the earlyinit |
| 2485 | + // pref requires restarting the browser to take effect. |
| 2486 | + if (!ContentParent::sEarlySandboxInit) { |
| 2487 | + ContentParent::sEarlySandboxInit = |
| 2488 | + Preferences::GetBool("security.sandbox.content.mac.earlyinit"); |
| 2489 | + } |
| 2490 | +#endif |
2355 | 2491 | } |
2356 | 2492 |
|
2357 | 2493 | ContentParent::~ContentParent() |
@@ -2622,6 +2758,12 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority) |
2622 | 2758 | // of value to take effect. |
2623 | 2759 | shouldSandbox = IsContentSandboxEnabled(); |
2624 | 2760 |
|
| 2761 | +#ifdef XP_MACOSX |
| 2762 | + // If the sandbox was initialized during content process |
| 2763 | + // startup, we must not send the SetProcessSandbox message. |
| 2764 | + shouldSandbox = shouldSandbox && !sEarlySandboxInit; |
| 2765 | +#endif |
| 2766 | + |
2625 | 2767 | #ifdef XP_LINUX |
2626 | 2768 | if (shouldSandbox) { |
2627 | 2769 | MOZ_ASSERT(!mSandboxBroker); |
|
0 commit comments