Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / common / sandbox_linux / bpf_cros_arm_gpu_policy_linux.cc
1 // Copyright (c) 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 "content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h"
6
7 #include <dlfcn.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <sys/socket.h>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14
15 #include <string>
16 #include <vector>
17
18 #include "base/bind.h"
19 #include "base/compiler_specific.h"
20 #include "base/logging.h"
21 #include "base/memory/scoped_ptr.h"
22 #include "build/build_config.h"
23 #include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
24 #include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h"
25 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
26 #include "sandbox/linux/services/linux_syscalls.h"
27
28 using sandbox::SyscallSets;
29 using sandbox::bpf_dsl::Allow;
30 using sandbox::bpf_dsl::Arg;
31 using sandbox::bpf_dsl::Error;
32 using sandbox::bpf_dsl::If;
33 using sandbox::bpf_dsl::ResultExpr;
34
35 namespace content {
36
37 namespace {
38
39 inline bool IsChromeOS() {
40 #if defined(OS_CHROMEOS)
41   return true;
42 #else
43   return false;
44 #endif
45 }
46
47 inline bool IsArchitectureArm() {
48 #if defined(__arm__)
49   return true;
50 #else
51   return false;
52 #endif
53 }
54
55 void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist,
56                             std::vector<std::string>* write_whitelist) {
57   // Device file needed by the ARM GPU userspace.
58   static const char kMali0Path[] = "/dev/mali0";
59
60   // Devices needed for video decode acceleration on ARM.
61   static const char kDevMfcDecPath[] = "/dev/mfc-dec";
62   static const char kDevGsc1Path[] = "/dev/gsc1";
63
64   // Devices needed for video encode acceleration on ARM.
65   static const char kDevMfcEncPath[] = "/dev/mfc-enc";
66
67   read_whitelist->push_back(kMali0Path);
68   read_whitelist->push_back(kDevMfcDecPath);
69   read_whitelist->push_back(kDevGsc1Path);
70   read_whitelist->push_back(kDevMfcEncPath);
71
72   write_whitelist->push_back(kMali0Path);
73   write_whitelist->push_back(kDevMfcDecPath);
74   write_whitelist->push_back(kDevGsc1Path);
75   write_whitelist->push_back(kDevMfcEncPath);
76 }
77
78 void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist,
79                         std::vector<std::string>* write_whitelist) {
80   // On ARM we're enabling the sandbox before the X connection is made,
81   // so we need to allow access to |.Xauthority|.
82   static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
83   static const char kLdSoCache[] = "/etc/ld.so.cache";
84
85   // Files needed by the ARM GPU userspace.
86   static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
87   static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";
88
89   read_whitelist->push_back(kXAuthorityPath);
90   read_whitelist->push_back(kLdSoCache);
91   read_whitelist->push_back(kLibGlesPath);
92   read_whitelist->push_back(kLibEglPath);
93
94   AddArmMaliGpuWhitelist(read_whitelist, write_whitelist);
95 }
96
97 class CrosArmGpuBrokerProcessPolicy : public CrosArmGpuProcessPolicy {
98  public:
99   static sandbox::bpf_dsl::SandboxBPFDSLPolicy* Create() {
100     return new CrosArmGpuBrokerProcessPolicy();
101   }
102   virtual ~CrosArmGpuBrokerProcessPolicy() {}
103
104   virtual ResultExpr EvaluateSyscall(int system_call_number) const OVERRIDE;
105
106  private:
107   CrosArmGpuBrokerProcessPolicy() : CrosArmGpuProcessPolicy(false) {}
108   DISALLOW_COPY_AND_ASSIGN(CrosArmGpuBrokerProcessPolicy);
109 };
110
111 // A GPU broker policy is the same as a GPU policy with open and
112 // openat allowed.
113 ResultExpr CrosArmGpuBrokerProcessPolicy::EvaluateSyscall(int sysno) const {
114   switch (sysno) {
115     case __NR_access:
116     case __NR_open:
117     case __NR_openat:
118       return Allow();
119     default:
120       return CrosArmGpuProcessPolicy::EvaluateSyscall(sysno);
121   }
122 }
123
124 }  // namespace
125
126 CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(bool allow_shmat)
127     : allow_shmat_(allow_shmat) {}
128
129 CrosArmGpuProcessPolicy::~CrosArmGpuProcessPolicy() {}
130
131 ResultExpr CrosArmGpuProcessPolicy::EvaluateSyscall(int sysno) const {
132 #if defined(__arm__)
133   if (allow_shmat_ && sysno == __NR_shmat)
134     return Allow();
135 #endif  // defined(__arm__)
136
137   switch (sysno) {
138 #if defined(__arm__)
139     // ARM GPU sandbox is started earlier so we need to allow networking
140     // in the sandbox.
141     case __NR_connect:
142     case __NR_getpeername:
143     case __NR_getsockname:
144     case __NR_sysinfo:
145     case __NR_uname:
146       return Allow();
147     // Allow only AF_UNIX for |domain|.
148     case __NR_socket:
149     case __NR_socketpair: {
150       const Arg<int> domain(0);
151       return If(domain == AF_UNIX, Allow()).Else(Error(EPERM));
152     }
153 #endif  // defined(__arm__)
154     default:
155       if (SyscallSets::IsAdvancedScheduler(sysno))
156         return Allow();
157
158       // Default to the generic GPU policy.
159       return GpuProcessPolicy::EvaluateSyscall(sysno);
160   }
161 }
162
163 bool CrosArmGpuProcessPolicy::PreSandboxHook() {
164   DCHECK(IsChromeOS() && IsArchitectureArm());
165   // Create a new broker process.
166   DCHECK(!broker_process());
167
168   std::vector<std::string> read_whitelist_extra;
169   std::vector<std::string> write_whitelist_extra;
170   // Add ARM-specific files to whitelist in the broker.
171
172   AddArmGpuWhitelist(&read_whitelist_extra, &write_whitelist_extra);
173   InitGpuBrokerProcess(CrosArmGpuBrokerProcessPolicy::Create,
174                        read_whitelist_extra,
175                        write_whitelist_extra);
176
177   const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;
178
179   // Preload the Mali library.
180   dlopen("/usr/lib/libmali.so", dlopen_flag);
181   // Preload the Tegra V4L2 (video decode acceleration) library.
182   dlopen("/usr/lib/libtegrav4l2.so", dlopen_flag);
183   // Resetting errno since platform-specific libraries will fail on other
184   // platforms.
185   errno = 0;
186
187   return true;
188 }
189
190 }  // namespace content