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 23 using sandbox::ErrorCode; 24 using sandbox::SandboxBPF; 25 using sandbox::SandboxBPFPolicy; 26 27 namespace nacl { 28 29 namespace { 30 31 class 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 45 ErrorCode 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 107 void 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 126 bool 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