1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "components/nacl/loader/sandbox_linux/nacl_bpf_sandbox_linux.h" 6 7#include <errno.h> 8#include <signal.h> 9#include <sys/ptrace.h> 10 11#include "base/basictypes.h" 12#include "base/callback.h" 13#include "base/compiler_specific.h" 14#include "base/logging.h" 15#include "build/build_config.h" 16 17#if defined(USE_SECCOMP_BPF) 18#include "content/public/common/sandbox_init.h" 19#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" 20#include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" 21#include "sandbox/linux/services/linux_syscalls.h" 22 23using sandbox::ErrorCode; 24using sandbox::SandboxBPF; 25using sandbox::SandboxBPFPolicy; 26 27namespace nacl { 28 29namespace { 30 31class NaClBPFSandboxPolicy : public SandboxBPFPolicy { 32 public: 33 NaClBPFSandboxPolicy() 34 : baseline_policy_(content::GetBPFSandboxBaselinePolicy()) {} 35 virtual ~NaClBPFSandboxPolicy() {} 36 37 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, 38 int system_call_number) const OVERRIDE; 39 40 private: 41 scoped_ptr<SandboxBPFPolicy> baseline_policy_; 42 DISALLOW_COPY_AND_ASSIGN(NaClBPFSandboxPolicy); 43}; 44 45ErrorCode NaClBPFSandboxPolicy::EvaluateSyscall( 46 sandbox::SandboxBPF* sb, int sysno) const { 47 DCHECK(baseline_policy_); 48 switch (sysno) { 49 // TODO(jln): NaCl's GDB debug stub uses the following socket system calls, 50 // see if it can be restricted a bit. 51#if defined(__x86_64__) || defined(__arm__) 52 // transport_common.cc needs this. 53 case __NR_accept: 54 case __NR_setsockopt: 55#elif defined(__i386__) 56 case __NR_socketcall: 57#endif 58 // trusted/service_runtime/linux/thread_suspension.c needs sigwait() and is 59 // used by NaCl's GDB debug stub. 60 case __NR_rt_sigtimedwait: 61#if defined(__i386__) 62 // Needed on i386 to set-up the custom segments. 63 case __NR_modify_ldt: 64#endif 65 // NaClAddrSpaceBeforeAlloc needs prlimit64. 66 case __NR_prlimit64: 67 // NaCl uses custom signal stacks. 68 case __NR_sigaltstack: 69 // Below is fairly similar to the policy for a Chromium renderer. 70#if defined(__i386__) || defined(__x86_64__) 71 case __NR_getrlimit: 72#endif 73#if defined(__i386__) || defined(__arm__) 74 case __NR_ugetrlimit: 75#endif 76 // NaCl runtime exposes clock_getres to untrusted code. 77 case __NR_clock_getres: 78 // NaCl runtime uses flock to simulate POSIX behavior for pwrite. 79 case __NR_flock: 80 case __NR_pread64: 81 case __NR_pwrite64: 82 case __NR_sched_get_priority_max: 83 case __NR_sched_get_priority_min: 84 case __NR_sched_getaffinity: 85 case __NR_sched_getparam: 86 case __NR_sched_getscheduler: 87 case __NR_sched_setscheduler: 88 case __NR_setpriority: 89 case __NR_sysinfo: 90 // __NR_times needed as clock() is called by CommandBufferHelper, which is 91 // used by NaCl applications that use Pepper's 3D interfaces. 92 // See crbug.com/264856 for details. 93 case __NR_times: 94 case __NR_uname: 95 return ErrorCode(ErrorCode::ERR_ALLOWED); 96 case __NR_ioctl: 97 case __NR_ptrace: 98 return ErrorCode(EPERM); 99 default: 100 return baseline_policy_->EvaluateSyscall(sb, sysno); 101 } 102 NOTREACHED(); 103 // GCC wants this. 104 return ErrorCode(EPERM); 105} 106 107void RunSandboxSanityChecks() { 108 errno = 0; 109 // Make a ptrace request with an invalid PID. 110 long ptrace_ret = ptrace(PTRACE_PEEKUSER, -1 /* pid */, NULL, NULL); 111 CHECK_EQ(-1, ptrace_ret); 112 // Without the sandbox on, this ptrace call would ESRCH instead. 113 CHECK_EQ(EPERM, errno); 114} 115 116} // namespace 117 118#else 119 120#if !defined(ARCH_CPU_MIPS_FAMILY) 121#error "Seccomp-bpf disabled on supported architecture!" 122#endif 123 124#endif // defined(USE_SECCOMP_BPF) 125 126bool InitializeBPFSandbox() { 127#if defined(USE_SECCOMP_BPF) 128 bool sandbox_is_initialized = content::InitializeSandbox( 129 scoped_ptr<SandboxBPFPolicy>(new NaClBPFSandboxPolicy())); 130 if (sandbox_is_initialized) { 131 RunSandboxSanityChecks(); 132 return true; 133 } 134#endif // defined(USE_SECCOMP_BPF) 135 return false; 136} 137 138} // namespace nacl 139