|
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> |
@@ -2130,6 +2140,115 @@ ContentParent::GetTestShellSingleton() |
2130 | 2140 | return static_cast<TestShellParent*>(p); |
2131 | 2141 | } |
2132 | 2142 |
|
| 2143 | +#ifdef XP_MACOSX |
| 2144 | +void |
| 2145 | +ContentParent::AppendSandboxParams(std::vector<std::string> &aArgs) |
| 2146 | +{ |
| 2147 | + nsCOMPtr<nsIProperties> |
| 2148 | + directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID)); |
| 2149 | + if (!directoryService) { |
| 2150 | + MOZ_CRASH("Failed to get the directory service"); |
| 2151 | + } |
| 2152 | + |
| 2153 | + // Indicates the child should startup the sandbox |
| 2154 | + aArgs.push_back("-sbStartup"); |
| 2155 | + |
| 2156 | + // The content sandbox level |
| 2157 | + int contentSandboxLevel = |
| 2158 | + Preferences::GetInt("security.sandbox.content.level"); |
| 2159 | + std::ostringstream os; |
| 2160 | + os << contentSandboxLevel; |
| 2161 | + std::string contentSandboxLevelString = os.str(); |
| 2162 | + aArgs.push_back("-sbLevel"); |
| 2163 | + aArgs.push_back(contentSandboxLevelString); |
| 2164 | + |
| 2165 | + // Sandbox logging |
| 2166 | + if (Preferences::GetBool("security.sandbox.logging.enabled") || |
| 2167 | + PR_GetEnv("MOZ_SANDBOX_LOGGING")) { |
| 2168 | + aArgs.push_back("-sbLogging"); |
| 2169 | + } |
| 2170 | + |
| 2171 | + // For file content processes |
| 2172 | + if (GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE)) { |
| 2173 | + aArgs.push_back("-sbAllowFileAccess"); |
| 2174 | + } |
| 2175 | + |
| 2176 | + // Audio access |
| 2177 | + if (!Preferences::GetBool("media.cubeb.sandbox")) { |
| 2178 | + aArgs.push_back("-sbAllowAudio"); |
| 2179 | + } |
| 2180 | + |
| 2181 | + // .app path (normalized) |
| 2182 | + nsAutoCString appPath; |
| 2183 | + if (!nsMacUtilsImpl::GetAppPath(appPath)) { |
| 2184 | + MOZ_CRASH("Failed to get app dir paths"); |
| 2185 | + } |
| 2186 | + aArgs.push_back("-sbAppPath"); |
| 2187 | + aArgs.push_back(appPath.get()); |
| 2188 | + |
| 2189 | + // TESTING_READ_PATH1 |
| 2190 | + nsAutoCString testingReadPath1; |
| 2191 | + Preferences::GetCString("security.sandbox.content.mac.testing_read_path1", |
| 2192 | + testingReadPath1); |
| 2193 | + if (!testingReadPath1.IsEmpty()) { |
| 2194 | + aArgs.push_back("-sbTestingReadPath"); |
| 2195 | + aArgs.push_back(testingReadPath1.get()); |
| 2196 | + } |
| 2197 | + |
| 2198 | + // TESTING_READ_PATH2 |
| 2199 | + nsAutoCString testingReadPath2; |
| 2200 | + Preferences::GetCString("security.sandbox.content.mac.testing_read_path2", |
| 2201 | + testingReadPath2); |
| 2202 | + if (!testingReadPath2.IsEmpty()) { |
| 2203 | + aArgs.push_back("-sbTestingReadPath"); |
| 2204 | + aArgs.push_back(testingReadPath2.get()); |
| 2205 | + } |
| 2206 | + |
| 2207 | + // TESTING_READ_PATH3, TESTING_READ_PATH4. In development builds, |
| 2208 | + // these are used to whitelist the repo dir and object dir respectively. |
| 2209 | + nsresult rv; |
| 2210 | + if (mozilla::IsDevelopmentBuild()) { |
| 2211 | + // Repo dir |
| 2212 | + nsCOMPtr<nsIFile> repoDir; |
| 2213 | + rv = mozilla::GetRepoDir(getter_AddRefs(repoDir)); |
| 2214 | + if (NS_FAILED(rv)) { |
| 2215 | + MOZ_CRASH("Failed to get path to repo dir"); |
| 2216 | + } |
| 2217 | + nsCString repoDirPath; |
| 2218 | + Unused << repoDir->GetNativePath(repoDirPath); |
| 2219 | + aArgs.push_back("-sbTestingReadPath"); |
| 2220 | + aArgs.push_back(repoDirPath.get()); |
| 2221 | + |
| 2222 | + // Object dir |
| 2223 | + nsCOMPtr<nsIFile> objDir; |
| 2224 | + rv = mozilla::GetObjDir(getter_AddRefs(objDir)); |
| 2225 | + if (NS_FAILED(rv)) { |
| 2226 | + MOZ_CRASH("Failed to get path to build object dir"); |
| 2227 | + } |
| 2228 | + nsCString objDirPath; |
| 2229 | + Unused << objDir->GetNativePath(objDirPath); |
| 2230 | + aArgs.push_back("-sbTestingReadPath"); |
| 2231 | + aArgs.push_back(objDirPath.get()); |
| 2232 | + } |
| 2233 | + |
| 2234 | + // DEBUG_WRITE_DIR |
| 2235 | +#ifdef DEBUG |
| 2236 | + // When a content process dies intentionally (|NoteIntentionalCrash|), for |
| 2237 | + // tests it wants to log that it did this. Allow writing to this location |
| 2238 | + // that the testrunner wants. |
| 2239 | + char *bloatLog = PR_GetEnv("XPCOM_MEM_BLOAT_LOG"); |
| 2240 | + if (bloatLog != nullptr) { |
| 2241 | + // |bloatLog| points to a specific file, but we actually write to a sibling |
| 2242 | + // of that path. |
| 2243 | + nsAutoCString bloatDirectoryPath = |
| 2244 | + nsMacUtilsImpl::GetDirectoryPath(bloatLog); |
| 2245 | + aArgs.push_back("-sbDebugWriteDir"); |
| 2246 | + aArgs.push_back(bloatDirectoryPath.get()); |
| 2247 | + } |
| 2248 | +#endif // DEBUG |
| 2249 | +} |
| 2250 | +#endif // XP_MACOSX |
| 2251 | + |
2133 | 2252 | bool |
2134 | 2253 | ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */) |
2135 | 2254 | { |
@@ -2218,6 +2337,12 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR |
2218 | 2337 | extraArgs.push_back("-safeMode"); |
2219 | 2338 | } |
2220 | 2339 |
|
| 2340 | +#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) |
| 2341 | + if (sEarlySandboxInit && IsContentSandboxEnabled()) { |
| 2342 | + AppendSandboxParams(extraArgs); |
| 2343 | + } |
| 2344 | +#endif |
| 2345 | + |
2221 | 2346 | nsCString parentBuildID(mozilla::PlatformBuildID()); |
2222 | 2347 | extraArgs.push_back("-parentBuildID"); |
2223 | 2348 | extraArgs.push_back(parentBuildID.get()); |
@@ -2337,6 +2462,17 @@ ContentParent::ContentParent(ContentParent* aOpener, |
2337 | 2462 | NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
2338 | 2463 | bool isFile = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE); |
2339 | 2464 | mSubprocess = new ContentProcessHost(this, isFile); |
| 2465 | + |
| 2466 | +#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) |
| 2467 | + // sEarlySandboxInit is statically initialized to false. |
| 2468 | + // Once we've set it to true due to the pref, avoid checking the |
| 2469 | + // pref on subsequent calls. As a result, changing the earlyinit |
| 2470 | + // pref requires restarting the browser to take effect. |
| 2471 | + if (!ContentParent::sEarlySandboxInit) { |
| 2472 | + ContentParent::sEarlySandboxInit = |
| 2473 | + Preferences::GetBool("security.sandbox.content.mac.earlyinit"); |
| 2474 | + } |
| 2475 | +#endif |
2340 | 2476 | } |
2341 | 2477 |
|
2342 | 2478 | ContentParent::~ContentParent() |
@@ -2607,6 +2743,12 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority) |
2607 | 2743 | // of value to take effect. |
2608 | 2744 | shouldSandbox = IsContentSandboxEnabled(); |
2609 | 2745 |
|
| 2746 | +#ifdef XP_MACOSX |
| 2747 | + // If the sandbox was initialized during content process |
| 2748 | + // startup, we must not send the SetProcessSandbox message. |
| 2749 | + shouldSandbox = shouldSandbox && !sEarlySandboxInit; |
| 2750 | +#endif |
| 2751 | + |
2610 | 2752 | #ifdef XP_LINUX |
2611 | 2753 | if (shouldSandbox) { |
2612 | 2754 | MOZ_ASSERT(!mSandboxBroker); |
|
0 commit comments