OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/public/common/sandbox_init.h" | 5 #include "content/public/common/sandbox_init.h" |
6 | 6 |
7 #if defined(OS_LINUX) && defined(__x86_64__) | 7 #if defined(OS_LINUX) && defined(__x86_64__) |
8 | 8 |
9 #include <asm/unistd.h> | 9 #include <asm/unistd.h> |
10 #include <errno.h> | 10 #include <errno.h> |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 EmitAllowSyscall(__NR_dup, program); | 187 EmitAllowSyscall(__NR_dup, program); |
188 EmitAllowSyscall(__NR_mlock, program); | 188 EmitAllowSyscall(__NR_mlock, program); |
189 EmitAllowSyscall(__NR_munlock, program); | 189 EmitAllowSyscall(__NR_munlock, program); |
190 EmitAllowSyscall(__NR_exit, program); | 190 EmitAllowSyscall(__NR_exit, program); |
191 EmitAllowSyscall(__NR_exit_group, program); | 191 EmitAllowSyscall(__NR_exit_group, program); |
192 | 192 |
193 EmitFailSyscall(__NR_open, ENOENT, program); | 193 EmitFailSyscall(__NR_open, ENOENT, program); |
194 EmitFailSyscall(__NR_access, ENOENT, program); | 194 EmitFailSyscall(__NR_access, ENOENT, program); |
195 } | 195 } |
196 | 196 |
| 197 static void ApplyFlashPolicy(std::vector<struct sock_filter>* program) { |
| 198 // "Hot" syscalls go first. |
| 199 EmitAllowSyscall(__NR_futex, program); |
| 200 EmitAllowSyscall(__NR_write, program); |
| 201 EmitAllowSyscall(__NR_epoll_wait, program); |
| 202 EmitAllowSyscall(__NR_read, program); |
| 203 EmitAllowSyscall(__NR_times, program); |
| 204 |
| 205 // Less hot syscalls. |
| 206 EmitAllowSyscall(__NR_clone, program); |
| 207 EmitAllowSyscall(__NR_set_robust_list, program); |
| 208 EmitAllowSyscall(__NR_getuid, program); |
| 209 EmitAllowSyscall(__NR_geteuid, program); |
| 210 EmitAllowSyscall(__NR_getgid, program); |
| 211 EmitAllowSyscall(__NR_getegid, program); |
| 212 EmitAllowSyscall(__NR_epoll_create, program); |
| 213 EmitAllowSyscall(__NR_fcntl, program); |
| 214 EmitAllowSyscall(__NR_socketpair, program); |
| 215 EmitAllowSyscall(__NR_pipe, program); |
| 216 EmitAllowSyscall(__NR_epoll_ctl, program); |
| 217 EmitAllowSyscall(__NR_gettid, program); |
| 218 EmitAllowSyscall(__NR_prctl, program); |
| 219 EmitAllowSyscall(__NR_fstat, program); |
| 220 EmitAllowSyscall(__NR_sendmsg, program); |
| 221 EmitAllowSyscall(__NR_mmap, program); |
| 222 EmitAllowSyscall(__NR_munmap, program); |
| 223 EmitAllowSyscall(__NR_mprotect, program); |
| 224 EmitAllowSyscall(__NR_madvise, program); |
| 225 EmitAllowSyscall(__NR_rt_sigaction, program); |
| 226 EmitAllowSyscall(__NR_rt_sigprocmask, program); |
| 227 EmitAllowSyscall(__NR_wait4, program); |
| 228 EmitAllowSyscall(__NR_exit_group, program); |
| 229 EmitAllowSyscall(__NR_exit, program); |
| 230 EmitAllowSyscall(__NR_rt_sigreturn, program); |
| 231 EmitAllowSyscall(__NR_restart_syscall, program); |
| 232 EmitAllowSyscall(__NR_close, program); |
| 233 EmitAllowSyscall(__NR_recvmsg, program); |
| 234 EmitAllowSyscall(__NR_lseek, program); |
| 235 EmitAllowSyscall(__NR_brk, program); |
| 236 EmitAllowSyscall(__NR_sched_yield, program); |
| 237 |
| 238 // These are under investigation, and hopefully not here for the long term. |
| 239 EmitAllowSyscall(__NR_shmctl, program); |
| 240 EmitAllowSyscall(__NR_shmat, program); |
| 241 EmitAllowSyscall(__NR_shmdt, program); |
| 242 |
| 243 EmitFailSyscall(__NR_open, ENOENT, program); |
| 244 EmitFailSyscall(__NR_execve, ENOENT, program); |
| 245 EmitFailSyscall(__NR_access, ENOENT, program); |
| 246 } |
| 247 |
197 static bool CanUseSeccompFilters() { | 248 static bool CanUseSeccompFilters() { |
198 int ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, 0, 0, 0); | 249 int ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, 0, 0, 0); |
199 if (ret != 0 && errno == EFAULT) | 250 if (ret != 0 && errno == EFAULT) |
200 return true; | 251 return true; |
201 return false; | 252 return false; |
202 } | 253 } |
203 | 254 |
204 static void InstallFilter(const std::vector<struct sock_filter>& program) { | 255 static void InstallFilter(const std::vector<struct sock_filter>& program) { |
205 int ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | 256 int ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); |
206 PLOG_IF(FATAL, ret != 0) << "prctl(PR_SET_NO_NEW_PRIVS) failed"; | 257 PLOG_IF(FATAL, ret != 0) << "prctl(PR_SET_NO_NEW_PRIVS) failed"; |
207 | 258 |
208 struct sock_fprog fprog; | 259 struct sock_fprog fprog; |
209 fprog.len = program.size(); | 260 fprog.len = program.size(); |
210 fprog.filter = const_cast<struct sock_filter*>(&program[0]); | 261 fprog.filter = const_cast<struct sock_filter*>(&program[0]); |
211 | 262 |
212 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fprog, 0, 0); | 263 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fprog, 0, 0); |
213 PLOG_IF(FATAL, ret != 0) << "Failed to install filter."; | 264 PLOG_IF(FATAL, ret != 0) << "Failed to install filter."; |
214 } | 265 } |
215 | 266 |
216 } // anonymous namespace | 267 } // anonymous namespace |
217 | 268 |
218 namespace content { | 269 namespace content { |
219 | 270 |
220 void InitializeSandbox() { | 271 void InitializeSandbox() { |
221 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 272 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
222 if (command_line.HasSwitch(switches::kNoSandbox)) | 273 if (command_line.HasSwitch(switches::kNoSandbox) || |
| 274 command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) |
223 return; | 275 return; |
224 | 276 |
225 std::string process_type = | 277 std::string process_type = |
226 command_line.GetSwitchValueASCII(switches::kProcessType); | 278 command_line.GetSwitchValueASCII(switches::kProcessType); |
227 if (process_type == switches::kGpuProcess && | 279 if (process_type == switches::kGpuProcess && |
228 command_line.HasSwitch(switches::kDisableGpuSandbox)) | 280 command_line.HasSwitch(switches::kDisableGpuSandbox)) |
229 return; | 281 return; |
230 | 282 |
231 if (!CanUseSeccompFilters()) | 283 if (!CanUseSeccompFilters()) |
232 return; | 284 return; |
233 | 285 |
234 CheckSingleThreaded(); | 286 CheckSingleThreaded(); |
235 | 287 |
236 std::vector<struct sock_filter> program; | 288 std::vector<struct sock_filter> program; |
237 EmitPreamble(&program); | 289 EmitPreamble(&program); |
238 | 290 |
239 if (process_type == switches::kGpuProcess) { | 291 if (process_type == switches::kGpuProcess) { |
240 ApplyGPUPolicy(&program); | 292 ApplyGPUPolicy(&program); |
| 293 } else if (process_type == switches::kPpapiPluginProcess) { |
| 294 ApplyFlashPolicy(&program); |
241 } else { | 295 } else { |
242 NOTREACHED(); | 296 NOTREACHED(); |
243 } | 297 } |
244 | 298 |
245 EmitTrap(&program); | 299 EmitTrap(&program); |
246 | 300 |
247 InstallSIGSYSHandler(); | 301 InstallSIGSYSHandler(); |
248 InstallFilter(program); | 302 InstallFilter(program); |
249 } | 303 } |
250 | 304 |
251 } // namespace content | 305 } // namespace content |
252 | 306 |
253 #else | 307 #else |
254 | 308 |
255 namespace content { | 309 namespace content { |
256 | 310 |
257 void InitializeSandbox() { | 311 void InitializeSandbox() { |
258 } | 312 } |
259 | 313 |
260 } // namespace content | 314 } // namespace content |
261 | 315 |
262 #endif | 316 #endif |
263 | 317 |
OLD | NEW |