Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(853)

Unified Diff: content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc

Issue 99133015: Linux Sandbox: split the GPU policies to their own file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address nits from Mark. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
diff --git a/content/common/sandbox_seccomp_bpf_linux.cc b/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
similarity index 45%
rename from content/common/sandbox_seccomp_bpf_linux.cc
rename to content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
index 484fe734a09094133f0f98226ed0e8ff56423fb3..846a36edd5f4a6cf7aa0a1db0b1ac0759d022fee 100644
--- a/content/common/sandbox_seccomp_bpf_linux.cc
+++ b/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
@@ -24,10 +24,7 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "build/build_config.h"
-#include "content/common/sandbox_linux.h"
-#include "content/common/sandbox_seccomp_bpf_linux.h"
#include "content/public/common/content_switches.h"
-#include "sandbox/linux/services/broker_process.h"
// These are the only architectures supported for now.
#if defined(__i386__) || defined(__x86_64__) || \
@@ -37,7 +34,11 @@
#if defined(SECCOMP_BPF_SANDBOX)
#include "base/posix/eintr_wrapper.h"
-#include "content/common/sandbox_bpf_base_policy_linux.h"
+#include "content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h"
+#include "content/common/sandbox_linux/bpf_gpu_policy_linux.h"
+#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
+#include "content/common/sandbox_linux/sandbox_linux.h"
+#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h"
#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
@@ -47,7 +48,6 @@
#include "sandbox/linux/services/linux_syscalls.h"
using sandbox::BaselinePolicy;
-using sandbox::BrokerProcess;
using sandbox::ErrorCode;
using sandbox::SandboxBPF;
using sandbox::SyscallSets;
@@ -67,22 +67,6 @@ inline bool IsChromeOS() {
#endif
}
-inline bool IsArchitectureX86_64() {
-#if defined(__x86_64__)
- return true;
-#else
- return false;
-#endif
-}
-
-inline bool IsArchitectureI386() {
-#if defined(__i386__)
- return true;
-#else
- return false;
-#endif
-}
-
inline bool IsArchitectureArm() {
#if defined(__arm__)
return true;
@@ -99,194 +83,6 @@ inline bool IsUsingToolKitGtk() {
#endif
}
-// Policies for the GPU process.
-// TODO(jln): move to gpu/
-
-bool IsAcceleratedVideoDecodeEnabled() {
- // Accelerated video decode is currently enabled on Chrome OS,
- // but not on Linux: crbug.com/137247.
- bool is_enabled = IsChromeOS();
-
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- is_enabled = is_enabled &&
- !command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode);
-
- return is_enabled;
-}
-
-intptr_t GpuSIGSYS_Handler(const struct arch_seccomp_data& args,
- void* aux_broker_process) {
- RAW_CHECK(aux_broker_process);
- BrokerProcess* broker_process =
- static_cast<BrokerProcess*>(aux_broker_process);
- switch (args.nr) {
- case __NR_access:
- return broker_process->Access(reinterpret_cast<const char*>(args.args[0]),
- static_cast<int>(args.args[1]));
- case __NR_open:
- return broker_process->Open(reinterpret_cast<const char*>(args.args[0]),
- static_cast<int>(args.args[1]));
- case __NR_openat:
- // Allow using openat() as open().
- if (static_cast<int>(args.args[0]) == AT_FDCWD) {
- return
- broker_process->Open(reinterpret_cast<const char*>(args.args[1]),
- static_cast<int>(args.args[2]));
- } else {
- return -EPERM;
- }
- default:
- RAW_CHECK(false);
- return -ENOSYS;
- }
-}
-
-class GpuProcessPolicy : public SandboxBPFBasePolicy {
- public:
- explicit GpuProcessPolicy(void* broker_process)
- : broker_process_(broker_process) {}
- virtual ~GpuProcessPolicy() {}
-
- virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
- int system_call_number) const OVERRIDE;
-
- private:
- const void* broker_process_; // Non-owning pointer.
- DISALLOW_COPY_AND_ASSIGN(GpuProcessPolicy);
-};
-
-// Main policy for x86_64/i386. Extended by ArmGpuProcessPolicy.
-ErrorCode GpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
- int sysno) const {
- switch (sysno) {
- case __NR_ioctl:
-#if defined(__i386__) || defined(__x86_64__)
- // The Nvidia driver uses flags not in the baseline policy
- // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT)
- case __NR_mmap:
-#endif
- // We also hit this on the linux_chromeos bot but don't yet know what
- // weird flags were involved.
- case __NR_mprotect:
- case __NR_sched_getaffinity:
- case __NR_sched_setaffinity:
- case __NR_setpriority:
- return ErrorCode(ErrorCode::ERR_ALLOWED);
- case __NR_access:
- case __NR_open:
- case __NR_openat:
- return sandbox->Trap(GpuSIGSYS_Handler, broker_process_);
- default:
- if (SyscallSets::IsEventFd(sysno))
- return ErrorCode(ErrorCode::ERR_ALLOWED);
-
- // Default on the baseline policy.
- return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno);
- }
-}
-
-class GpuBrokerProcessPolicy : public GpuProcessPolicy {
- public:
- GpuBrokerProcessPolicy() : GpuProcessPolicy(NULL) {}
- virtual ~GpuBrokerProcessPolicy() {}
-
- virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
- int system_call_number) const OVERRIDE;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GpuBrokerProcessPolicy);
-};
-
-// x86_64/i386.
-// A GPU broker policy is the same as a GPU policy with open and
-// openat allowed.
-ErrorCode GpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
- int sysno) const {
- switch (sysno) {
- case __NR_access:
- case __NR_open:
- case __NR_openat:
- return ErrorCode(ErrorCode::ERR_ALLOWED);
- default:
- return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno);
- }
-}
-
-class ArmGpuProcessPolicy : public GpuProcessPolicy {
- public:
- explicit ArmGpuProcessPolicy(void* broker_process, bool allow_shmat)
- : GpuProcessPolicy(broker_process), allow_shmat_(allow_shmat) {}
- virtual ~ArmGpuProcessPolicy() {}
-
- virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
- int system_call_number) const OVERRIDE;
-
- private:
- const bool allow_shmat_; // Allow shmat(2).
- DISALLOW_COPY_AND_ASSIGN(ArmGpuProcessPolicy);
-};
-
-// Generic ARM GPU process sandbox, inheriting from GpuProcessPolicy.
-ErrorCode ArmGpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
- int sysno) const {
-#if defined(__arm__)
- if (allow_shmat_ && sysno == __NR_shmat)
- return ErrorCode(ErrorCode::ERR_ALLOWED);
-#endif // defined(__arm__)
-
- switch (sysno) {
-#if defined(__arm__)
- // ARM GPU sandbox is started earlier so we need to allow networking
- // in the sandbox.
- case __NR_connect:
- case __NR_getpeername:
- case __NR_getsockname:
- case __NR_sysinfo:
- case __NR_uname:
- return ErrorCode(ErrorCode::ERR_ALLOWED);
- // Allow only AF_UNIX for |domain|.
- case __NR_socket:
- case __NR_socketpair:
- return sandbox->Cond(0, ErrorCode::TP_32BIT,
- ErrorCode::OP_EQUAL, AF_UNIX,
- ErrorCode(ErrorCode::ERR_ALLOWED),
- ErrorCode(EPERM));
-#endif // defined(__arm__)
- default:
- if (SyscallSets::IsAdvancedScheduler(sysno))
- return ErrorCode(ErrorCode::ERR_ALLOWED);
-
- // Default to the generic GPU policy.
- return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno);
- }
-}
-
-class ArmGpuBrokerProcessPolicy : public ArmGpuProcessPolicy {
- public:
- ArmGpuBrokerProcessPolicy() : ArmGpuProcessPolicy(NULL, false) {}
- virtual ~ArmGpuBrokerProcessPolicy() {}
-
- virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
- int system_call_number) const OVERRIDE;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ArmGpuBrokerProcessPolicy);
-};
-
-// A GPU broker policy is the same as a GPU policy with open and
-// openat allowed.
-ErrorCode ArmGpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
- int sysno) const {
- switch (sysno) {
- case __NR_access:
- case __NR_open:
- case __NR_openat:
- return ErrorCode(ErrorCode::ERR_ALLOWED);
- default:
- return ArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno);
- }
-}
-
// Policy for renderer and worker processes.
// TODO(jln): move to renderer/
@@ -480,199 +276,6 @@ void RunSandboxSanityChecks(const std::string& process_type) {
}
}
-bool EnableGpuBrokerPolicyCallback() {
- StartSandboxWithPolicy(new GpuBrokerProcessPolicy);
- return true;
-}
-
-bool EnableArmGpuBrokerPolicyCallback() {
- StartSandboxWithPolicy(new ArmGpuBrokerProcessPolicy);
- return true;
-}
-
-// Files needed by the ARM GPU userspace.
-static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
-static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";
-
-void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist,
- std::vector<std::string>* write_whitelist) {
- // Device file needed by the ARM GPU userspace.
- static const char kMali0Path[] = "/dev/mali0";
-
- // Devices needed for video decode acceleration on ARM.
- static const char kDevMfcDecPath[] = "/dev/mfc-dec";
- static const char kDevGsc1Path[] = "/dev/gsc1";
-
- // Devices needed for video encode acceleration on ARM.
- static const char kDevMfcEncPath[] = "/dev/mfc-enc";
-
- read_whitelist->push_back(kMali0Path);
- read_whitelist->push_back(kDevMfcDecPath);
- read_whitelist->push_back(kDevGsc1Path);
- read_whitelist->push_back(kDevMfcEncPath);
-
- write_whitelist->push_back(kMali0Path);
- write_whitelist->push_back(kDevMfcDecPath);
- write_whitelist->push_back(kDevGsc1Path);
- write_whitelist->push_back(kDevMfcEncPath);
-}
-
-void AddArmTegraGpuWhitelist(std::vector<std::string>* read_whitelist,
- std::vector<std::string>* write_whitelist) {
- // Device files needed by the Tegra GPU userspace.
- static const char kDevNvhostCtrlPath[] = "/dev/nvhost-ctrl";
- static const char kDevNvhostGr2dPath[] = "/dev/nvhost-gr2d";
- static const char kDevNvhostGr3dPath[] = "/dev/nvhost-gr3d";
- static const char kDevNvhostIspPath[] = "/dev/nvhost-isp";
- static const char kDevNvhostViPath[] = "/dev/nvhost-vi";
- static const char kDevNvmapPath[] = "/dev/nvmap";
- static const char kDevTegraSemaPath[] = "/dev/tegra_sema";
-
- read_whitelist->push_back(kDevNvhostCtrlPath);
- read_whitelist->push_back(kDevNvhostGr2dPath);
- read_whitelist->push_back(kDevNvhostGr3dPath);
- read_whitelist->push_back(kDevNvhostIspPath);
- read_whitelist->push_back(kDevNvhostViPath);
- read_whitelist->push_back(kDevNvmapPath);
- read_whitelist->push_back(kDevTegraSemaPath);
-
- write_whitelist->push_back(kDevNvhostCtrlPath);
- write_whitelist->push_back(kDevNvhostGr2dPath);
- write_whitelist->push_back(kDevNvhostGr3dPath);
- write_whitelist->push_back(kDevNvhostIspPath);
- write_whitelist->push_back(kDevNvhostViPath);
- write_whitelist->push_back(kDevNvmapPath);
- write_whitelist->push_back(kDevTegraSemaPath);
-}
-
-void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist,
- std::vector<std::string>* write_whitelist) {
- // On ARM we're enabling the sandbox before the X connection is made,
- // so we need to allow access to |.Xauthority|.
- static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
- static const char kLdSoCache[] = "/etc/ld.so.cache";
-
- read_whitelist->push_back(kXAuthorityPath);
- read_whitelist->push_back(kLdSoCache);
- read_whitelist->push_back(kLibGlesPath);
- read_whitelist->push_back(kLibEglPath);
-
- AddArmMaliGpuWhitelist(read_whitelist, write_whitelist);
- AddArmTegraGpuWhitelist(read_whitelist, write_whitelist);
-}
-
-// Start a broker process to handle open() inside the sandbox.
-void InitGpuBrokerProcess(bool for_chromeos_arm,
- BrokerProcess** broker_process) {
- static const char kDriRcPath[] = "/etc/drirc";
- static const char kDriCard0Path[] = "/dev/dri/card0";
-
- CHECK(broker_process);
- CHECK(*broker_process == NULL);
-
- bool (*sandbox_callback)(void) = NULL;
-
- // All GPU process policies need these files brokered out.
- std::vector<std::string> read_whitelist;
- read_whitelist.push_back(kDriCard0Path);
- read_whitelist.push_back(kDriRcPath);
-
- std::vector<std::string> write_whitelist;
- write_whitelist.push_back(kDriCard0Path);
-
- if (for_chromeos_arm) {
- // We shouldn't be using this policy on non-ARM architectures.
- DCHECK(IsArchitectureArm());
- AddArmGpuWhitelist(&read_whitelist, &write_whitelist);
- sandbox_callback = EnableArmGpuBrokerPolicyCallback;
- } else {
- sandbox_callback = EnableGpuBrokerPolicyCallback;
- }
-
- *broker_process = new BrokerProcess(SandboxBPFBasePolicy::GetFSDeniedErrno(),
- read_whitelist,
- write_whitelist);
- // Initialize the broker process and give it a sandbox callback.
- CHECK((*broker_process)->Init(sandbox_callback));
-}
-
-// Warms up/preloads resources needed by the policies.
-// Eventually start a broker process and return it in broker_process.
-void WarmupPolicy(bool chromeos_arm_gpu,
- BrokerProcess** broker_process) {
- if (!chromeos_arm_gpu) {
- // Create a new broker process.
- InitGpuBrokerProcess(false /* not for ChromeOS ARM */, broker_process);
-
- if (IsArchitectureX86_64() || IsArchitectureI386()) {
- // Accelerated video decode dlopen()'s some shared objects
- // inside the sandbox, so preload them now.
- if (IsAcceleratedVideoDecodeEnabled()) {
- const char* I965DrvVideoPath = NULL;
-
- if (IsArchitectureX86_64()) {
- I965DrvVideoPath = "/usr/lib64/va/drivers/i965_drv_video.so";
- } else if (IsArchitectureI386()) {
- I965DrvVideoPath = "/usr/lib/va/drivers/i965_drv_video.so";
- }
-
- dlopen(I965DrvVideoPath, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- dlopen("libva.so.1", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- dlopen("libva-x11.so.1", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- }
- }
- } else {
- // ChromeOS ARM GPU policy.
- // Create a new broker process.
- InitGpuBrokerProcess(true /* for ChromeOS ARM */, broker_process);
-
- // Preload the Mali library.
- dlopen("/usr/lib/libmali.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
-
- // Preload the Tegra libraries.
- dlopen("/usr/lib/libnvrm.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- dlopen("/usr/lib/libnvrm_graphics.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- dlopen("/usr/lib/libnvos.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- dlopen("/usr/lib/libnvddk_2d.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- dlopen("/usr/lib/libardrv_dynamic.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- dlopen("/usr/lib/libnvwsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- dlopen("/usr/lib/libnvglsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- dlopen("/usr/lib/libcgdrv.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
- }
-}
-
-void StartGpuProcessSandbox(const CommandLine& command_line,
- const std::string& process_type) {
- bool chromeos_arm_gpu = false;
- bool allow_sysv_shm = false;
-
- if (process_type == switches::kGpuProcess) {
- // On Chrome OS ARM, we need a specific GPU process policy.
- if (IsChromeOS() && IsArchitectureArm()) {
- chromeos_arm_gpu = true;
- if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm)) {
- allow_sysv_shm = true;
- }
- }
- }
-
- // This should never be destroyed, as after the sandbox is started it is
- // vital to the process. Ownership is transfered to the policies and then to
- // the BPF sandbox which will keep it around to service SIGSYS traps from the
- // kernel.
- BrokerProcess* broker_process = NULL;
- // Warm up resources needed by the policy we're about to enable and
- // eventually start a broker process.
- WarmupPolicy(chromeos_arm_gpu, &broker_process);
-
- scoped_ptr<SandboxBPFBasePolicy> gpu_policy;
- if (chromeos_arm_gpu) {
- gpu_policy.reset(new ArmGpuProcessPolicy(broker_process, allow_sysv_shm));
- } else {
- gpu_policy.reset(new GpuProcessPolicy(broker_process));
- }
- StartSandboxWithPolicy(gpu_policy.release());
-}
// This function takes ownership of |policy|.
void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* policy) {
@@ -686,11 +289,34 @@ void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* policy) {
sandbox.StartSandbox();
}
-void StartNonGpuSandbox(const std::string& process_type) {
+// nacl_helper needs to be tiny and includes only part of content/
+// in its dependencies. Make sure to not link things that are not needed.
+#if !defined(IN_NACL_HELPER)
+scoped_ptr<SandboxBPFBasePolicy> GetGpuProcessSandbox() {
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ bool allow_sysv_shm = false;
+ if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm)) {
+ DCHECK(IsArchitectureArm());
+ allow_sysv_shm = true;
+ }
+
+ if (IsChromeOS() && IsArchitectureArm()) {
+ return scoped_ptr<SandboxBPFBasePolicy>(
+ new CrosArmGpuProcessPolicy(allow_sysv_shm));
+ } else {
+ return scoped_ptr<SandboxBPFBasePolicy>(new GpuProcessPolicy);
+ }
+}
+
+// Initialize the seccomp-bpf sandbox.
+bool StartBPFSandbox(const CommandLine& command_line,
+ const std::string& process_type) {
scoped_ptr<SandboxBPFBasePolicy> policy;
- if (process_type == switches::kRendererProcess ||
- process_type == switches::kWorkerProcess) {
+ if (process_type == switches::kGpuProcess) {
+ policy.reset(GetGpuProcessSandbox().release());
+ } else if (process_type == switches::kRendererProcess ||
+ process_type == switches::kWorkerProcess) {
policy.reset(new RendererOrWorkerProcessPolicy);
} else if (process_type == switches::kPpapiPluginProcess) {
policy.reset(new FlashProcessPolicy);
@@ -701,22 +327,23 @@ void StartNonGpuSandbox(const std::string& process_type) {
policy.reset(new AllowAllPolicy);
}
+ CHECK(policy->PreSandboxHook());
StartSandboxWithPolicy(policy.release());
-}
-
-// Initialize the seccomp-bpf sandbox.
-bool StartBPFSandbox(const CommandLine& command_line,
- const std::string& process_type) {
-
- if (process_type == switches::kGpuProcess) {
- StartGpuProcessSandbox(command_line, process_type);
- } else {
- StartNonGpuSandbox(process_type);
- }
RunSandboxSanityChecks(process_type);
return true;
}
+#else // defined(IN_NACL_HELPER)
+bool StartBPFSandbox(const CommandLine& command_line,
+ const std::string& process_type) {
+ NOTREACHED();
+ // Avoid -Wunused-function with no-op code.
+ ignore_result(IsChromeOS);
+ ignore_result(IsArchitectureArm);
+ ignore_result(RunSandboxSanityChecks);
+ return false;
+}
+#endif // !defined(IN_NACL_HELPER)
} // namespace
« no previous file with comments | « content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h ('k') | content/common/sandbox_seccomp_bpf_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698