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