OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/common/sandbox_linux/android/sandbox_bpf_base_policy_android.h
" | 5 #include "content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.h
" |
6 | 6 |
| 7 #include <errno.h> |
| 8 #include <fcntl.h> |
| 9 #include <linux/net.h> |
| 10 #include <sys/socket.h> |
7 #include <sys/syscall.h> | 11 #include <sys/syscall.h> |
8 #include <sys/types.h> | 12 #include <sys/types.h> |
9 | 13 |
10 #include "build/build_config.h" | 14 #include "build/build_config.h" |
11 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" | 15 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" |
12 | 16 |
| 17 using sandbox::bpf_dsl::AllOf; |
13 using sandbox::bpf_dsl::Allow; | 18 using sandbox::bpf_dsl::Allow; |
| 19 using sandbox::bpf_dsl::AnyOf; |
| 20 using sandbox::bpf_dsl::Arg; |
| 21 using sandbox::bpf_dsl::BoolExpr; |
| 22 using sandbox::bpf_dsl::If; |
| 23 using sandbox::bpf_dsl::Error; |
14 using sandbox::bpf_dsl::ResultExpr; | 24 using sandbox::bpf_dsl::ResultExpr; |
15 | 25 |
16 namespace content { | 26 namespace content { |
17 | 27 |
| 28 #ifndef SOCK_CLOEXEC |
| 29 #define SOCK_CLOEXEC O_CLOEXEC |
| 30 #endif |
| 31 |
| 32 #ifndef SOCK_NONBLOCK |
| 33 #define SOCK_NONBLOCK O_NONBLOCK |
| 34 #endif |
| 35 |
| 36 namespace { |
| 37 |
| 38 // Restricts the arguments to sys_socket() to AF_UNIX. Returns a BoolExpr that |
| 39 // evaluates to true if the syscall should be allowed. |
| 40 BoolExpr RestrictSocketArguments(const Arg<int>& domain, |
| 41 const Arg<int>& type, |
| 42 const Arg<int>& protocol) { |
| 43 const int kSockFlags = SOCK_CLOEXEC | SOCK_NONBLOCK; |
| 44 return AllOf(domain == AF_UNIX, |
| 45 AnyOf((type & ~kSockFlags) == SOCK_DGRAM, |
| 46 (type & ~kSockFlags) == SOCK_STREAM), |
| 47 protocol == 0); |
| 48 } |
| 49 |
| 50 } // namespace |
| 51 |
18 SandboxBPFBasePolicyAndroid::SandboxBPFBasePolicyAndroid() | 52 SandboxBPFBasePolicyAndroid::SandboxBPFBasePolicyAndroid() |
19 : SandboxBPFBasePolicy() {} | 53 : SandboxBPFBasePolicy() {} |
20 | 54 |
21 SandboxBPFBasePolicyAndroid::~SandboxBPFBasePolicyAndroid() {} | 55 SandboxBPFBasePolicyAndroid::~SandboxBPFBasePolicyAndroid() {} |
22 | 56 |
23 ResultExpr SandboxBPFBasePolicyAndroid::EvaluateSyscall(int sysno) const { | 57 ResultExpr SandboxBPFBasePolicyAndroid::EvaluateSyscall(int sysno) const { |
24 bool override_and_allow = false; | 58 bool override_and_allow = false; |
25 | 59 |
26 switch (sysno) { | 60 switch (sysno) { |
27 // TODO(rsesek): restrict clone parameters. | 61 // TODO(rsesek): restrict clone parameters. |
28 case __NR_clone: | 62 case __NR_clone: |
29 case __NR_epoll_pwait: | 63 case __NR_epoll_pwait: |
30 case __NR_flock: | 64 case __NR_flock: |
31 #if defined(__x86_64__) || defined(__aarch64__) | 65 #if defined(__x86_64__) || defined(__aarch64__) |
32 case __NR_newfstatat: | 66 case __NR_newfstatat: |
| 67 case __NR_getdents64: |
33 #elif defined(__i386__) || defined(__arm__) || defined(__mips__) | 68 #elif defined(__i386__) || defined(__arm__) || defined(__mips__) |
34 case __NR_fstatat64: | 69 case __NR_fstatat64: |
| 70 case __NR_getdents: |
35 #endif | 71 #endif |
36 case __NR_getpriority: | 72 case __NR_getpriority: |
37 case __NR_ioctl: | 73 case __NR_ioctl: |
38 case __NR_mremap: | 74 case __NR_mremap: |
39 // File system access cannot be restricted with seccomp-bpf on Android, | 75 // File system access cannot be restricted with seccomp-bpf on Android, |
40 // since the JVM classloader and other Framework features require file | 76 // since the JVM classloader and other Framework features require file |
41 // access. It may be possible to restrict the filesystem with SELinux. | 77 // access. It may be possible to restrict the filesystem with SELinux. |
42 // Currently we rely on the app/service UID isolation to create a | 78 // Currently we rely on the app/service UID isolation to create a |
43 // filesystem "sandbox". | 79 // filesystem "sandbox". |
44 #if !defined(ARCH_CPU_ARM64) | 80 #if !defined(ARCH_CPU_ARM64) |
45 case __NR_open: | 81 case __NR_open: |
46 #endif | 82 #endif |
47 case __NR_openat: | 83 case __NR_openat: |
48 case __NR_pread64: | 84 case __NR_pread64: |
49 case __NR_rt_sigtimedwait: | 85 case __NR_rt_sigtimedwait: |
50 case __NR_setpriority: | 86 case __NR_setpriority: |
51 case __NR_set_tid_address: | 87 case __NR_set_tid_address: |
52 case __NR_sigaltstack: | 88 case __NR_sigaltstack: |
53 #if defined(__i386__) || defined(__arm__) | 89 #if defined(__i386__) || defined(__arm__) |
54 case __NR_ugetrlimit: | 90 case __NR_ugetrlimit: |
55 #else | 91 #else |
56 case __NR_getrlimit: | 92 case __NR_getrlimit: |
57 #endif | 93 #endif |
58 case __NR_uname: | 94 case __NR_uname: |
| 95 |
| 96 // Permit socket operations so that renderers can connect to logd and |
| 97 // debuggerd. The arguments to socket() are further restricted below. |
| 98 // Note that on i386, both of these calls map to __NR_socketcall, which |
| 99 // is demultiplexed below. |
| 100 #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || \ |
| 101 defined(__mips__) |
| 102 case __NR_socket: |
| 103 case __NR_connect: |
| 104 #endif |
| 105 |
| 106 // Ptrace is allowed so the Breakpad Microdumper can fork in a renderer |
| 107 // and then ptrace the parent. |
| 108 case __NR_ptrace: |
59 override_and_allow = true; | 109 override_and_allow = true; |
60 break; | 110 break; |
61 } | 111 } |
62 | 112 |
| 113 #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || \ |
| 114 defined(__mips__) |
| 115 if (sysno == __NR_socket) { |
| 116 const Arg<int> domain(0); |
| 117 const Arg<int> type(1); |
| 118 const Arg<int> protocol(2); |
| 119 return If(RestrictSocketArguments(domain, type, protocol), Allow()) |
| 120 .Else(Error(EPERM)); |
| 121 } |
| 122 #elif defined(__i386__) |
| 123 if (sysno == __NR_socketcall) { |
| 124 const Arg<int> socketcall(0); |
| 125 const Arg<int> domain(1); |
| 126 const Arg<int> type(2); |
| 127 const Arg<int> protocol(3); |
| 128 return If(socketcall == SYS_CONNECT, Allow()) |
| 129 .ElseIf(AllOf(socketcall == SYS_SOCKET, |
| 130 RestrictSocketArguments(domain, type, protocol)), |
| 131 Allow()) |
| 132 .Else(Error(EPERM)); |
| 133 } |
| 134 #endif |
| 135 |
63 if (override_and_allow) | 136 if (override_and_allow) |
64 return Allow(); | 137 return Allow(); |
65 | 138 |
66 return SandboxBPFBasePolicy::EvaluateSyscall(sysno); | 139 return SandboxBPFBasePolicy::EvaluateSyscall(sysno); |
67 } | 140 } |
68 | 141 |
69 } // namespace content | 142 } // namespace content |
OLD | NEW |