mirror of
https://github.com/roytam1/UXP.git
synced 2026-05-26 13:58:49 +00:00
Remove content process sandbox code.
This commit is contained in:
@@ -492,32 +492,7 @@ bool
|
||||
DocAccessibleParent::RecvGetWindowedPluginIAccessible(
|
||||
const WindowsHandle& aHwnd, IAccessibleHolder* aPluginCOMProxy)
|
||||
{
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
// We don't actually want the accessible object for aHwnd, but rather the
|
||||
// one that belongs to its child (see HTMLWin32ObjectAccessible).
|
||||
HWND childWnd = ::GetWindow(reinterpret_cast<HWND>(aHwnd), GW_CHILD);
|
||||
if (!childWnd) {
|
||||
// We're seeing this in the wild - the plugin is windowed but we no longer
|
||||
// have a window.
|
||||
return true;
|
||||
}
|
||||
|
||||
IAccessible* rawAccPlugin = nullptr;
|
||||
HRESULT hr = ::AccessibleObjectFromWindow(childWnd, OBJID_WINDOW,
|
||||
IID_IAccessible,
|
||||
(void**)&rawAccPlugin);
|
||||
if (FAILED(hr)) {
|
||||
// This might happen if the plugin doesn't handle WM_GETOBJECT properly.
|
||||
// We should not consider that a failure.
|
||||
return true;
|
||||
}
|
||||
|
||||
aPluginCOMProxy->Set(IAccessibleHolder::COMPtrType(rawAccPlugin));
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
@@ -62,25 +62,6 @@ HTMLWin32ObjectAccessible::HTMLWin32ObjectAccessible(void* aHwnd,
|
||||
{
|
||||
mHwnd = aHwnd;
|
||||
if (mHwnd) {
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
if (XRE_IsContentProcess()) {
|
||||
DocAccessibleChild* ipcDoc = aDoc->IPCDoc();
|
||||
MOZ_ASSERT(ipcDoc);
|
||||
if (!ipcDoc) {
|
||||
return;
|
||||
}
|
||||
|
||||
IAccessibleHolder proxyHolder;
|
||||
if (!ipcDoc->SendGetWindowedPluginIAccessible(
|
||||
reinterpret_cast<uintptr_t>(mHwnd), &proxyHolder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCOMProxy.reset(proxyHolder.Release());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// The plugin is not windowless. In this situation we use
|
||||
// use its inner child owned by the plugin so that we don't get
|
||||
// in an infinite loop, where the WM_GETOBJECT's get forwarded
|
||||
@@ -92,14 +73,6 @@ HTMLWin32ObjectAccessible::HTMLWin32ObjectAccessible(void* aHwnd,
|
||||
void
|
||||
HTMLWin32ObjectAccessible::GetNativeInterface(void** aNativeAccessible)
|
||||
{
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
if (XRE_IsContentProcess()) {
|
||||
RefPtr<IAccessible> addRefed = mCOMProxy.get();
|
||||
addRefed.forget(aNativeAccessible);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mHwnd) {
|
||||
::AccessibleObjectFromWindow(static_cast<HWND>(mHwnd),
|
||||
OBJID_WINDOW, IID_IAccessible,
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
|
||||
#include "BaseAccessibles.h"
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
#include "mozilla/mscom/Ptr.h"
|
||||
#endif
|
||||
|
||||
struct IAccessible;
|
||||
|
||||
namespace mozilla {
|
||||
@@ -59,9 +55,6 @@ public:
|
||||
|
||||
protected:
|
||||
void* mHwnd;
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
mscom::ProxyUniquePtr<IAccessible> mCOMProxy;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
|
||||
@@ -265,12 +265,6 @@ static int do_main(int argc, char* argv[], char* envp[], nsIFile *xreDirectory)
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
sandbox::BrokerServices* brokerServices =
|
||||
sandboxing::GetInitializedBrokerServices();
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
if (!brokerServices) {
|
||||
Output("Couldn't initialize the broker services.\n");
|
||||
return 255;
|
||||
}
|
||||
#endif
|
||||
appData.sandboxBrokerServices = brokerServices;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -265,12 +265,6 @@ static int do_main(int argc, char* argv[], char* envp[], nsIFile *xreDirectory)
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
sandbox::BrokerServices* brokerServices =
|
||||
sandboxing::GetInitializedBrokerServices();
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
if (!brokerServices) {
|
||||
Output("Couldn't initialize the broker services.\n");
|
||||
return 255;
|
||||
}
|
||||
#endif
|
||||
appData.sandboxBrokerServices = brokerServices;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -945,74 +945,6 @@ pref("dom.ipc.plugins.sandbox-level.flash", 2);
|
||||
#else
|
||||
pref("dom.ipc.plugins.sandbox-level.flash", 0);
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
// This controls the strength of the Windows content process sandbox for testing
|
||||
// purposes. This will require a restart.
|
||||
// On windows these levels are:
|
||||
// See - security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
|
||||
// SetSecurityLevelForContentProcess() for what the different settings mean.
|
||||
#if defined(NIGHTLY_BUILD)
|
||||
pref("security.sandbox.content.level", 2);
|
||||
#else
|
||||
pref("security.sandbox.content.level", 1);
|
||||
#endif
|
||||
|
||||
// This controls the depth of stack trace that is logged when Windows sandbox
|
||||
// logging is turned on. This is only currently available for the content
|
||||
// process because the only other sandbox (for GMP) has too strict a policy to
|
||||
// allow stack tracing. This does not require a restart to take effect.
|
||||
pref("security.sandbox.windows.log.stackTraceDepth", 0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
// This pref is discussed in bug 1083344, the naming is inspired from its
|
||||
// Windows counterpart, but on Mac it's an integer which means:
|
||||
// 0 -> "no sandbox"
|
||||
// 1 -> "preliminary content sandboxing enabled: write access to
|
||||
// home directory is prevented"
|
||||
// 2 -> "preliminary content sandboxing enabled with profile protection:
|
||||
// write access to home directory is prevented, read and write access
|
||||
// to ~/Library and profile directories are prevented (excluding
|
||||
// $PROFILE/{extensions,weave})"
|
||||
// This setting is read when the content process is started. On Mac the content
|
||||
// process is killed when all windows are closed, so a change will take effect
|
||||
// when the 1st window is opened.
|
||||
#if defined(NIGHTLY_BUILD)
|
||||
pref("security.sandbox.content.level", 2);
|
||||
#else
|
||||
pref("security.sandbox.content.level", 1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_LINUX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
// This pref is introduced as part of bug 742434, the naming is inspired from
|
||||
// its Windows/Mac counterpart, but on Linux it's an integer which means:
|
||||
// 0 -> "no sandbox"
|
||||
// 1 -> "content sandbox using seccomp-bpf when available"
|
||||
// 2 -> "seccomp-bpf + file broker"
|
||||
// Content sandboxing on Linux is currently in the stage of
|
||||
// 'just getting it enabled', which includes a very permissive whitelist. We
|
||||
// enable seccomp-bpf on nightly to see if everything is running, or if we need
|
||||
// to whitelist more system calls.
|
||||
//
|
||||
// So the purpose of this setting is to allow nightly users to disable the
|
||||
// sandbox while we fix their problems. This way, they won't have to wait for
|
||||
// another nightly release which disables seccomp-bpf again.
|
||||
//
|
||||
// This setting may not be required anymore once we decide to permanently
|
||||
// enable the content sandbox.
|
||||
pref("security.sandbox.content.level", 2);
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
#if defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
// ID (a UUID when set by gecko) that is used to form the name of a
|
||||
// sandbox-writable temporary directory to be used by content processes
|
||||
// when a temporary writable file is required in a level 1 sandbox.
|
||||
pref("security.sandbox.content.tempDirSuffix", "");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// This pref governs whether we attempt to work around problems caused by
|
||||
|
||||
@@ -65,21 +65,6 @@
|
||||
#include "imgLoader.h"
|
||||
#include "GMPServiceChild.h"
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
#if defined(XP_WIN)
|
||||
#define TARGET_SANDBOX_EXPORTS
|
||||
#include "mozilla/sandboxTarget.h"
|
||||
#elif defined(XP_LINUX)
|
||||
#include "mozilla/Sandbox.h"
|
||||
#include "mozilla/SandboxInfo.h"
|
||||
|
||||
// Remove this include with Bug 1104619
|
||||
#include "CubebUtils.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
#include "mozilla/Sandbox.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
#include "mozInlineSpellChecker.h"
|
||||
@@ -1250,192 +1235,11 @@ ContentChild::AllocPProcessHangMonitorChild(Transport* aTransport,
|
||||
return CreateHangMonitorChild(aTransport, aOtherProcess);
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static bool
|
||||
GetAppPaths(nsCString &aAppPath, nsCString &aAppBinaryPath, nsCString &aAppDir)
|
||||
{
|
||||
nsAutoCString appPath;
|
||||
nsAutoCString appBinaryPath(
|
||||
(CommandLine::ForCurrentProcess()->argv()[0]).c_str());
|
||||
|
||||
nsAutoCString::const_iterator start, end;
|
||||
appBinaryPath.BeginReading(start);
|
||||
appBinaryPath.EndReading(end);
|
||||
if (RFindInReadable(NS_LITERAL_CSTRING(".app/Contents/MacOS/"), start, end)) {
|
||||
end = start;
|
||||
++end; ++end; ++end; ++end;
|
||||
appBinaryPath.BeginReading(start);
|
||||
appPath.Assign(Substring(start, end));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> app, appBinary;
|
||||
nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(appPath),
|
||||
true, getter_AddRefs(app));
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(appBinaryPath),
|
||||
true, getter_AddRefs(appBinary));
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> appDir;
|
||||
nsCOMPtr<nsIProperties> dirSvc =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
|
||||
if (!dirSvc) {
|
||||
return false;
|
||||
}
|
||||
rv = dirSvc->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
NS_GET_IID(nsIFile), getter_AddRefs(appDir));
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
bool exists;
|
||||
rv = appDir->Exists(&exists);
|
||||
if (NS_FAILED(rv) || !exists) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isLink;
|
||||
app->IsSymlink(&isLink);
|
||||
if (isLink) {
|
||||
app->GetNativeTarget(aAppPath);
|
||||
} else {
|
||||
app->GetNativePath(aAppPath);
|
||||
}
|
||||
appBinary->IsSymlink(&isLink);
|
||||
if (isLink) {
|
||||
appBinary->GetNativeTarget(aAppBinaryPath);
|
||||
} else {
|
||||
appBinary->GetNativePath(aAppBinaryPath);
|
||||
}
|
||||
appDir->IsSymlink(&isLink);
|
||||
if (isLink) {
|
||||
appDir->GetNativeTarget(aAppDir);
|
||||
} else {
|
||||
appDir->GetNativePath(aAppDir);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
StartMacOSContentSandbox()
|
||||
{
|
||||
int sandboxLevel = Preferences::GetInt("security.sandbox.content.level");
|
||||
if (sandboxLevel < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoCString appPath, appBinaryPath, appDir;
|
||||
if (!GetAppPaths(appPath, appBinaryPath, appDir)) {
|
||||
MOZ_CRASH("Error resolving child process path");
|
||||
}
|
||||
|
||||
// During sandboxed content process startup, before reaching
|
||||
// this point, NS_OS_TEMP_DIR is modified to refer to a sandbox-
|
||||
// writable temporary directory
|
||||
nsCOMPtr<nsIFile> tempDir;
|
||||
nsresult rv = nsDirectoryService::gService->Get(NS_OS_TEMP_DIR,
|
||||
NS_GET_IID(nsIFile), getter_AddRefs(tempDir));
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_CRASH("Failed to get NS_OS_TEMP_DIR");
|
||||
}
|
||||
|
||||
nsAutoCString tempDirPath;
|
||||
tempDir->Normalize();
|
||||
rv = tempDir->GetNativePath(tempDirPath);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_CRASH("Failed to get NS_OS_TEMP_DIR path");
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> profileDir;
|
||||
ContentChild::GetSingleton()->GetProfileDir(getter_AddRefs(profileDir));
|
||||
nsCString profileDirPath;
|
||||
if (profileDir) {
|
||||
rv = profileDir->GetNativePath(profileDirPath);
|
||||
if (NS_FAILED(rv) || profileDirPath.IsEmpty()) {
|
||||
MOZ_CRASH("Failed to get profile path");
|
||||
}
|
||||
}
|
||||
|
||||
MacSandboxInfo info;
|
||||
info.type = MacSandboxType_Content;
|
||||
info.level = info.level = sandboxLevel;
|
||||
info.appPath.assign(appPath.get());
|
||||
info.appBinaryPath.assign(appBinaryPath.get());
|
||||
info.appDir.assign(appDir.get());
|
||||
info.appTempDir.assign(tempDirPath.get());
|
||||
|
||||
if (profileDir) {
|
||||
info.hasSandboxedProfile = true;
|
||||
info.profileDir.assign(profileDirPath.get());
|
||||
} else {
|
||||
info.hasSandboxedProfile = false;
|
||||
}
|
||||
|
||||
std::string err;
|
||||
if (!mozilla::StartMacSandbox(info, err)) {
|
||||
NS_WARNING(err.c_str());
|
||||
MOZ_CRASH("sandbox_init() failed");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
ContentChild::RecvSetProcessSandbox(const MaybeFileDesc& aBroker)
|
||||
{
|
||||
// We may want to move the sandbox initialization somewhere else
|
||||
// at some point; see bug 880808.
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
bool sandboxEnabled = true;
|
||||
#if defined(XP_LINUX)
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 19
|
||||
// For B2G >= KitKat, sandboxing is mandatory; this has already
|
||||
// been enforced by ContentParent::StartUp().
|
||||
MOZ_ASSERT(SandboxInfo::Get().CanSandboxContent());
|
||||
#else
|
||||
// Otherwise, sandboxing is best-effort.
|
||||
if (!SandboxInfo::Get().CanSandboxContent()) {
|
||||
sandboxEnabled = false;
|
||||
} else {
|
||||
// This triggers the initialization of cubeb, which needs to happen
|
||||
// before seccomp is enabled (Bug 1259508). It also increases the startup
|
||||
// time of the content process, because cubeb is usually initialized
|
||||
// when it is actually needed. This call here is no longer required
|
||||
// once Bug 1104619 (remoting audio) is resolved.
|
||||
Unused << CubebUtils::GetCubebContext();
|
||||
}
|
||||
|
||||
#endif /* MOZ_WIDGET_GONK && ANDROID_VERSION >= 19 */
|
||||
if (sandboxEnabled) {
|
||||
int brokerFd = -1;
|
||||
if (aBroker.type() == MaybeFileDesc::TFileDescriptor) {
|
||||
auto fd = aBroker.get_FileDescriptor().ClonePlatformHandle();
|
||||
brokerFd = fd.release();
|
||||
// brokerFd < 0 means to allow direct filesystem access, so
|
||||
// make absolutely sure that doesn't happen if the parent
|
||||
// didn't intend it.
|
||||
MOZ_RELEASE_ASSERT(brokerFd >= 0);
|
||||
}
|
||||
sandboxEnabled = SetContentProcessSandbox(brokerFd);
|
||||
}
|
||||
#elif defined(XP_WIN)
|
||||
mozilla::SandboxTarget::Instance()->StartSandbox();
|
||||
#elif defined(XP_MACOSX)
|
||||
sandboxEnabled = StartMacOSContentSandbox();
|
||||
#endif
|
||||
|
||||
#endif /* MOZ_CONTENT_SANDBOX */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsIWindowProvider.h"
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
#include "nsIFile.h"
|
||||
#endif
|
||||
|
||||
struct ChromePackage;
|
||||
class nsIObserver;
|
||||
struct SubstitutionMapping;
|
||||
@@ -118,19 +114,6 @@ public:
|
||||
|
||||
void GetProcessName(nsACString& aName) const;
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
void GetProfileDir(nsIFile** aProfileDir) const
|
||||
{
|
||||
*aProfileDir = mProfileDir;
|
||||
NS_IF_ADDREF(*aProfileDir);
|
||||
}
|
||||
|
||||
void SetProfileDir(nsIFile* aProfileDir)
|
||||
{
|
||||
mProfileDir = aProfileDir;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool IsAlive() const;
|
||||
|
||||
bool IsShuttingDown() const;
|
||||
@@ -679,10 +662,6 @@ private:
|
||||
nsCOMPtr<nsIDomainPolicy> mPolicy;
|
||||
nsCOMPtr<nsITimer> mForceKillTimer;
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
nsCOMPtr<nsIFile> mProfileDir;
|
||||
#endif
|
||||
|
||||
// Hashtable to keep track of the pending GetFilesHelper objects.
|
||||
// This GetFilesHelperChild objects are removed when RecvGetFilesResponse is
|
||||
// received.
|
||||
|
||||
@@ -230,12 +230,6 @@ using namespace mozilla::system;
|
||||
#include "mozilla/dom/SpeechSynthesisParent.h"
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_LINUX)
|
||||
#include "mozilla/SandboxInfo.h"
|
||||
#include "mozilla/SandboxBroker.h"
|
||||
#include "mozilla/SandboxBrokerPolicyFactory.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_TOOLKIT_SEARCH
|
||||
#include "nsIBrowserSearchService.h"
|
||||
#endif
|
||||
@@ -503,9 +497,6 @@ nsTArray<ContentParent*>* ContentParent::sNonAppContentParents;
|
||||
nsTArray<ContentParent*>* ContentParent::sLargeAllocationContentParents;
|
||||
nsTArray<ContentParent*>* ContentParent::sPrivateContent;
|
||||
StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
|
||||
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
UniquePtr<SandboxBrokerPolicyFactory> ContentParent::sSandboxBrokerPolicyFactory;
|
||||
#endif
|
||||
|
||||
// This is true when subprocess launching is enabled. This is the
|
||||
// case between StartUp() and ShutDown() or JoinAllSubprocesses().
|
||||
@@ -637,18 +628,6 @@ ContentParent::StartUp()
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX) && defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 19
|
||||
// Require sandboxing on B2G >= KitKat. This condition must stay
|
||||
// in sync with ContentChild::RecvSetProcessSandbox.
|
||||
if (!SandboxInfo::Get().CanSandboxContent()) {
|
||||
// MOZ_CRASH strings are only for debug builds; make sure the
|
||||
// message is clear on non-debug builds as well:
|
||||
printf_stderr("Sandboxing support is required on this platform. "
|
||||
"Recompile kernel with CONFIG_SECCOMP_FILTER=y\n");
|
||||
MOZ_CRASH("Sandboxing support is required on this platform.");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Note: This reporter measures all ContentParents.
|
||||
RegisterStrongMemoryReporter(new ContentParentsMemoryReporter());
|
||||
|
||||
@@ -662,10 +641,6 @@ ContentParent::StartUp()
|
||||
PreallocatedProcessManager::AllocateAfterDelay();
|
||||
|
||||
sDisableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
|
||||
|
||||
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
sSandboxBrokerPolicyFactory = MakeUnique<SandboxBrokerPolicyFactory>();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
@@ -674,10 +649,6 @@ ContentParent::ShutDown()
|
||||
// No-op for now. We rely on normal process shutdown and
|
||||
// ClearOnShutdown() to clean up our state.
|
||||
sCanLaunchSubprocesses = false;
|
||||
|
||||
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
sSandboxBrokerPolicyFactory = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
@@ -2244,37 +2215,6 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
bool shouldSandbox = true;
|
||||
MaybeFileDesc brokerFd = void_t();
|
||||
#ifdef XP_LINUX
|
||||
// XXX: Checking the pref here makes it possible to enable/disable sandboxing
|
||||
// during an active session. Currently the pref is only used for testing
|
||||
// purpose. If the decision is made to permanently rely on the pref, this
|
||||
// should be changed so that it is required to restart firefox for the change
|
||||
// of value to take effect.
|
||||
shouldSandbox = (Preferences::GetInt("security.sandbox.content.level") > 0) &&
|
||||
!PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX");
|
||||
|
||||
if (shouldSandbox) {
|
||||
MOZ_ASSERT(!mSandboxBroker);
|
||||
UniquePtr<SandboxBroker::Policy> policy =
|
||||
sSandboxBrokerPolicyFactory->GetContentPolicy(Pid());
|
||||
if (policy) {
|
||||
brokerFd = FileDescriptor();
|
||||
mSandboxBroker = SandboxBroker::Create(Move(policy), Pid(), brokerFd);
|
||||
if (!mSandboxBroker) {
|
||||
KillHard("SandboxBroker::Create failed");
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(static_cast<const FileDescriptor&>(brokerFd).IsValid());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (shouldSandbox && !SendSetProcessSandbox(brokerFd)) {
|
||||
KillHard("SandboxInitFailed");
|
||||
}
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
// Send the info needed to join the browser process's audio session.
|
||||
nsID id;
|
||||
|
||||
@@ -46,11 +46,6 @@ class PRemoteSpellcheckEngineParent;
|
||||
class ProfileGatherer;
|
||||
#endif
|
||||
|
||||
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
class SandboxBroker;
|
||||
class SandboxBrokerPolicyFactory;
|
||||
#endif
|
||||
|
||||
namespace embedding {
|
||||
class PrintingParent;
|
||||
}
|
||||
@@ -1152,12 +1147,6 @@ private:
|
||||
|
||||
UniquePtr<gfx::DriverCrashGuard> mDriverCrashGuard;
|
||||
|
||||
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
mozilla::UniquePtr<SandboxBroker> mSandboxBroker;
|
||||
static mozilla::UniquePtr<SandboxBrokerPolicyFactory>
|
||||
sSandboxBrokerPolicyFactory;
|
||||
#endif
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
RefPtr<embedding::PrintingParent> mPrintingParent;
|
||||
#endif
|
||||
|
||||
@@ -8,127 +8,17 @@
|
||||
|
||||
#include "ContentProcess.h"
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryService.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#endif
|
||||
|
||||
using mozilla::ipc::IOThreadChild;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
|
||||
static bool
|
||||
IsSandboxTempDirRequired()
|
||||
{
|
||||
// On Windows, a sandbox-writable temp directory is only used
|
||||
// for Vista or later with sandbox pref level >= 1.
|
||||
return (IsVistaOrLater() &&
|
||||
(Preferences::GetInt("security.sandbox.content.level") >= 1));
|
||||
}
|
||||
|
||||
static void
|
||||
SetTmpEnvironmentVariable(nsIFile* aValue)
|
||||
{
|
||||
// Save the TMP environment variable so that is is picked up by GetTempPath().
|
||||
// Note that we specifically write to the TMP variable, as that is the first
|
||||
// variable that is checked by GetTempPath() to determine its output.
|
||||
nsAutoString fullTmpPath;
|
||||
nsresult rv = aValue->GetPath(fullTmpPath);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
Unused << NS_WARN_IF(!SetEnvironmentVariableW(L"TMP", fullTmpPath.get()));
|
||||
// We also set TEMP in case there is naughty third-party code that is
|
||||
// referencing the environment variable directly.
|
||||
Unused << NS_WARN_IF(!SetEnvironmentVariableW(L"TEMP", fullTmpPath.get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
static bool
|
||||
IsSandboxTempDirRequired()
|
||||
{
|
||||
// On OSX, use the sandbox-writable temp when the pref level >= 1.
|
||||
return (Preferences::GetInt("security.sandbox.content.level") >= 1);
|
||||
}
|
||||
|
||||
static void
|
||||
SetTmpEnvironmentVariable(nsIFile* aValue)
|
||||
{
|
||||
nsAutoCString fullTmpPath;
|
||||
nsresult rv = aValue->GetNativePath(fullTmpPath);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
Unused << NS_WARN_IF(setenv("TMPDIR", fullTmpPath.get(), 1) != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
static void
|
||||
SetUpSandboxEnvironment()
|
||||
{
|
||||
MOZ_ASSERT(nsDirectoryService::gService,
|
||||
"SetUpSandboxEnvironment relies on nsDirectoryService being initialized");
|
||||
|
||||
if (!IsSandboxTempDirRequired()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> sandboxedContentTemp;
|
||||
nsresult rv =
|
||||
nsDirectoryService::gService->Get(NS_APP_CONTENT_PROCESS_TEMP_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(sandboxedContentTemp));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Change the gecko defined temp directory to our sandbox-writable one.
|
||||
// Undefine returns a failure if the property is not already set.
|
||||
Unused << nsDirectoryService::gService->Undefine(NS_OS_TEMP_DIR);
|
||||
rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, sandboxedContentTemp);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetTmpEnvironmentVariable(sandboxedContentTemp);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ContentProcess::SetAppDir(const nsACString& aPath)
|
||||
{
|
||||
mXREEmbed.SetAppDir(aPath);
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
void
|
||||
ContentProcess::SetProfile(const nsACString& aProfile)
|
||||
{
|
||||
bool flag;
|
||||
nsresult rv =
|
||||
XRE_GetFileFromPath(aProfile.BeginReading(), getter_AddRefs(mProfileDir));
|
||||
if (NS_FAILED(rv) ||
|
||||
NS_FAILED(mProfileDir->Exists(&flag)) || !flag) {
|
||||
NS_WARNING("Invalid profile directory passed to content process.");
|
||||
mProfileDir = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
ContentProcess::Init()
|
||||
{
|
||||
@@ -139,14 +29,6 @@ ContentProcess::Init()
|
||||
mContent.InitXPCOM();
|
||||
mContent.InitGraphicsDeviceData();
|
||||
|
||||
#if (defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
mContent.SetProfileDir(mProfileDir);
|
||||
#endif
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
SetUpSandboxEnvironment();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,18 +39,10 @@ public:
|
||||
|
||||
void SetAppDir(const nsACString& aPath);
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
void SetProfile(const nsACString& aProfile);
|
||||
#endif
|
||||
|
||||
private:
|
||||
ContentChild mContent;
|
||||
mozilla::ipc::ScopedXREEmbed mXREEmbed;
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
nsCOMPtr<nsIFile> mProfileDir;
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// This object initializes and configures COM.
|
||||
mozilla::mscom::MainThreadRuntime mCOMRuntime;
|
||||
|
||||
@@ -112,11 +112,6 @@ if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_TARGET'] == 'Darwin':
|
||||
'mozsandbox',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_CONTENT_SANDBOX'] and CONFIG['OS_ARCH'] == 'Linux':
|
||||
USE_LIBS += [
|
||||
'mozsandbox',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/caps',
|
||||
'/chrome',
|
||||
|
||||
@@ -49,10 +49,6 @@
|
||||
"Gecko:MozillaRntimeMain", __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
|
||||
# ifdef MOZ_CONTENT_SANDBOX
|
||||
# include "mozilla/Sandbox.h"
|
||||
# endif
|
||||
|
||||
#endif // MOZ_WIDGET_GONK
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
||||
@@ -23,10 +23,6 @@
|
||||
#include "prenv.h"
|
||||
#include "nsXPCOMPrivate.h"
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#endif
|
||||
|
||||
#include "nsExceptionHandler.h"
|
||||
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
@@ -312,15 +308,6 @@ GeckoChildProcessHost::PrepareLaunch()
|
||||
InitWindowsGroupID();
|
||||
}
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
// We need to get the pref here as the process is launched off main thread.
|
||||
if (mProcessType == GeckoProcessType_Content) {
|
||||
mSandboxLevel = Preferences::GetInt("security.sandbox.content.level");
|
||||
mEnableSandboxLogging =
|
||||
Preferences::GetBool("security.sandbox.windows.log");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_SANDBOX)
|
||||
// For other process types we can't rely on them being launched on main
|
||||
// thread and they may not have access to prefs in the child process, so allow
|
||||
@@ -608,20 +595,6 @@ AddAppDirToCommandLine(std::vector<std::string>& aCmdLine)
|
||||
aCmdLine.push_back(path.get());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
// Full path to the profile dir
|
||||
nsCOMPtr<nsIFile> profileDir;
|
||||
rv = directoryService->Get(NS_APP_USER_PROFILE_50_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(profileDir));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoCString path;
|
||||
MOZ_ALWAYS_SUCCEEDS(profileDir->GetNativePath(path));
|
||||
aCmdLine.push_back("-profile");
|
||||
aCmdLine.push_back(path.get());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1029,17 +1002,6 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
// of reorganizing so I don't think this patch is the right time.
|
||||
switch (mProcessType) {
|
||||
case GeckoProcessType_Content:
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
if (mSandboxLevel > 0 &&
|
||||
!PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX")) {
|
||||
// For now we treat every failure as fatal in SetSecurityLevelForContentProcess
|
||||
// and just crash there right away. Should this change in the future then we
|
||||
// should also handle the error here.
|
||||
mSandboxBroker.SetSecurityLevelForContentProcess(mSandboxLevel);
|
||||
shouldSandboxCurrentProcess = true;
|
||||
AddContentSandboxAllowedFiles(mSandboxLevel, mAllowedFilesRead);
|
||||
}
|
||||
#endif // MOZ_CONTENT_SANDBOX
|
||||
break;
|
||||
case GeckoProcessType_Plugin:
|
||||
if (mSandboxLevel > 0 &&
|
||||
|
||||
@@ -98,13 +98,8 @@ Logger::Logger(const nsACString& aLeafBaseName)
|
||||
rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(logFileName));
|
||||
} else if (procType == GeckoProcessType_Content) {
|
||||
leafName.AppendLiteral("-Content-");
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
|
||||
getter_AddRefs(logFileName));
|
||||
#else
|
||||
rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
|
||||
getter_AddRefs(logFileName));
|
||||
#endif // defined(MOZ_CONTENT_SANDBOX)
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-41
@@ -2311,7 +2311,6 @@ MOZ_INSTALL_TRACKING=
|
||||
ACCESSIBILITY=1
|
||||
MOZ_TIME_MANAGER=
|
||||
MOZ_AUDIO_CHANNEL_MANAGER=
|
||||
MOZ_CONTENT_SANDBOX=
|
||||
MOZ_GMP_SANDBOX=
|
||||
MOZ_SANDBOX=
|
||||
MOZ_BINARY_EXTENSIONS=
|
||||
@@ -3943,45 +3942,6 @@ if test -n "$MOZ_TSAN" -o -n "$MOZ_ASAN"; then
|
||||
esac
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Content process sandboxing
|
||||
dnl ========================================================
|
||||
if test -n "$gonkdir"; then
|
||||
MOZ_CONTENT_SANDBOX=$MOZ_SANDBOX
|
||||
fi
|
||||
|
||||
case "$OS_TARGET:$NIGHTLY_BUILD" in
|
||||
WINNT:*)
|
||||
MOZ_CONTENT_SANDBOX=$MOZ_SANDBOX
|
||||
;;
|
||||
Darwin:*)
|
||||
MOZ_CONTENT_SANDBOX=$MOZ_SANDBOX
|
||||
;;
|
||||
Linux:1)
|
||||
case $CPU_ARCH in
|
||||
x86_64|x86)
|
||||
MOZ_CONTENT_SANDBOX=$MOZ_SANDBOX
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(content-sandbox,
|
||||
[ --enable-content-sandbox Enable sandboxing support for content-processes
|
||||
--disable-content-sandbox Disable sandboxing support for content-processes],
|
||||
MOZ_CONTENT_SANDBOX=1,
|
||||
MOZ_CONTENT_SANDBOX=)
|
||||
|
||||
if test -n "$MOZ_CONTENT_SANDBOX" -a -z "$MOZ_SANDBOX"; then
|
||||
AC_MSG_ERROR([--enable-content-sandbox and --disable-sandbox are conflicting options])
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_CONTENT_SANDBOX"; then
|
||||
AC_DEFINE(MOZ_CONTENT_SANDBOX)
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_CONTENT_SANDBOX)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Gecko Media Plugin sandboxing
|
||||
dnl ========================================================
|
||||
@@ -4007,7 +3967,7 @@ fi
|
||||
|
||||
AC_SUBST(MOZ_GMP_SANDBOX)
|
||||
|
||||
if test -z "$MOZ_CONTENT_SANDBOX" -a -z "$MOZ_GMP_SANDBOX"; then
|
||||
if test -z "$MOZ_GMP_SANDBOX"; then
|
||||
MOZ_SANDBOX=
|
||||
fi
|
||||
|
||||
|
||||
@@ -89,15 +89,6 @@ InitLoggingIfRequired(ProvideLogFunctionCb aProvideLogFunctionCb)
|
||||
if (Preferences::GetBool("security.sandbox.windows.log") ||
|
||||
PR_GetEnv("MOZ_WIN_SANDBOX_LOGGING")) {
|
||||
aProvideLogFunctionCb(Log);
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
// We can only log the stack trace on process types where we know that the
|
||||
// sandbox won't prevent it.
|
||||
if (XRE_IsContentProcess()) {
|
||||
Preferences::AddUintVarCache(&sStackTraceDepth,
|
||||
"security.sandbox.windows.log.stackTraceDepth");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -626,34 +626,6 @@ SandboxEarlyInit(GeckoProcessType aType)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
/**
|
||||
* Starts the seccomp sandbox for a content process. Should be called
|
||||
* only once, and before any potentially harmful content is loaded.
|
||||
*
|
||||
* Will normally make the process exit on failure.
|
||||
*/
|
||||
bool
|
||||
SetContentProcessSandbox(int aBrokerFd)
|
||||
{
|
||||
if (!SandboxInfo::Get().Test(SandboxInfo::kEnabledForContent)) {
|
||||
if (aBrokerFd >= 0) {
|
||||
close(aBrokerFd);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This needs to live until the process exits.
|
||||
static Maybe<SandboxBrokerClient> sBroker;
|
||||
if (aBrokerFd >= 0) {
|
||||
sBroker.emplace(aBrokerFd);
|
||||
}
|
||||
|
||||
SetCurrentProcessSandbox(GetContentSandboxPolicy(sBroker.ptrOr(nullptr)));
|
||||
return true;
|
||||
}
|
||||
#endif // MOZ_CONTENT_SANDBOX
|
||||
|
||||
#ifdef MOZ_GMP_SANDBOX
|
||||
/**
|
||||
* Starts the seccomp sandbox for a media plugin process. Should be
|
||||
|
||||
@@ -19,14 +19,6 @@ namespace mozilla {
|
||||
// This must be called early, while the process is still single-threaded.
|
||||
MOZ_EXPORT void SandboxEarlyInit(GeckoProcessType aType);
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
// Call only if SandboxInfo::CanSandboxContent() returns true.
|
||||
// (No-op if MOZ_DISABLE_CONTENT_SANDBOX is set.)
|
||||
// aBrokerFd is the filesystem broker client file descriptor,
|
||||
// or -1 to allow direct filesystem access.
|
||||
MOZ_EXPORT bool SetContentProcessSandbox(int aBrokerFd);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_GMP_SANDBOX
|
||||
// Call only if SandboxInfo::CanSandboxMedia() returns true.
|
||||
// (No-op if MOZ_DISABLE_GMP_SANDBOX is set.)
|
||||
|
||||
@@ -340,495 +340,6 @@ public:
|
||||
|
||||
// The process-type-specific syscall rules start here:
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
// The seccomp-bpf filter for content processes is not a true sandbox
|
||||
// on its own; its purpose is attack surface reduction and syscall
|
||||
// interception in support of a semantic sandboxing layer. On B2G
|
||||
// this is the Android process permission model; on desktop,
|
||||
// namespaces and chroot() will be used.
|
||||
class ContentSandboxPolicy : public SandboxPolicyCommon {
|
||||
SandboxBrokerClient* mBroker;
|
||||
|
||||
// Trap handlers for filesystem brokering.
|
||||
// (The amount of code duplication here could be improved....)
|
||||
#ifdef __NR_open
|
||||
static intptr_t OpenTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
auto flags = static_cast<int>(aArgs.args[1]);
|
||||
return broker->Open(path, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
static intptr_t OpenAtTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto fd = static_cast<int>(aArgs.args[0]);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[1]);
|
||||
auto flags = static_cast<int>(aArgs.args[2]);
|
||||
if (fd != AT_FDCWD && path[0] != '/') {
|
||||
SANDBOX_LOG_ERROR("unsupported fd-relative openat(%d, \"%s\", 0%o)",
|
||||
fd, path, flags);
|
||||
return BlockedSyscallTrap(aArgs, nullptr);
|
||||
}
|
||||
return broker->Open(path, flags);
|
||||
}
|
||||
|
||||
#ifdef __NR_access
|
||||
static intptr_t AccessTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
auto mode = static_cast<int>(aArgs.args[1]);
|
||||
return broker->Access(path, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
static intptr_t AccessAtTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto fd = static_cast<int>(aArgs.args[0]);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[1]);
|
||||
auto mode = static_cast<int>(aArgs.args[2]);
|
||||
// Linux's faccessat syscall has no "flags" argument. Attempting
|
||||
// to handle the flags != 0 case is left to userspace; this is
|
||||
// impossible to do correctly in all cases, but that's not our
|
||||
// problem.
|
||||
if (fd != AT_FDCWD && path[0] != '/') {
|
||||
SANDBOX_LOG_ERROR("unsupported fd-relative faccessat(%d, \"%s\", %d)",
|
||||
fd, path, mode);
|
||||
return BlockedSyscallTrap(aArgs, nullptr);
|
||||
}
|
||||
return broker->Access(path, mode);
|
||||
}
|
||||
|
||||
static intptr_t StatTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
auto buf = reinterpret_cast<statstruct*>(aArgs.args[1]);
|
||||
return broker->Stat(path, buf);
|
||||
}
|
||||
|
||||
static intptr_t LStatTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
auto buf = reinterpret_cast<statstruct*>(aArgs.args[1]);
|
||||
return broker->LStat(path, buf);
|
||||
}
|
||||
|
||||
static intptr_t StatAtTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto fd = static_cast<int>(aArgs.args[0]);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[1]);
|
||||
auto buf = reinterpret_cast<statstruct*>(aArgs.args[2]);
|
||||
auto flags = static_cast<int>(aArgs.args[3]);
|
||||
if (fd != AT_FDCWD && path[0] != '/') {
|
||||
SANDBOX_LOG_ERROR("unsupported fd-relative fstatat(%d, \"%s\", %p, %d)",
|
||||
fd, path, buf, flags);
|
||||
return BlockedSyscallTrap(aArgs, nullptr);
|
||||
}
|
||||
if ((flags & ~AT_SYMLINK_NOFOLLOW) != 0) {
|
||||
SANDBOX_LOG_ERROR("unsupported flags %d in fstatat(%d, \"%s\", %p, %d)",
|
||||
(flags & ~AT_SYMLINK_NOFOLLOW), fd, path, buf, flags);
|
||||
return BlockedSyscallTrap(aArgs, nullptr);
|
||||
}
|
||||
return (flags & AT_SYMLINK_NOFOLLOW) == 0
|
||||
? broker->Stat(path, buf)
|
||||
: broker->LStat(path, buf);
|
||||
}
|
||||
|
||||
static intptr_t ChmodTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
auto mode = static_cast<mode_t>(aArgs.args[1]);
|
||||
return broker->Chmod(path, mode);
|
||||
}
|
||||
|
||||
static intptr_t LinkTrap(ArgsRef aArgs, void *aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
auto path2 = reinterpret_cast<const char*>(aArgs.args[1]);
|
||||
return broker->Link(path, path2);
|
||||
}
|
||||
|
||||
static intptr_t SymlinkTrap(ArgsRef aArgs, void *aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
auto path2 = reinterpret_cast<const char*>(aArgs.args[1]);
|
||||
return broker->Symlink(path, path2);
|
||||
}
|
||||
|
||||
static intptr_t RenameTrap(ArgsRef aArgs, void *aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
auto path2 = reinterpret_cast<const char*>(aArgs.args[1]);
|
||||
return broker->Rename(path, path2);
|
||||
}
|
||||
|
||||
static intptr_t MkdirTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
auto mode = static_cast<mode_t>(aArgs.args[1]);
|
||||
return broker->Mkdir(path, mode);
|
||||
}
|
||||
|
||||
static intptr_t RmdirTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
return broker->Rmdir(path);
|
||||
}
|
||||
|
||||
static intptr_t UnlinkTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
return broker->Unlink(path);
|
||||
}
|
||||
|
||||
static intptr_t ReadlinkTrap(ArgsRef aArgs, void* aux) {
|
||||
auto broker = static_cast<SandboxBrokerClient*>(aux);
|
||||
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
|
||||
auto buf = reinterpret_cast<char*>(aArgs.args[1]);
|
||||
auto size = static_cast<size_t>(aArgs.args[2]);
|
||||
return broker->Readlink(path, buf, size);
|
||||
}
|
||||
|
||||
static intptr_t GetPPidTrap(ArgsRef aArgs, void* aux) {
|
||||
// In a pid namespace, getppid() will return 0. We will return 0 instead
|
||||
// of the real parent pid to see what breaks when we introduce the
|
||||
// pid namespace (Bug 1151624).
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit ContentSandboxPolicy(SandboxBrokerClient* aBroker):mBroker(aBroker) { }
|
||||
virtual ~ContentSandboxPolicy() { }
|
||||
virtual ResultExpr PrctlPolicy() const override {
|
||||
// Ideally this should be restricted to a whitelist, but content
|
||||
// uses enough things that it's not trivial to determine it.
|
||||
return Allow();
|
||||
}
|
||||
virtual Maybe<ResultExpr> EvaluateSocketCall(int aCall) const override {
|
||||
switch(aCall) {
|
||||
case SYS_RECVFROM:
|
||||
case SYS_SENDTO:
|
||||
return Some(Allow());
|
||||
|
||||
case SYS_SOCKETPAIR: {
|
||||
// See bug 1066750.
|
||||
if (!kSocketCallHasArgs) {
|
||||
// We can't filter the args if the platform passes them by pointer.
|
||||
return Some(Allow());
|
||||
}
|
||||
Arg<int> domain(0), type(1);
|
||||
return Some(If(AllOf(domain == AF_UNIX,
|
||||
AnyOf(type == SOCK_STREAM, type == SOCK_SEQPACKET)),
|
||||
Allow())
|
||||
.Else(InvalidSyscall()));
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
case SYS_SOCKET:
|
||||
return Some(Error(EACCES));
|
||||
#else // #ifdef DESKTOP
|
||||
case SYS_RECV:
|
||||
case SYS_SEND:
|
||||
case SYS_SOCKET: // DANGEROUS
|
||||
case SYS_CONNECT: // DANGEROUS
|
||||
case SYS_ACCEPT:
|
||||
case SYS_ACCEPT4:
|
||||
case SYS_BIND:
|
||||
case SYS_LISTEN:
|
||||
case SYS_GETSOCKOPT:
|
||||
case SYS_SETSOCKOPT:
|
||||
case SYS_GETSOCKNAME:
|
||||
case SYS_GETPEERNAME:
|
||||
case SYS_SHUTDOWN:
|
||||
return Some(Allow());
|
||||
#endif
|
||||
default:
|
||||
return SandboxPolicyCommon::EvaluateSocketCall(aCall);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DESKTOP
|
||||
virtual Maybe<ResultExpr> EvaluateIpcCall(int aCall) const override {
|
||||
switch(aCall) {
|
||||
// These are a problem: SysV shared memory follows the Unix
|
||||
// "same uid policy" and can't be restricted/brokered like file
|
||||
// access. But the graphics layer might not be using them
|
||||
// anymore; this needs to be studied.
|
||||
case SHMGET:
|
||||
case SHMCTL:
|
||||
case SHMAT:
|
||||
case SHMDT:
|
||||
case SEMGET:
|
||||
case SEMCTL:
|
||||
case SEMOP:
|
||||
case MSGGET:
|
||||
return Some(Allow());
|
||||
default:
|
||||
return SandboxPolicyCommon::EvaluateIpcCall(aCall);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual ResultExpr EvaluateSyscall(int sysno) const override {
|
||||
if (mBroker) {
|
||||
// Have broker; route the appropriate syscalls to it.
|
||||
switch (sysno) {
|
||||
case __NR_open:
|
||||
return Trap(OpenTrap, mBroker);
|
||||
case __NR_openat:
|
||||
return Trap(OpenAtTrap, mBroker);
|
||||
case __NR_access:
|
||||
return Trap(AccessTrap, mBroker);
|
||||
case __NR_faccessat:
|
||||
return Trap(AccessAtTrap, mBroker);
|
||||
CASES_FOR_stat:
|
||||
return Trap(StatTrap, mBroker);
|
||||
CASES_FOR_lstat:
|
||||
return Trap(LStatTrap, mBroker);
|
||||
CASES_FOR_fstatat:
|
||||
return Trap(StatAtTrap, mBroker);
|
||||
case __NR_chmod:
|
||||
return Trap(ChmodTrap, mBroker);
|
||||
case __NR_link:
|
||||
return Trap(LinkTrap, mBroker);
|
||||
case __NR_mkdir:
|
||||
return Trap(MkdirTrap, mBroker);
|
||||
case __NR_symlink:
|
||||
return Trap(SymlinkTrap, mBroker);
|
||||
case __NR_rename:
|
||||
return Trap(RenameTrap, mBroker);
|
||||
case __NR_rmdir:
|
||||
return Trap(RmdirTrap, mBroker);
|
||||
case __NR_unlink:
|
||||
return Trap(UnlinkTrap, mBroker);
|
||||
case __NR_readlink:
|
||||
return Trap(ReadlinkTrap, mBroker);
|
||||
}
|
||||
} else {
|
||||
// No broker; allow the syscalls directly. )-:
|
||||
switch(sysno) {
|
||||
case __NR_open:
|
||||
case __NR_openat:
|
||||
case __NR_access:
|
||||
case __NR_faccessat:
|
||||
CASES_FOR_stat:
|
||||
CASES_FOR_lstat:
|
||||
CASES_FOR_fstatat:
|
||||
case __NR_chmod:
|
||||
case __NR_link:
|
||||
case __NR_mkdir:
|
||||
case __NR_symlink:
|
||||
case __NR_rename:
|
||||
case __NR_rmdir:
|
||||
case __NR_unlink:
|
||||
case __NR_readlink:
|
||||
return Allow();
|
||||
}
|
||||
}
|
||||
|
||||
switch (sysno) {
|
||||
#ifdef DESKTOP
|
||||
case __NR_getppid:
|
||||
return Trap(GetPPidTrap, nullptr);
|
||||
|
||||
// Filesystem syscalls that need more work to determine who's
|
||||
// using them, if they need to be, and what we intend to about it.
|
||||
case __NR_getcwd:
|
||||
CASES_FOR_statfs:
|
||||
CASES_FOR_fstatfs:
|
||||
case __NR_quotactl:
|
||||
CASES_FOR_fchown:
|
||||
case __NR_fchmod:
|
||||
case __NR_flock:
|
||||
#endif
|
||||
return Allow();
|
||||
|
||||
case __NR_readlinkat:
|
||||
#ifdef DESKTOP
|
||||
// Bug 1290896
|
||||
return Allow();
|
||||
#else
|
||||
// Workaround for bug 964455:
|
||||
return Error(EINVAL);
|
||||
#endif
|
||||
|
||||
CASES_FOR_select:
|
||||
case __NR_pselect6:
|
||||
return Allow();
|
||||
|
||||
CASES_FOR_getdents:
|
||||
CASES_FOR_ftruncate:
|
||||
case __NR_writev:
|
||||
case __NR_pread64:
|
||||
#ifdef DESKTOP
|
||||
case __NR_pwrite64:
|
||||
case __NR_readahead:
|
||||
#endif
|
||||
return Allow();
|
||||
|
||||
case __NR_ioctl:
|
||||
// ioctl() is for GL. Remove when GL proxy is implemented.
|
||||
// Additionally ioctl() might be a place where we want to have
|
||||
// argument filtering
|
||||
return Allow();
|
||||
|
||||
CASES_FOR_fcntl:
|
||||
// Some fcntls have significant side effects like sending
|
||||
// arbitrary signals, and there's probably nontrivial kernel
|
||||
// attack surface; this should be locked down more if possible.
|
||||
return Allow();
|
||||
|
||||
case __NR_mprotect:
|
||||
case __NR_brk:
|
||||
case __NR_madvise:
|
||||
#if !defined(MOZ_MEMORY)
|
||||
// libc's realloc uses mremap (Bug 1286119).
|
||||
case __NR_mremap:
|
||||
#endif
|
||||
return Allow();
|
||||
|
||||
case __NR_sigaltstack:
|
||||
return Allow();
|
||||
|
||||
#ifdef __NR_set_thread_area
|
||||
case __NR_set_thread_area:
|
||||
return Allow();
|
||||
#endif
|
||||
|
||||
case __NR_getrusage:
|
||||
case __NR_times:
|
||||
return Allow();
|
||||
|
||||
case __NR_dup:
|
||||
return Allow();
|
||||
|
||||
CASES_FOR_getuid:
|
||||
CASES_FOR_getgid:
|
||||
CASES_FOR_geteuid:
|
||||
CASES_FOR_getegid:
|
||||
return Allow();
|
||||
|
||||
case __NR_fsync:
|
||||
case __NR_msync:
|
||||
return Allow();
|
||||
|
||||
case __NR_getpriority:
|
||||
case __NR_setpriority:
|
||||
case __NR_sched_get_priority_min:
|
||||
case __NR_sched_get_priority_max:
|
||||
case __NR_sched_getscheduler:
|
||||
case __NR_sched_setscheduler:
|
||||
case __NR_sched_getparam:
|
||||
case __NR_sched_setparam:
|
||||
#ifdef DESKTOP
|
||||
case __NR_sched_getaffinity:
|
||||
#endif
|
||||
return Allow();
|
||||
|
||||
#ifdef DESKTOP
|
||||
case __NR_pipe2:
|
||||
return Allow();
|
||||
|
||||
CASES_FOR_getrlimit:
|
||||
case __NR_clock_getres:
|
||||
CASES_FOR_getresuid:
|
||||
CASES_FOR_getresgid:
|
||||
return Allow();
|
||||
|
||||
case __NR_umask:
|
||||
case __NR_kill:
|
||||
case __NR_wait4:
|
||||
#ifdef __NR_waitpid
|
||||
case __NR_waitpid:
|
||||
#endif
|
||||
#ifdef __NR_arch_prctl
|
||||
case __NR_arch_prctl:
|
||||
#endif
|
||||
return Allow();
|
||||
|
||||
case __NR_eventfd2:
|
||||
case __NR_inotify_init1:
|
||||
case __NR_inotify_add_watch:
|
||||
case __NR_inotify_rm_watch:
|
||||
return Allow();
|
||||
|
||||
#ifdef __NR_memfd_create
|
||||
case __NR_memfd_create:
|
||||
return Allow();
|
||||
#endif
|
||||
|
||||
#ifdef __NR_rt_tgsigqueueinfo
|
||||
// Only allow to send signals within the process.
|
||||
case __NR_rt_tgsigqueueinfo: {
|
||||
Arg<pid_t> tgid(0);
|
||||
return If(tgid == getpid(), Allow())
|
||||
.Else(InvalidSyscall());
|
||||
}
|
||||
#endif
|
||||
|
||||
case __NR_mlock:
|
||||
case __NR_munlock:
|
||||
return Allow();
|
||||
|
||||
// We can't usefully allow fork+exec, even on a temporary basis;
|
||||
// the child would inherit the seccomp-bpf policy and almost
|
||||
// certainly die from an unexpected SIGSYS. We also can't have
|
||||
// fork() crash, currently, because there are too many system
|
||||
// libraries/plugins that try to run commands. But they can
|
||||
// usually do something reasonable on error.
|
||||
case __NR_clone:
|
||||
return ClonePolicy(Error(EPERM));
|
||||
|
||||
#ifdef __NR_fadvise64
|
||||
case __NR_fadvise64:
|
||||
return Allow();
|
||||
#endif
|
||||
|
||||
#ifdef __NR_fadvise64_64
|
||||
case __NR_fadvise64_64:
|
||||
return Allow();
|
||||
#endif
|
||||
|
||||
case __NR_fallocate:
|
||||
return Allow();
|
||||
|
||||
case __NR_get_mempolicy:
|
||||
return Allow();
|
||||
|
||||
#endif // DESKTOP
|
||||
|
||||
#ifdef __NR_getrandom
|
||||
case __NR_getrandom:
|
||||
return Allow();
|
||||
#endif
|
||||
|
||||
// nsSystemInfo uses uname (and we cache an instance, so
|
||||
// the info remains present even if we block the syscall)
|
||||
case __NR_uname:
|
||||
#ifdef DESKTOP
|
||||
case __NR_sysinfo:
|
||||
#endif
|
||||
return Allow();
|
||||
|
||||
#ifdef MOZ_JPROF
|
||||
case __NR_setitimer:
|
||||
return Allow();
|
||||
#endif // MOZ_JPROF
|
||||
|
||||
default:
|
||||
return SandboxPolicyCommon::EvaluateSyscall(sysno);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
UniquePtr<sandbox::bpf_dsl::Policy>
|
||||
GetContentSandboxPolicy(SandboxBrokerClient* aMaybeBroker)
|
||||
{
|
||||
return UniquePtr<sandbox::bpf_dsl::Policy>(new ContentSandboxPolicy(aMaybeBroker));
|
||||
}
|
||||
#endif // MOZ_CONTENT_SANDBOX
|
||||
|
||||
|
||||
#ifdef MOZ_GMP_SANDBOX
|
||||
// Unlike for content, the GeckoMediaPlugin seccomp-bpf policy needs
|
||||
// to be an effective sandbox by itself, because we allow GMP on Linux
|
||||
|
||||
@@ -18,12 +18,6 @@ class Policy;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
class SandboxBrokerClient;
|
||||
|
||||
UniquePtr<sandbox::bpf_dsl::Policy> GetContentSandboxPolicy(SandboxBrokerClient* aMaybeBroker);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_GMP_SANDBOX
|
||||
struct SandboxOpenedFile {
|
||||
const char *mPath;
|
||||
|
||||
@@ -225,14 +225,6 @@ SandboxInfo::SandboxInfo() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
if (!getenv("MOZ_DISABLE_CONTENT_SANDBOX")) {
|
||||
flags |= kEnabledForContent;
|
||||
}
|
||||
if (getenv("MOZ_PERMISSIVE_CONTENT_SANDBOX")) {
|
||||
flags |= kPermissive;
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_GMP_SANDBOX
|
||||
if (!getenv("MOZ_DISABLE_GMP_SANDBOX")) {
|
||||
flags |= kEnabledForMedia;
|
||||
|
||||
@@ -41,154 +41,10 @@ SandboxBrokerPolicyFactory::IsSystemSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
namespace {
|
||||
static const int rdonly = SandboxBroker::MAY_READ;
|
||||
static const int wronly = SandboxBroker::MAY_WRITE;
|
||||
static const int rdwr = rdonly | wronly;
|
||||
static const int rdwrcr = rdwr | SandboxBroker::MAY_CREATE;
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
static const int wrlog = wronly | SandboxBroker::MAY_CREATE;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
SandboxBrokerPolicyFactory::SandboxBrokerPolicyFactory()
|
||||
{
|
||||
// Policy entries that are the same in every process go here, and
|
||||
// are cached over the lifetime of the factory.
|
||||
#if defined(MOZ_CONTENT_SANDBOX) && defined(MOZ_WIDGET_GONK)
|
||||
SandboxBroker::Policy* policy = new SandboxBroker::Policy;
|
||||
|
||||
// Devices that need write access:
|
||||
policy->AddPath(rdwr, "/dev/genlock"); // bug 980924
|
||||
policy->AddPath(rdwr, "/dev/ashmem"); // bug 980947
|
||||
policy->AddTree(wronly, "/dev/log"); // bug 1199857
|
||||
// Graphics devices are a significant source of attack surface, but
|
||||
// there's not much we can do about it without proxying (which is
|
||||
// very difficult and a perforamnce hit).
|
||||
policy->AddPrefix(rdwr, "/dev", "kgsl"); // bug 995072
|
||||
policy->AddPath(rdwr, "/dev/qemu_pipe"); // but 1198410: goldfish gralloc.
|
||||
|
||||
// Bug 1198475: mochitest logs. (This is actually passed in via URL
|
||||
// query param to the mochitest page, and is configurable, so this
|
||||
// isn't enough in general, but hopefully it's good enough for B2G.)
|
||||
// Conditional on tests being run, using the same check seen in
|
||||
// DirectoryProvider.js to set ProfD.
|
||||
if (access("/data/local/tests/profile", R_OK) == 0) {
|
||||
policy->AddPath(wrlog, "/data/local/tests/log/mochitest.log");
|
||||
}
|
||||
|
||||
// Read-only items below this line.
|
||||
|
||||
policy->AddPath(rdonly, "/dev/urandom"); // bug 964500, bug 995069
|
||||
policy->AddPath(rdonly, "/dev/ion"); // bug 980937
|
||||
policy->AddPath(rdonly, "/proc/cpuinfo"); // bug 995067
|
||||
policy->AddPath(rdonly, "/proc/meminfo"); // bug 1025333
|
||||
policy->AddPath(rdonly, "/sys/devices/system/cpu/present"); // bug 1025329
|
||||
policy->AddPath(rdonly, "/sys/devices/system/soc/soc0/id"); // bug 1025339
|
||||
policy->AddPath(rdonly, "/etc/media_profiles.xml"); // bug 1198419
|
||||
policy->AddPath(rdonly, "/etc/media_codecs.xml"); // bug 1198460
|
||||
policy->AddTree(rdonly, "/system/fonts"); // bug 1026063
|
||||
|
||||
// Bug 1199051 (crossplatformly, this is NS_GRE_DIR).
|
||||
policy->AddTree(rdonly, "/system/b2g");
|
||||
|
||||
// Bug 1026356: dynamic library loading from assorted frameworks we
|
||||
// don't control (media codecs, maybe others).
|
||||
//
|
||||
// Bug 1198515: Also, the profiler calls breakpad code to get info
|
||||
// on all loaded ELF objects, which opens those files.
|
||||
policy->AddTree(rdonly, "/system/lib");
|
||||
policy->AddTree(rdonly, "/vendor/lib");
|
||||
policy->AddPath(rdonly, "/system/bin/linker"); // (profiler only)
|
||||
|
||||
// Bug 1199866: EGL/WebGL.
|
||||
policy->AddPath(rdonly, "/system/lib/egl");
|
||||
policy->AddPath(rdonly, "/vendor/lib/egl");
|
||||
|
||||
// Bug 1198401: timezones. Yes, we need both of these; see bug.
|
||||
policy->AddTree(rdonly, "/system/usr/share/zoneinfo");
|
||||
policy->AddTree(rdonly, "/system//usr/share/zoneinfo");
|
||||
|
||||
policy->AddPath(rdonly, "/data/local/tmp/profiler.options",
|
||||
SandboxBroker::Policy::AddAlways); // bug 1029337
|
||||
|
||||
mCommonContentPolicy.reset(policy);
|
||||
#elif defined(MOZ_CONTENT_SANDBOX)
|
||||
SandboxBroker::Policy* policy = new SandboxBroker::Policy;
|
||||
policy->AddDir(rdonly, "/");
|
||||
policy->AddDir(rdwrcr, "/dev/shm");
|
||||
// Add write permissions on the temporary directory. This can come
|
||||
// from various environment variables (TMPDIR,TMP,TEMP,...) so
|
||||
// make sure to use the full logic.
|
||||
nsCOMPtr<nsIFile> tmpDir;
|
||||
nsresult rv = GetSpecialSystemDirectory(OS_TemporaryDirectory,
|
||||
getter_AddRefs(tmpDir));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoCString tmpPath;
|
||||
rv = tmpDir->GetNativePath(tmpPath);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
policy->AddDir(rdwrcr, tmpPath.get());
|
||||
}
|
||||
}
|
||||
// If the above fails at any point, fall back to a very good guess.
|
||||
if (NS_FAILED(rv)) {
|
||||
policy->AddDir(rdwrcr, "/tmp");
|
||||
}
|
||||
|
||||
// Bug 1308851: NVIDIA proprietary driver when using WebGL
|
||||
policy->AddPrefix(rdwr, "/dev", "nvidia");
|
||||
|
||||
// Bug 1312678: radeonsi/Intel with DRI when using WebGL
|
||||
policy->AddDir(rdwr, "/dev/dri");
|
||||
|
||||
mCommonContentPolicy.reset(policy);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
UniquePtr<SandboxBroker::Policy>
|
||||
SandboxBrokerPolicyFactory::GetContentPolicy(int aPid)
|
||||
{
|
||||
// Policy entries that vary per-process (currently the only reason
|
||||
// that can happen is because they contain the pid) are added here.
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// File broker usage is controlled through a pref.
|
||||
if (Preferences::GetInt("security.sandbox.content.level") <= 1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mCommonContentPolicy);
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
// Allow overriding "unsupported"ness with a pref, for testing.
|
||||
if (!IsSystemSupported()) {
|
||||
return nullptr;
|
||||
}
|
||||
UniquePtr<SandboxBroker::Policy>
|
||||
policy(new SandboxBroker::Policy(*mCommonContentPolicy));
|
||||
|
||||
// Bug 1029337: where the profiler writes the data.
|
||||
nsPrintfCString profilerLogPath("/data/local/tmp/profile_%d_%d.txt",
|
||||
GeckoProcessType_Content, aPid);
|
||||
policy->AddPath(wrlog, profilerLogPath.get());
|
||||
|
||||
// Bug 1198550: the profiler's replacement for dl_iterate_phdr
|
||||
policy->AddPath(rdonly, nsPrintfCString("/proc/%d/maps", aPid).get());
|
||||
|
||||
// Bug 1198552: memory reporting.
|
||||
policy->AddPath(rdonly, nsPrintfCString("/proc/%d/statm", aPid).get());
|
||||
policy->AddPath(rdonly, nsPrintfCString("/proc/%d/smaps", aPid).get());
|
||||
|
||||
return policy;
|
||||
#else
|
||||
UniquePtr<SandboxBroker::Policy>
|
||||
policy(new SandboxBroker::Policy(*mCommonContentPolicy));
|
||||
// Return the common policy.
|
||||
return policy;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // MOZ_CONTENT_SANDBOX
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -15,10 +15,6 @@ class SandboxBrokerPolicyFactory {
|
||||
public:
|
||||
SandboxBrokerPolicyFactory();
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
UniquePtr<SandboxBroker::Policy> GetContentPolicy(int aPid);
|
||||
#endif
|
||||
|
||||
private:
|
||||
UniquePtr<const SandboxBroker::Policy> mCommonContentPolicy;
|
||||
// B2G devices tend to have hardware-specific paths used by device
|
||||
|
||||
@@ -90,130 +90,6 @@ SandboxBroker::LaunchApp(const wchar_t *aPath,
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
void
|
||||
SandboxBroker::SetSecurityLevelForContentProcess(int32_t aSandboxLevel)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mPolicy, "mPolicy must be set before this call.");
|
||||
|
||||
sandbox::JobLevel jobLevel;
|
||||
sandbox::TokenLevel accessTokenLevel;
|
||||
sandbox::IntegrityLevel initialIntegrityLevel;
|
||||
sandbox::IntegrityLevel delayedIntegrityLevel;
|
||||
|
||||
// The setting of these levels is pretty arbitrary, but they are a useful (if
|
||||
// crude) tool while we are tightening the policy. Gaps are left to try and
|
||||
// avoid changing their meaning.
|
||||
MOZ_RELEASE_ASSERT(aSandboxLevel >= 1, "Should not be called with aSandboxLevel < 1");
|
||||
if (aSandboxLevel >= 20) {
|
||||
jobLevel = sandbox::JOB_LOCKDOWN;
|
||||
accessTokenLevel = sandbox::USER_LOCKDOWN;
|
||||
initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
|
||||
delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_UNTRUSTED;
|
||||
} else if (aSandboxLevel >= 10) {
|
||||
jobLevel = sandbox::JOB_RESTRICTED;
|
||||
accessTokenLevel = sandbox::USER_LIMITED;
|
||||
initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
|
||||
delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
|
||||
} else if (aSandboxLevel >= 2) {
|
||||
jobLevel = sandbox::JOB_INTERACTIVE;
|
||||
accessTokenLevel = sandbox::USER_INTERACTIVE;
|
||||
initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
|
||||
delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
|
||||
} else if (aSandboxLevel == 1) {
|
||||
jobLevel = sandbox::JOB_NONE;
|
||||
accessTokenLevel = sandbox::USER_NON_ADMIN;
|
||||
initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
|
||||
delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
|
||||
}
|
||||
|
||||
sandbox::ResultCode result = mPolicy->SetJobLevel(jobLevel,
|
||||
0 /* ui_exceptions */);
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"Setting job level failed, have you set memory limit when jobLevel == JOB_NONE?");
|
||||
|
||||
// If the delayed access token is not restricted we don't want the initial one
|
||||
// to be either, because it can interfere with running from a network drive.
|
||||
sandbox::TokenLevel initialAccessTokenLevel =
|
||||
(accessTokenLevel == sandbox::USER_UNPROTECTED ||
|
||||
accessTokenLevel == sandbox::USER_NON_ADMIN)
|
||||
? sandbox::USER_UNPROTECTED : sandbox::USER_RESTRICTED_SAME_ACCESS;
|
||||
|
||||
result = mPolicy->SetTokenLevel(initialAccessTokenLevel, accessTokenLevel);
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"Lockdown level cannot be USER_UNPROTECTED or USER_LAST if initial level was USER_RESTRICTED_SAME_ACCESS");
|
||||
|
||||
result = mPolicy->SetIntegrityLevel(initialIntegrityLevel);
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"SetIntegrityLevel should never fail, what happened?");
|
||||
result = mPolicy->SetDelayedIntegrityLevel(delayedIntegrityLevel);
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"SetDelayedIntegrityLevel should never fail, what happened?");
|
||||
|
||||
if (aSandboxLevel > 2) {
|
||||
result = mPolicy->SetAlternateDesktop(true);
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"Failed to create alternate desktop for sandbox.");
|
||||
}
|
||||
|
||||
sandbox::MitigationFlags mitigations =
|
||||
sandbox::MITIGATION_BOTTOM_UP_ASLR |
|
||||
sandbox::MITIGATION_HEAP_TERMINATE |
|
||||
sandbox::MITIGATION_SEHOP |
|
||||
sandbox::MITIGATION_DEP_NO_ATL_THUNK |
|
||||
sandbox::MITIGATION_DEP;
|
||||
|
||||
result = mPolicy->SetProcessMitigations(mitigations);
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"Invalid flags for SetProcessMitigations.");
|
||||
|
||||
mitigations =
|
||||
sandbox::MITIGATION_STRICT_HANDLE_CHECKS |
|
||||
sandbox::MITIGATION_DLL_SEARCH_ORDER;
|
||||
|
||||
result = mPolicy->SetDelayedProcessMitigations(mitigations);
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"Invalid flags for SetDelayedProcessMitigations.");
|
||||
|
||||
// Add the policy for the client side of a pipe. It is just a file
|
||||
// in the \pipe\ namespace. We restrict it to pipes that start with
|
||||
// "chrome." so the sandboxed process cannot connect to system services.
|
||||
result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
|
||||
sandbox::TargetPolicy::FILES_ALLOW_ANY,
|
||||
L"\\??\\pipe\\chrome.*");
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"With these static arguments AddRule should never fail, what happened?");
|
||||
|
||||
// Add the policy for the client side of the crash server pipe.
|
||||
result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
|
||||
sandbox::TargetPolicy::FILES_ALLOW_ANY,
|
||||
L"\\??\\pipe\\gecko-crash-server-pipe.*");
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"With these static arguments AddRule should never fail, what happened?");
|
||||
|
||||
// The content process needs to be able to duplicate named pipes back to the
|
||||
// broker process, which are File type handles.
|
||||
result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
|
||||
sandbox::TargetPolicy::HANDLES_DUP_BROKER,
|
||||
L"File");
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"With these static arguments AddRule should never fail, what happened?");
|
||||
|
||||
// The content process needs to be able to duplicate shared memory handles,
|
||||
// which are Section handles, to the broker process and other child processes.
|
||||
result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
|
||||
sandbox::TargetPolicy::HANDLES_DUP_BROKER,
|
||||
L"Section");
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"With these static arguments AddRule should never fail, what happened?");
|
||||
result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
|
||||
sandbox::TargetPolicy::HANDLES_DUP_ANY,
|
||||
L"Section");
|
||||
MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
|
||||
"With these static arguments AddRule should never fail, what happened?");
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SANDBOX_ENSURE_SUCCESS(result, message) \
|
||||
do { \
|
||||
MOZ_ASSERT(sandbox::SBOX_ALL_OK == result, message); \
|
||||
|
||||
@@ -31,9 +31,6 @@ public:
|
||||
virtual ~SandboxBroker();
|
||||
|
||||
// Security levels for different types of processes
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
void SetSecurityLevelForContentProcess(int32_t aSandboxLevel);
|
||||
#endif
|
||||
bool SetSecurityLevelForPluginProcess(int32_t aSandboxLevel);
|
||||
enum SandboxLevel {
|
||||
LockDown,
|
||||
|
||||
@@ -3417,22 +3417,10 @@ OOPInit()
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX))
|
||||
nsCOMPtr<nsIFile> tmpDir;
|
||||
# if defined(MOZ_CONTENT_SANDBOX)
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
|
||||
getter_AddRefs(tmpDir));
|
||||
if (NS_FAILED(rv) && PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR")) {
|
||||
// Temporary hack for xpcshell, will be fixed in bug 1257098
|
||||
rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpDir));
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
childProcessTmpDir = CreatePathFromFile(tmpDir);
|
||||
}
|
||||
# else
|
||||
if (NS_SUCCEEDED(NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
|
||||
getter_AddRefs(tmpDir)))) {
|
||||
childProcessTmpDir = CreatePathFromFile(tmpDir);
|
||||
}
|
||||
# endif // defined(MOZ_CONTENT_SANDBOX)
|
||||
#endif // (defined(XP_WIN) || defined(XP_MACOSX))
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
@@ -88,13 +88,6 @@ this.AppConstants = Object.freeze({
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_CONTENT_SANDBOX:
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_TELEMETRY_REPORTING:
|
||||
#ifdef MOZ_TELEMETRY_REPORTING
|
||||
true,
|
||||
|
||||
@@ -547,11 +547,6 @@ if (AppConstants.MOZ_SANDBOX) {
|
||||
}
|
||||
}
|
||||
|
||||
if (AppConstants.MOZ_CONTENT_SANDBOX) {
|
||||
data.contentSandboxLevel =
|
||||
Services.prefs.getIntPref("security.sandbox.content.level");
|
||||
}
|
||||
|
||||
done(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,10 +469,6 @@ const SNAPSHOT_SCHEMA = {
|
||||
required: false,
|
||||
type: "boolean"
|
||||
},
|
||||
contentSandboxLevel: {
|
||||
required: AppConstants.MOZ_CONTENT_SANDBOX,
|
||||
type: "number"
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -107,10 +107,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsAccessibilityService.h"
|
||||
#if defined(XP_WIN)
|
||||
@@ -2962,13 +2958,6 @@ XREMain::XRE_mainInit(bool* aExitFlag)
|
||||
Telemetry::Accumulate(Telemetry::SANDBOX_BROKER_INITIALIZED, true);
|
||||
} else {
|
||||
Telemetry::Accumulate(Telemetry::SANDBOX_BROKER_INITIALIZED, false);
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
// If we're sandboxing content and we fail to initialize, then crashing here
|
||||
// seems like the sensible option.
|
||||
if (BrowserTabsRemoteAutostart()) {
|
||||
MOZ_CRASH("Failed to initialize broker services, can't continue.");
|
||||
}
|
||||
#endif
|
||||
// Otherwise just warn for the moment, as most things will work.
|
||||
NS_WARNING("Failed to initialize broker services, sandboxed processes will "
|
||||
"fail to start.");
|
||||
|
||||
@@ -79,10 +79,6 @@
|
||||
#include "mozilla/sandboxing/loggingCallbacks.h"
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX) && !defined(MOZ_WIDGET_GONK)
|
||||
#include "mozilla/Preferences.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_IPDL_TESTS
|
||||
#include "mozilla/_ipdltest/IPDLUnitTests.h"
|
||||
#include "mozilla/_ipdltest/IPDLUnitTestProcessChild.h"
|
||||
@@ -539,11 +535,6 @@ XRE_InitChildProcess(int aArgc,
|
||||
// If passed in grab the application path for xpcom init
|
||||
bool foundAppdir = false;
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
// If passed in grab the profile path for sandboxing
|
||||
bool foundProfile = false;
|
||||
#endif
|
||||
|
||||
for (int idx = aArgc; idx > 0; idx--) {
|
||||
if (aArgv[idx] && !strcmp(aArgv[idx], "-appdir")) {
|
||||
MOZ_ASSERT(!foundAppdir);
|
||||
@@ -559,19 +550,6 @@ XRE_InitChildProcess(int aArgc,
|
||||
if (aArgv[idx] && !strcmp(aArgv[idx], "-safeMode")) {
|
||||
gSafeMode = true;
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
if (aArgv[idx] && !strcmp(aArgv[idx], "-profile")) {
|
||||
MOZ_ASSERT(!foundProfile);
|
||||
if (foundProfile) {
|
||||
continue;
|
||||
}
|
||||
nsCString profile;
|
||||
profile.Assign(nsDependentCString(aArgv[idx+1]));
|
||||
static_cast<ContentProcess*>(process.get())->SetProfile(profile);
|
||||
foundProfile = true;
|
||||
}
|
||||
#endif /* XP_MACOSX && MOZ_CONTENT_SANDBOX */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
#include "nsILocalFileMac.h"
|
||||
@@ -63,11 +62,6 @@
|
||||
#include "UIKitDirProvider.h"
|
||||
#endif
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#define APP_REGISTRY_NAME "Application Registry"
|
||||
#elif defined(XP_WIN)
|
||||
@@ -78,14 +72,6 @@
|
||||
|
||||
#define PREF_OVERRIDE_DIRNAME "preferences"
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
static already_AddRefed<nsIFile> GetContentProcessSandboxTempDir();
|
||||
static nsresult DeleteDirIfExists(nsIFile *dir);
|
||||
static bool IsContentSandboxDisabled();
|
||||
static const char* GetContentProcessTempBaseDirKey();
|
||||
static already_AddRefed<nsIFile> CreateContentProcessSandboxTempDir();
|
||||
#endif
|
||||
|
||||
static already_AddRefed<nsIFile>
|
||||
CloneAndAppend(nsIFile* aFile, const char* name)
|
||||
{
|
||||
@@ -496,14 +482,6 @@ nsXREDirProvider::GetFile(const char* aProperty, bool* aPersistent,
|
||||
bool unused;
|
||||
rv = dirsvc->GetFile("XCurProcD", &unused, getter_AddRefs(file));
|
||||
}
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
else if (!strcmp(aProperty, NS_APP_CONTENT_PROCESS_TEMP_DIR)) {
|
||||
if (!mContentTempDir && NS_FAILED((rv = LoadContentProcessTempDir()))) {
|
||||
return rv;
|
||||
}
|
||||
rv = mContentTempDir->Clone(getter_AddRefs(file));
|
||||
}
|
||||
#endif // defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
|
||||
else if (NS_SUCCEEDED(GetProfileStartupDir(getter_AddRefs(file)))) {
|
||||
// We need to allow component, xpt, and chrome registration to
|
||||
// occur prior to the profile-after-change notification.
|
||||
@@ -730,179 +708,6 @@ LoadExtensionDirectories(nsINIParser &parser,
|
||||
while (true);
|
||||
}
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
|
||||
static const char*
|
||||
GetContentProcessTempBaseDirKey()
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
return NS_WIN_LOW_INTEGRITY_TEMP_BASE;
|
||||
#else
|
||||
return NS_OS_TEMP_DIR;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Sets mContentTempDir so that it refers to the appropriate temp dir.
|
||||
// If the sandbox is enabled, NS_APP_CONTENT_PROCESS_TEMP_DIR, otherwise
|
||||
// NS_OS_TEMP_DIR is used.
|
||||
//
|
||||
nsresult
|
||||
nsXREDirProvider::LoadContentProcessTempDir()
|
||||
{
|
||||
mContentTempDir = GetContentProcessSandboxTempDir();
|
||||
if (mContentTempDir) {
|
||||
return NS_OK;
|
||||
} else {
|
||||
return NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
|
||||
getter_AddRefs(mContentTempDir));
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
IsContentSandboxDisabled()
|
||||
{
|
||||
if (!BrowserTabsRemoteAutostart()) {
|
||||
return false;
|
||||
}
|
||||
#if defined(XP_WIN)
|
||||
const bool isSandboxDisabled = !mozilla::IsVistaOrLater() ||
|
||||
(Preferences::GetInt("security.sandbox.content.level") < 1);
|
||||
#elif defined(XP_MACOSX)
|
||||
const bool isSandboxDisabled =
|
||||
Preferences::GetInt("security.sandbox.content.level") < 1;
|
||||
#endif
|
||||
return isSandboxDisabled;
|
||||
}
|
||||
|
||||
//
|
||||
// If a content process sandbox temp dir is to be used, returns an nsIFile
|
||||
// for the directory. Returns null if the content sandbox is disabled or
|
||||
// an error occurs.
|
||||
//
|
||||
static already_AddRefed<nsIFile>
|
||||
GetContentProcessSandboxTempDir()
|
||||
{
|
||||
if (IsContentSandboxDisabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
|
||||
nsresult rv = NS_GetSpecialDirectory(GetContentProcessTempBaseDirKey(),
|
||||
getter_AddRefs(localFile));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoString tempDirSuffix;
|
||||
rv = Preferences::GetString("security.sandbox.content.tempDirSuffix",
|
||||
&tempDirSuffix);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)) || tempDirSuffix.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rv = localFile->Append(NS_LITERAL_STRING("Temp-") + tempDirSuffix);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return localFile.forget();
|
||||
}
|
||||
|
||||
//
|
||||
// Create a temporary directory for use from sandboxed content processes.
|
||||
// Only called in the parent. The path is derived from a UUID stored in a
|
||||
// pref which is available to content processes. Returns null if the
|
||||
// content sandbox is disabled or if an error occurs.
|
||||
//
|
||||
static already_AddRefed<nsIFile>
|
||||
CreateContentProcessSandboxTempDir()
|
||||
{
|
||||
if (IsContentSandboxDisabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Get (and create if blank) temp directory suffix pref.
|
||||
nsresult rv;
|
||||
nsAdoptingString tempDirSuffix =
|
||||
Preferences::GetString("security.sandbox.content.tempDirSuffix");
|
||||
if (tempDirSuffix.IsEmpty()) {
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
||||
do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsID uuid;
|
||||
rv = uuidgen->GenerateUUIDInPlace(&uuid);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char uuidChars[NSID_LENGTH];
|
||||
uuid.ToProvidedString(uuidChars);
|
||||
tempDirSuffix.AssignASCII(uuidChars);
|
||||
|
||||
// Save the pref
|
||||
rv = Preferences::SetCString("security.sandbox.content.tempDirSuffix",
|
||||
uuidChars);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// If we fail to save the pref we don't want to create the temp dir,
|
||||
// because we won't be able to clean it up later.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrefService> prefsvc = Preferences::GetService();
|
||||
if (!prefsvc || NS_FAILED((rv = prefsvc->SavePrefFile(nullptr)))) {
|
||||
// Again, if we fail to save the pref file we might not be able to clean
|
||||
// up the temp directory, so don't create one.
|
||||
NS_WARNING("Failed to save pref file, cannot create temp dir.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> sandboxTempDir = GetContentProcessSandboxTempDir();
|
||||
if (!sandboxTempDir) {
|
||||
NS_WARNING("Failed to determine sandbox temp dir path.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Remove the directory. It may exist due to a previous crash.
|
||||
if (NS_FAILED(DeleteDirIfExists(sandboxTempDir))) {
|
||||
NS_WARNING("Failed to reset sandbox temp dir.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create the directory
|
||||
rv = sandboxTempDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to create sandbox temp dir.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sandboxTempDir.forget();
|
||||
}
|
||||
|
||||
static nsresult
|
||||
DeleteDirIfExists(nsIFile* dir)
|
||||
{
|
||||
if (dir) {
|
||||
// Don't return an error if the directory doesn't exist.
|
||||
// Windows Remove() returns NS_ERROR_FILE_NOT_FOUND while
|
||||
// OS X returns NS_ERROR_FILE_TARGET_DOES_NOT_EXIST.
|
||||
nsresult rv = dir->Remove(/* aRecursive */ true);
|
||||
if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND &&
|
||||
rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif // (defined(XP_WIN) || defined(XP_MACOSX)) &&
|
||||
// defined(MOZ_CONTENT_SANDBOX)
|
||||
|
||||
void
|
||||
nsXREDirProvider::LoadExtensionBundleDirectories()
|
||||
{
|
||||
@@ -1207,14 +1012,6 @@ nsXREDirProvider::DoStartup()
|
||||
}
|
||||
|
||||
obsSvc->NotifyObservers(nullptr, "profile-initial-state", nullptr);
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
// The parent is responsible for creating the sandbox temp dir
|
||||
if (XRE_IsParentProcess()) {
|
||||
mContentProcessSandboxTempDir = CreateContentProcessSandboxTempDir();
|
||||
mContentTempDir = mContentProcessSandboxTempDir;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1225,12 +1022,6 @@ nsXREDirProvider::DoShutdown()
|
||||
PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
|
||||
|
||||
if (mProfileNotified) {
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
if (XRE_IsParentProcess()) {
|
||||
Unused << DeleteDirIfExists(mContentProcessSandboxTempDir);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsSvc =
|
||||
mozilla::services::GetObserverService();
|
||||
NS_ASSERTION(obsSvc, "No observer service?");
|
||||
|
||||
@@ -121,11 +121,6 @@ protected:
|
||||
// delimiters.
|
||||
static inline nsresult AppendProfileString(nsIFile* aFile, const char* aPath);
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
// Load the temp directory for sandboxed content processes
|
||||
nsresult LoadContentProcessTempDir();
|
||||
#endif
|
||||
|
||||
// Calculate and register extension and theme bundle directories.
|
||||
void LoadExtensionBundleDirectories();
|
||||
|
||||
@@ -146,10 +141,6 @@ protected:
|
||||
nsCOMPtr<nsIFile> mProfileDir;
|
||||
nsCOMPtr<nsIFile> mProfileLocalDir;
|
||||
bool mProfileNotified;
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
nsCOMPtr<nsIFile> mContentTempDir;
|
||||
nsCOMPtr<nsIFile> mContentProcessSandboxTempDir;
|
||||
#endif
|
||||
nsCOMArray<nsIFile> mAppBundleDirectories;
|
||||
nsCOMArray<nsIFile> mExtensionDirectories;
|
||||
nsCOMArray<nsIFile> mThemeDirectories;
|
||||
|
||||
@@ -738,14 +738,6 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
case Win_LocalAppdataLow: {
|
||||
// This should only really fail on versions pre-Vista, in which case this
|
||||
// shouldn't have been used in the first place.
|
||||
GUID localAppDataLowGuid = FOLDERID_LocalAppDataLow;
|
||||
return GetKnownFolder(&localAppDataLowGuid, aFile);
|
||||
}
|
||||
#endif
|
||||
case Win_Documents: {
|
||||
return GetLibrarySaveToPath(CSIDL_MYDOCUMENTS,
|
||||
FOLDERID_DocumentsLibrary,
|
||||
|
||||
@@ -79,9 +79,6 @@ enum SystemDirectories {
|
||||
Win_Pictures = 233,
|
||||
Win_Music = 234,
|
||||
Win_Videos = 235,
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
Win_LocalAppdataLow = 236,
|
||||
#endif
|
||||
|
||||
Unix_LocalDirectory = 301,
|
||||
Unix_LibDirectory = 302,
|
||||
|
||||
@@ -84,35 +84,6 @@
|
||||
|
||||
#define NS_APP_PERMISSION_PARENT_DIR "permissionDBPDir"
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
//
|
||||
// NS_APP_CONTENT_PROCESS_TEMP_DIR refers to a directory that is read and
|
||||
// write accessible from a sandboxed content process. The key may be used in
|
||||
// either process, but the directory is intended to be used for short-lived
|
||||
// files that need to be saved to the filesystem by the content process and
|
||||
// don't need to survive browser restarts. The directory is reset on startup.
|
||||
// The key is only valid when MOZ_CONTENT_SANDBOX is defined. When
|
||||
// MOZ_CONTENT_SANDBOX is defined, the directory the key refers to differs
|
||||
// depending on whether or not content sandboxing is enabled.
|
||||
//
|
||||
// When MOZ_CONTENT_SANDBOX is defined and sandboxing is enabled (versus
|
||||
// manually disabled via prefs), the content process replaces NS_OS_TEMP_DIR
|
||||
// with NS_APP_CONTENT_PROCESS_TEMP_DIR so that legacy code in content
|
||||
// attempting to write to NS_OS_TEMP_DIR will write to
|
||||
// NS_APP_CONTENT_PROCESS_TEMP_DIR instead. When MOZ_CONTENT_SANDBOX is
|
||||
// defined but sandboxing is disabled, NS_APP_CONTENT_PROCESS_TEMP_DIR
|
||||
// falls back to NS_OS_TEMP_DIR in both content and chrome processes.
|
||||
//
|
||||
// New code should avoid writing to the filesystem from the content process
|
||||
// and should instead proxy through the parent process whenever possible.
|
||||
//
|
||||
// At present, all sandboxed content processes use the same directory for
|
||||
// NS_APP_CONTENT_PROCESS_TEMP_DIR, but that should not be relied upon.
|
||||
//
|
||||
#define NS_APP_CONTENT_PROCESS_TEMP_DIR "ContentTmpD"
|
||||
#else
|
||||
// Otherwise NS_APP_CONTENT_PROCESS_TEMP_DIR must match NS_OS_TEMP_DIR.
|
||||
#define NS_APP_CONTENT_PROCESS_TEMP_DIR "TmpD"
|
||||
#endif // (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
|
||||
#endif // nsAppDirectoryServiceDefs_h___
|
||||
|
||||
@@ -490,27 +490,6 @@ nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider* aProv)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_WIN)
|
||||
static nsresult
|
||||
GetLowIntegrityTempBase(nsIFile** aLowIntegrityTempBase)
|
||||
{
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
nsresult rv = GetSpecialSystemDirectory(Win_LocalAppdataLow,
|
||||
getter_AddRefs(localFile));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = localFile->Append(NS_LITERAL_STRING(MOZ_USER_DIR));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
localFile.forget(aLowIntegrityTempBase);
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
// DO NOT ADD ANY LOCATIONS TO THIS FUNCTION UNTIL YOU TALK TO: dougt@netscape.com.
|
||||
// This is meant to be a place of xpcom or system specific file locations, not
|
||||
// application specific locations. If you need the later, register a callback for
|
||||
@@ -684,12 +663,6 @@ nsDirectoryService::GetFile(const char* aProp, bool* aPersistent,
|
||||
rv = GetSpecialSystemDirectory(Win_Appdata, getter_AddRefs(localFile));
|
||||
} else if (inAtom == nsDirectoryService::sLocalAppdata) {
|
||||
rv = GetSpecialSystemDirectory(Win_LocalAppdata, getter_AddRefs(localFile));
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
} else if (inAtom == nsDirectoryService::sLocalAppdataLow) {
|
||||
rv = GetSpecialSystemDirectory(Win_LocalAppdataLow, getter_AddRefs(localFile));
|
||||
} else if (inAtom == nsDirectoryService::sLowIntegrityTempBase) {
|
||||
rv = GetLowIntegrityTempBase(getter_AddRefs(localFile));
|
||||
#endif
|
||||
} else if (inAtom == nsDirectoryService::sPrinthood) {
|
||||
rv = GetSpecialSystemDirectory(Win_Printhood, getter_AddRefs(localFile));
|
||||
} else if (inAtom == nsDirectoryService::sWinCookiesDirectory) {
|
||||
|
||||
@@ -72,10 +72,6 @@ DIR_ATOM(sCommon_Desktopdirectory, NS_WIN_COMMON_DESKTOP_DIRECTORY)
|
||||
DIR_ATOM(sCommon_AppData, NS_WIN_COMMON_APPDATA_DIR)
|
||||
DIR_ATOM(sAppdata, NS_WIN_APPDATA_DIR)
|
||||
DIR_ATOM(sLocalAppdata, NS_WIN_LOCAL_APPDATA_DIR)
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
DIR_ATOM(sLocalAppdataLow, NS_WIN_LOCAL_APPDATA_LOW_DIR)
|
||||
DIR_ATOM(sLowIntegrityTempBase, NS_WIN_LOW_INTEGRITY_TEMP_BASE)
|
||||
#endif
|
||||
DIR_ATOM(sPrinthood, NS_WIN_PRINTHOOD)
|
||||
DIR_ATOM(sWinCookiesDirectory, NS_WIN_COOKIES_DIR)
|
||||
DIR_ATOM(sDefaultDownloadDirectory, NS_WIN_DEFAULT_DOWNLOAD_DIR)
|
||||
|
||||
@@ -129,10 +129,6 @@
|
||||
#define NS_WIN_COMMON_APPDATA_DIR "CmAppData"
|
||||
#define NS_WIN_APPDATA_DIR "AppData"
|
||||
#define NS_WIN_LOCAL_APPDATA_DIR "LocalAppData"
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
#define NS_WIN_LOCAL_APPDATA_LOW_DIR "LocalAppDataLow"
|
||||
#define NS_WIN_LOW_INTEGRITY_TEMP_BASE "LowTmpDBase"
|
||||
#endif
|
||||
#define NS_WIN_PRINTHOOD "PrntHd"
|
||||
#define NS_WIN_COOKIES_DIR "CookD"
|
||||
#define NS_WIN_DEFAULT_DOWNLOAD_DIR "DfltDwnld"
|
||||
|
||||
Reference in New Issue
Block a user