Upstream version 5.34.104.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/compiler_specific.h"
19 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "build/build_config.h"
22 #include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
23 #include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h"
24 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
25 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
26 #include "sandbox/linux/services/linux_syscalls.h"
27
28 using sandbox::ErrorCode;
29 using sandbox::SandboxBPF;
30 using sandbox::SyscallSets;
31
32 namespace content {
33
34 namespace {
35
36 inline bool IsChromeOS() {
37 #if defined(OS_CHROMEOS)
38   return true;
39 #else
40   return false;
41 #endif
42 }
43
44 inline bool IsArchitectureArm() {
45 #if defined(__arm__)
46   return true;
47 #else
48   return false;
49 #endif
50 }
51
52 void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist,
53                             std::vector<std::string>* write_whitelist) {
54   // Device file needed by the ARM GPU userspace.
55   static const char kMali0Path[] = "/dev/mali0";
56
57   // Devices needed for video decode acceleration on ARM.
58   static const char kDevMfcDecPath[] = "/dev/mfc-dec";
59   static const char kDevGsc1Path[] = "/dev/gsc1";
60
61   // Devices needed for video encode acceleration on ARM.
62   static const char kDevMfcEncPath[] = "/dev/mfc-enc";
63
64   read_whitelist->push_back(kMali0Path);
65   read_whitelist->push_back(kDevMfcDecPath);
66   read_whitelist->push_back(kDevGsc1Path);
67   read_whitelist->push_back(kDevMfcEncPath);
68
69   write_whitelist->push_back(kMali0Path);
70   write_whitelist->push_back(kDevMfcDecPath);
71   write_whitelist->push_back(kDevGsc1Path);
72   write_whitelist->push_back(kDevMfcEncPath);
73 }
74
75 void AddArmTegraGpuWhitelist(std::vector<std::string>* read_whitelist,
76                              std::vector<std::string>* write_whitelist) {
77   // Device files needed by the Tegra GPU userspace.
78   static const char kDevNvhostCtrlPath[] = "/dev/nvhost-ctrl";
79   static const char kDevNvhostIspPath[] = "/dev/nvhost-isp";
80   static const char kDevNvhostViPath[] = "/dev/nvhost-vi";
81   static const char kDevNvmapPath[] = "/dev/nvmap";
82   static const char kDevNvhostGpuPath[] = "/dev/nvhost-gpu";
83   static const char kDevNvhostAsGpuPath[] = "/dev/nvhost-as-gpu";
84   static const char kDevNvhostCtrlGpuPath[] = "/dev/nvhost-ctrl-gpu";
85   static const char kSysDevicesSocIDPath[] = "/sys/devices/soc0/soc_id";
86   static const char kSysDevicesSocRevPath[] = "/sys/devices/soc0/revision";
87   // TODO(davidung): remove these device nodes before nyan launch.
88
89   read_whitelist->push_back(kDevNvhostCtrlPath);
90   read_whitelist->push_back(kDevNvhostIspPath);
91   read_whitelist->push_back(kDevNvhostViPath);
92   read_whitelist->push_back(kDevNvmapPath);
93   read_whitelist->push_back(kDevNvhostGpuPath);
94   read_whitelist->push_back(kDevNvhostAsGpuPath);
95   read_whitelist->push_back(kDevNvhostCtrlGpuPath);
96   read_whitelist->push_back(kSysDevicesSocIDPath);
97   read_whitelist->push_back(kSysDevicesSocRevPath);
98
99   write_whitelist->push_back(kDevNvhostCtrlPath);
100   write_whitelist->push_back(kDevNvhostIspPath);
101   write_whitelist->push_back(kDevNvhostViPath);
102   write_whitelist->push_back(kDevNvmapPath);
103   write_whitelist->push_back(kDevNvhostGpuPath);
104   write_whitelist->push_back(kDevNvhostAsGpuPath);
105   write_whitelist->push_back(kDevNvhostCtrlGpuPath);
106 }
107
108 void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist,
109                         std::vector<std::string>* write_whitelist) {
110   // On ARM we're enabling the sandbox before the X connection is made,
111   // so we need to allow access to |.Xauthority|.
112   static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
113   static const char kLdSoCache[] = "/etc/ld.so.cache";
114
115   // Files needed by the ARM GPU userspace.
116   static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
117   static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";
118
119   read_whitelist->push_back(kXAuthorityPath);
120   read_whitelist->push_back(kLdSoCache);
121   read_whitelist->push_back(kLibGlesPath);
122   read_whitelist->push_back(kLibEglPath);
123
124   AddArmMaliGpuWhitelist(read_whitelist, write_whitelist);
125   AddArmTegraGpuWhitelist(read_whitelist, write_whitelist);
126 }
127
128 class CrosArmGpuBrokerProcessPolicy : public CrosArmGpuProcessPolicy {
129  public:
130   CrosArmGpuBrokerProcessPolicy() : CrosArmGpuProcessPolicy(false) {}
131   virtual ~CrosArmGpuBrokerProcessPolicy() {}
132
133   virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
134                                     int system_call_number) const OVERRIDE;
135
136  private:
137   DISALLOW_COPY_AND_ASSIGN(CrosArmGpuBrokerProcessPolicy);
138 };
139
140 // A GPU broker policy is the same as a GPU policy with open and
141 // openat allowed.
142 ErrorCode CrosArmGpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
143     int sysno) const {
144   switch (sysno) {
145     case __NR_access:
146     case __NR_open:
147     case __NR_openat:
148       return ErrorCode(ErrorCode::ERR_ALLOWED);
149     default:
150       return CrosArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno);
151   }
152 }
153
154 bool EnableArmGpuBrokerPolicyCallback() {
155   return SandboxSeccompBPF::StartSandboxWithExternalPolicy(
156       scoped_ptr<sandbox::SandboxBPFPolicy>(new CrosArmGpuBrokerProcessPolicy));
157 }
158
159 }  // namespace
160
161 CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(bool allow_shmat)
162     : allow_shmat_(allow_shmat) {}
163
164 CrosArmGpuProcessPolicy::~CrosArmGpuProcessPolicy() {}
165
166 ErrorCode CrosArmGpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
167                                                    int sysno) const {
168 #if defined(__arm__)
169   if (allow_shmat_ && sysno == __NR_shmat)
170     return ErrorCode(ErrorCode::ERR_ALLOWED);
171 #endif  // defined(__arm__)
172
173   switch (sysno) {
174 #if defined(__arm__)
175     // ARM GPU sandbox is started earlier so we need to allow networking
176     // in the sandbox.
177     case __NR_connect:
178     case __NR_getpeername:
179     case __NR_getsockname:
180     case __NR_sysinfo:
181     case __NR_uname:
182       return ErrorCode(ErrorCode::ERR_ALLOWED);
183     // Allow only AF_UNIX for |domain|.
184     case __NR_socket:
185     case __NR_socketpair:
186       return sandbox->Cond(0, ErrorCode::TP_32BIT,
187                            ErrorCode::OP_EQUAL, AF_UNIX,
188                            ErrorCode(ErrorCode::ERR_ALLOWED),
189                            ErrorCode(EPERM));
190 #endif  // defined(__arm__)
191     default:
192       if (SyscallSets::IsAdvancedScheduler(sysno))
193         return ErrorCode(ErrorCode::ERR_ALLOWED);
194
195       // Default to the generic GPU policy.
196       return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno);
197   }
198 }
199
200 bool CrosArmGpuProcessPolicy::PreSandboxHook() {
201   DCHECK(IsChromeOS() && IsArchitectureArm());
202   // Create a new broker process.
203   DCHECK(!broker_process());
204
205   std::vector<std::string> read_whitelist_extra;
206   std::vector<std::string> write_whitelist_extra;
207   // Add ARM-specific files to whitelist in the broker.
208
209   AddArmGpuWhitelist(&read_whitelist_extra, &write_whitelist_extra);
210   InitGpuBrokerProcess(EnableArmGpuBrokerPolicyCallback,
211                        read_whitelist_extra,
212                        write_whitelist_extra);
213
214   const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;
215
216   // Preload the Mali library.
217   dlopen("/usr/lib/libmali.so", dlopen_flag);
218
219   // Preload the Tegra libraries.
220   dlopen("/usr/lib/libnvrm.so", dlopen_flag);
221   dlopen("/usr/lib/libnvrm_graphics.so", dlopen_flag);
222   dlopen("/usr/lib/libnvidia-glsi.so", dlopen_flag);
223   dlopen("/usr/lib/libnvidia-rmapi-tegra.so", dlopen_flag);
224   dlopen("/usr/lib/libnvidia-eglcore.so", dlopen_flag);
225   // TODO(davidung): remove these libraries before nyan launch.
226
227   return true;
228 }
229
230 }  // namespace content