forked from mirrors/gecko-dev
Bug 1839834 - Allow per-sandbox disabling on Utility r=jld
Differential Revision: https://phabricator.services.mozilla.com/D181782
This commit is contained in:
parent
bef38031b7
commit
a9ee883ccf
11 changed files with 144 additions and 12 deletions
|
|
@ -91,6 +91,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mozilla/ipc/UtilityProcessHost.h"
|
#include "mozilla/ipc/UtilityProcessHost.h"
|
||||||
|
#include "mozilla/ipc/UtilityProcessSandboxing.h"
|
||||||
|
|
||||||
#include "nsClassHashtable.h"
|
#include "nsClassHashtable.h"
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
|
|
@ -634,7 +635,7 @@ void GeckoChildProcessHost::PrepareLaunch() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
||||||
SandboxLaunchPrepare(mProcessType, mLaunchOptions.get());
|
SandboxLaunchPrepare(mProcessType, mLaunchOptions.get(), mSandbox);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
|
|
@ -1524,7 +1525,7 @@ Result<Ok, LaunchError> WindowsProcessLauncher::DoSetup() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GeckoProcessType_Utility:
|
case GeckoProcessType_Utility:
|
||||||
if (!PR_GetEnv("MOZ_DISABLE_UTILITY_SANDBOX")) {
|
if (IsUtilitySandboxEnabled(mSandbox)) {
|
||||||
if (!mResults.mSandboxBroker->SetSecurityLevelForUtilityProcess(
|
if (!mResults.mSandboxBroker->SetSecurityLevelForUtilityProcess(
|
||||||
mSandbox)) {
|
mSandbox)) {
|
||||||
return Err(LaunchError("SetSecurityLevelForUtilityProcess"));
|
return Err(LaunchError("SetSecurityLevelForUtilityProcess"));
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/ipc/Endpoint.h"
|
#include "mozilla/ipc/Endpoint.h"
|
||||||
#include "mozilla/ipc/UtilityProcessManager.h"
|
#include "mozilla/ipc/UtilityProcessManager.h"
|
||||||
|
#include "mozilla/ipc/UtilityProcessSandboxing.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
|
|
||||||
#include "chrome/common/process_watcher.h"
|
#include "chrome/common/process_watcher.h"
|
||||||
|
|
@ -52,8 +53,7 @@ UtilityProcessHost::UtilityProcessHost(SandboxingKind aSandbox,
|
||||||
|
|
||||||
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
|
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
|
||||||
if (!sLaunchWithMacSandbox) {
|
if (!sLaunchWithMacSandbox) {
|
||||||
sLaunchWithMacSandbox =
|
sLaunchWithMacSandbox = IsUtilitySandboxEnabled(aSandbox);
|
||||||
(PR_GetEnv("MOZ_DISABLE_UTILITY_SANDBOX") == nullptr);
|
|
||||||
}
|
}
|
||||||
mDisableOSActivityMode = sLaunchWithMacSandbox;
|
mDisableOSActivityMode = sLaunchWithMacSandbox;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
55
ipc/glue/UtilityProcessSandboxing.cpp
Normal file
55
ipc/glue/UtilityProcessSandboxing.cpp
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include "UtilityProcessSandboxing.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "prenv.h"
|
||||||
|
|
||||||
|
namespace mozilla::ipc {
|
||||||
|
|
||||||
|
std::vector<std::string> split(const std::string& str, char s) {
|
||||||
|
std::vector<std::string> rv;
|
||||||
|
size_t last = 0;
|
||||||
|
size_t i;
|
||||||
|
size_t c = str.size();
|
||||||
|
for (i = 0; i <= c; ++i) {
|
||||||
|
if (i == c || str[i] == s) {
|
||||||
|
rv.push_back(str.substr(last, i - last));
|
||||||
|
last = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsUtilitySandboxEnabled(const char* envVar, SandboxingKind aKind) {
|
||||||
|
if (envVar == nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string disableUtility(envVar);
|
||||||
|
if (disableUtility == "1") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> components = split(disableUtility, ',');
|
||||||
|
const std::string thisKind = "utility:" + std::to_string(aKind);
|
||||||
|
for (const std::string& thisOne : components) {
|
||||||
|
if (thisOne == thisKind) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsUtilitySandboxEnabled(SandboxingKind aKind) {
|
||||||
|
return IsUtilitySandboxEnabled(PR_GetEnv("MOZ_DISABLE_UTILITY_SANDBOX"),
|
||||||
|
aKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla::ipc
|
||||||
|
|
@ -35,6 +35,9 @@ enum SandboxingKind : uint64_t {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool IsUtilitySandboxEnabled(const char* envVar, SandboxingKind aKind);
|
||||||
|
bool IsUtilitySandboxEnabled(SandboxingKind aKind);
|
||||||
|
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ UNIFIED_SOURCES += [
|
||||||
"UtilityProcessImpl.cpp",
|
"UtilityProcessImpl.cpp",
|
||||||
"UtilityProcessManager.cpp",
|
"UtilityProcessManager.cpp",
|
||||||
"UtilityProcessParent.cpp",
|
"UtilityProcessParent.cpp",
|
||||||
|
"UtilityProcessSandboxing.cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
|
|
|
||||||
66
ipc/glue/test/gtest/TestUtilityProcessSandboxing.cpp
Normal file
66
ipc/glue/test/gtest/TestUtilityProcessSandboxing.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "mozilla/gtest/MozHelpers.h"
|
||||||
|
#include "mozilla/ipc/UtilityProcessSandboxing.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
using namespace mozilla::ipc;
|
||||||
|
|
||||||
|
TEST(UtilityProcessSandboxing, ParseNoEnvVar)
|
||||||
|
{ EXPECT_TRUE(IsUtilitySandboxEnabled("", SandboxingKind::COUNT)); }
|
||||||
|
|
||||||
|
TEST(UtilityProcessSandboxing, ParseEnvVar_DisableAll)
|
||||||
|
{ EXPECT_FALSE(IsUtilitySandboxEnabled("1", SandboxingKind::COUNT)); }
|
||||||
|
|
||||||
|
TEST(UtilityProcessSandboxing, ParseEnvVar_DontDisableAll)
|
||||||
|
{ EXPECT_TRUE(IsUtilitySandboxEnabled("0", SandboxingKind::COUNT)); }
|
||||||
|
|
||||||
|
TEST(UtilityProcessSandboxing, ParseEnvVar_DisableGenericOnly)
|
||||||
|
{
|
||||||
|
EXPECT_FALSE(
|
||||||
|
IsUtilitySandboxEnabled("utility:0", SandboxingKind::GENERIC_UTILITY));
|
||||||
|
EXPECT_TRUE(IsUtilitySandboxEnabled("utility:0", SandboxingKind::COUNT));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(XP_DARWIN)
|
||||||
|
TEST(UtilityProcessSandboxing, ParseEnvVar_DisableAppleAudioOnly)
|
||||||
|
{
|
||||||
|
EXPECT_FALSE(IsUtilitySandboxEnabled(
|
||||||
|
"utility:1", SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA));
|
||||||
|
EXPECT_TRUE(
|
||||||
|
IsUtilitySandboxEnabled("utility:1", SandboxingKind::GENERIC_UTILITY));
|
||||||
|
}
|
||||||
|
#endif // defined(XP_DARWIN)
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
TEST(UtilityProcessSandboxing, ParseEnvVar_DisableWMFOnly)
|
||||||
|
{
|
||||||
|
EXPECT_FALSE(IsUtilitySandboxEnabled(
|
||||||
|
"utility:1", SandboxingKind::UTILITY_AUDIO_DECODING_WMF));
|
||||||
|
EXPECT_TRUE(
|
||||||
|
IsUtilitySandboxEnabled("utility:1", SandboxingKind::GENERIC_UTILITY));
|
||||||
|
}
|
||||||
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
|
TEST(UtilityProcessSandboxing, ParseEnvVar_DisableGenericOnly_Multiples)
|
||||||
|
{
|
||||||
|
EXPECT_FALSE(IsUtilitySandboxEnabled("utility:1,utility:0,utility:2",
|
||||||
|
SandboxingKind::GENERIC_UTILITY));
|
||||||
|
#if defined(XP_DARWIN)
|
||||||
|
EXPECT_FALSE(IsUtilitySandboxEnabled(
|
||||||
|
"utility:1,utility:0,utility:2",
|
||||||
|
SandboxingKind::UTILITY_AUDIO_DECODING_APPLE_MEDIA));
|
||||||
|
#endif // XP_DARWIN
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
EXPECT_FALSE(
|
||||||
|
IsUtilitySandboxEnabled("utility:1,utility:0,utility:2",
|
||||||
|
SandboxingKind::UTILITY_AUDIO_DECODING_WMF));
|
||||||
|
#endif // XP_WIN
|
||||||
|
EXPECT_TRUE(IsUtilitySandboxEnabled("utility:8,utility:0,utility:6",
|
||||||
|
SandboxingKind::COUNT));
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ Library("ipcgluetest")
|
||||||
UNIFIED_SOURCES = [
|
UNIFIED_SOURCES = [
|
||||||
"TestAsyncBlockers.cpp",
|
"TestAsyncBlockers.cpp",
|
||||||
"TestUtilityProcess.cpp",
|
"TestUtilityProcess.cpp",
|
||||||
|
"TestUtilityProcessSandboxing.cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#include "mozilla/Span.h"
|
#include "mozilla/Span.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
|
#include "mozilla/ipc/UtilityProcessSandboxing.h"
|
||||||
#include "prenv.h"
|
#include "prenv.h"
|
||||||
#include "base/posix/eintr_wrapper.h"
|
#include "base/posix/eintr_wrapper.h"
|
||||||
#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
|
#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
|
||||||
|
|
@ -733,7 +734,7 @@ void SetSocketProcessSandbox(int aBroker) {
|
||||||
|
|
||||||
void SetUtilitySandbox(int aBroker, ipc::SandboxingKind aKind) {
|
void SetUtilitySandbox(int aBroker, ipc::SandboxingKind aKind) {
|
||||||
if (!SandboxInfo::Get().Test(SandboxInfo::kHasSeccompBPF) ||
|
if (!SandboxInfo::Get().Test(SandboxInfo::kHasSeccompBPF) ||
|
||||||
PR_GetEnv("MOZ_DISABLE_UTILITY_SANDBOX")) {
|
!IsUtilitySandboxEnabled(aKind)) {
|
||||||
if (aBroker >= 0) {
|
if (aBroker >= 0) {
|
||||||
close(aBroker);
|
close(aBroker);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include "mozilla/StaticPrefs_media.h"
|
#include "mozilla/StaticPrefs_media.h"
|
||||||
#include "mozilla/StaticPrefs_security.h"
|
#include "mozilla/StaticPrefs_security.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
|
#include "mozilla/ipc/UtilityProcessSandboxing.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsIGfxInfo.h"
|
#include "nsIGfxInfo.h"
|
||||||
|
|
@ -238,7 +239,8 @@ class SandboxFork : public base::LaunchOptions::ForkDelegate {
|
||||||
SandboxFork& operator=(const SandboxFork&) = delete;
|
SandboxFork& operator=(const SandboxFork&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int GetEffectiveSandboxLevel(GeckoProcessType aType) {
|
static int GetEffectiveSandboxLevel(GeckoProcessType aType,
|
||||||
|
ipc::SandboxingKind aKind) {
|
||||||
auto info = SandboxInfo::Get();
|
auto info = SandboxInfo::Get();
|
||||||
switch (aType) {
|
switch (aType) {
|
||||||
case GeckoProcessType_GMPlugin:
|
case GeckoProcessType_GMPlugin:
|
||||||
|
|
@ -266,14 +268,14 @@ static int GetEffectiveSandboxLevel(GeckoProcessType aType) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
return GetEffectiveSocketProcessSandboxLevel();
|
return GetEffectiveSocketProcessSandboxLevel();
|
||||||
case GeckoProcessType_Utility:
|
case GeckoProcessType_Utility:
|
||||||
return PR_GetEnv("MOZ_DISABLE_UTILITY_SANDBOX") == nullptr ? 1 : 0;
|
return IsUtilitySandboxEnabled(aKind);
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SandboxLaunchPrepare(GeckoProcessType aType,
|
void SandboxLaunchPrepare(GeckoProcessType aType, base::LaunchOptions* aOptions,
|
||||||
base::LaunchOptions* aOptions) {
|
ipc::SandboxingKind aKind) {
|
||||||
auto info = SandboxInfo::Get();
|
auto info = SandboxInfo::Get();
|
||||||
|
|
||||||
// We won't try any kind of sandboxing without seccomp-bpf.
|
// We won't try any kind of sandboxing without seccomp-bpf.
|
||||||
|
|
@ -282,7 +284,7 @@ void SandboxLaunchPrepare(GeckoProcessType aType,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check prefs (and env vars) controlling sandbox use.
|
// Check prefs (and env vars) controlling sandbox use.
|
||||||
int level = GetEffectiveSandboxLevel(aType);
|
int level = GetEffectiveSandboxLevel(aType, aKind);
|
||||||
if (level == 0) {
|
if (level == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#define mozilla_SandboxLaunch_h
|
#define mozilla_SandboxLaunch_h
|
||||||
|
|
||||||
#include "base/process_util.h"
|
#include "base/process_util.h"
|
||||||
|
#include "mozilla/ipc/UtilityProcessSandboxing.h"
|
||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -16,8 +17,8 @@ namespace mozilla {
|
||||||
// Called in the parent process to set up launch-time aspects of
|
// Called in the parent process to set up launch-time aspects of
|
||||||
// sandboxing. If aType is GeckoProcessType_Content, this must be
|
// sandboxing. If aType is GeckoProcessType_Content, this must be
|
||||||
// called on the main thread in order to access prefs.
|
// called on the main thread in order to access prefs.
|
||||||
void SandboxLaunchPrepare(GeckoProcessType aType,
|
void SandboxLaunchPrepare(GeckoProcessType aType, base::LaunchOptions* aOptions,
|
||||||
base::LaunchOptions* aOptions);
|
ipc::SandboxingKind aKind);
|
||||||
#if defined(MOZ_ENABLE_FORKSERVER)
|
#if defined(MOZ_ENABLE_FORKSERVER)
|
||||||
void SandboxLaunchForkServerPrepare(const std::vector<std::string>& aArgv,
|
void SandboxLaunchForkServerPrepare(const std::vector<std::string>& aArgv,
|
||||||
base::LaunchOptions& aOptions);
|
base::LaunchOptions& aOptions);
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ UNIFIED_SOURCES += [
|
||||||
"../chromium/sandbox/linux/bpf_dsl/syscall_set.cc",
|
"../chromium/sandbox/linux/bpf_dsl/syscall_set.cc",
|
||||||
"../chromium/sandbox/linux/seccomp-bpf/die.cc",
|
"../chromium/sandbox/linux/seccomp-bpf/die.cc",
|
||||||
"../chromium/sandbox/linux/seccomp-bpf/syscall.cc",
|
"../chromium/sandbox/linux/seccomp-bpf/syscall.cc",
|
||||||
|
"/ipc/glue/UtilityProcessSandboxing.cpp",
|
||||||
"broker/SandboxBrokerCommon.cpp",
|
"broker/SandboxBrokerCommon.cpp",
|
||||||
"Sandbox.cpp",
|
"Sandbox.cpp",
|
||||||
"SandboxBrokerClient.cpp",
|
"SandboxBrokerClient.cpp",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue