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..1864202554b3992c9e69e393b38c409177a1f2a6 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,24 @@ 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(); |
+ return false; |
Mark Seaborn
2013/12/13 01:08:47
Redundant when there's another return later? It l
jln (very slow on Chromium)
2013/12/13 01:31:31
It was to make it absolutely clear that what's bel
|
+ // Avoid -Wunused-function with clearly dead code. |
+ ignore_result(IsChromeOS); |
+ ignore_result(IsArchitectureArm); |
+ ignore_result(RunSandboxSanityChecks); |
+ return false; |
+} |
+#endif // !defined(IN_NACL_HELPER) |
} // namespace |