OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 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 "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" | 5 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <linux/futex.h> | 10 #include <linux/futex.h> |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 inline bool IsArchitectureMips() { | 72 inline bool IsArchitectureMips() { |
73 #if defined(__mips__) | 73 #if defined(__mips__) |
74 return true; | 74 return true; |
75 #else | 75 #else |
76 return false; | 76 return false; |
77 #endif | 77 #endif |
78 } | 78 } |
79 | 79 |
80 } // namespace. | 80 } // namespace. |
81 | 81 |
| 82 #define CASES SANDBOX_BPF_DSL_CASES |
| 83 |
82 using sandbox::bpf_dsl::Allow; | 84 using sandbox::bpf_dsl::Allow; |
83 using sandbox::bpf_dsl::Arg; | 85 using sandbox::bpf_dsl::Arg; |
84 using sandbox::bpf_dsl::BoolExpr; | 86 using sandbox::bpf_dsl::BoolExpr; |
85 using sandbox::bpf_dsl::Error; | 87 using sandbox::bpf_dsl::Error; |
86 using sandbox::bpf_dsl::If; | 88 using sandbox::bpf_dsl::If; |
87 using sandbox::bpf_dsl::ResultExpr; | 89 using sandbox::bpf_dsl::ResultExpr; |
88 | 90 |
89 // TODO(mdempsky): Make BoolExpr a standalone class so these operators can | 91 // TODO(mdempsky): Make BoolExpr a standalone class so these operators can |
90 // be resolved via argument-dependent lookup. | 92 // be resolved via argument-dependent lookup. |
91 using sandbox::bpf_dsl::operator||; | 93 using sandbox::bpf_dsl::operator||; |
(...skipping 24 matching lines...) Expand all Loading... |
116 | 118 |
117 return If(IsAndroid() ? android_test : glibc_test, Allow()) | 119 return If(IsAndroid() ? android_test : glibc_test, Allow()) |
118 .ElseIf((flags & (CLONE_VM | CLONE_THREAD)) == 0, Error(EPERM)) | 120 .ElseIf((flags & (CLONE_VM | CLONE_THREAD)) == 0, Error(EPERM)) |
119 .Else(CrashSIGSYSClone()); | 121 .Else(CrashSIGSYSClone()); |
120 } | 122 } |
121 | 123 |
122 ResultExpr RestrictPrctl() { | 124 ResultExpr RestrictPrctl() { |
123 // Will need to add seccomp compositing in the future. PR_SET_PTRACER is | 125 // Will need to add seccomp compositing in the future. PR_SET_PTRACER is |
124 // used by breakpad but not needed anymore. | 126 // used by breakpad but not needed anymore. |
125 const Arg<int> option(0); | 127 const Arg<int> option(0); |
126 return If(option == PR_GET_NAME || option == PR_SET_NAME || | 128 return Switch(option) |
127 option == PR_GET_DUMPABLE || option == PR_SET_DUMPABLE, | 129 .CASES((PR_GET_NAME, PR_SET_NAME, PR_GET_DUMPABLE, PR_SET_DUMPABLE), |
128 Allow()).Else(CrashSIGSYSPrctl()); | 130 Allow()) |
| 131 .Default(CrashSIGSYSPrctl()); |
129 } | 132 } |
130 | 133 |
131 ResultExpr RestrictIoctl() { | 134 ResultExpr RestrictIoctl() { |
132 const Arg<int> request(1); | 135 const Arg<int> request(1); |
133 return If(request == TCGETS || request == FIONREAD, Allow()) | 136 return Switch(request).CASES((TCGETS, FIONREAD), Allow()).Default( |
134 .Else(CrashSIGSYSIoctl()); | 137 CrashSIGSYSIoctl()); |
135 } | 138 } |
136 | 139 |
137 ResultExpr RestrictMmapFlags() { | 140 ResultExpr RestrictMmapFlags() { |
138 // The flags you see are actually the allowed ones, and the variable is a | 141 // The flags you see are actually the allowed ones, and the variable is a |
139 // "denied" mask because of the negation operator. | 142 // "denied" mask because of the negation operator. |
140 // Significantly, we don't permit MAP_HUGETLB, or the newer flags such as | 143 // Significantly, we don't permit MAP_HUGETLB, or the newer flags such as |
141 // MAP_POPULATE. | 144 // MAP_POPULATE. |
142 // TODO(davidung), remove MAP_DENYWRITE with updated Tegra libraries. | 145 // TODO(davidung), remove MAP_DENYWRITE with updated Tegra libraries. |
143 const uint32_t denied_mask = | 146 const uint32_t denied_mask = |
144 ~(MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK | MAP_NORESERVE | | 147 ~(MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK | MAP_NORESERVE | |
(...skipping 20 matching lines...) Expand all Loading... |
165 // Glibc overrides the kernel's O_LARGEFILE value. Account for this. | 168 // Glibc overrides the kernel's O_LARGEFILE value. Account for this. |
166 int kOLargeFileFlag = O_LARGEFILE; | 169 int kOLargeFileFlag = O_LARGEFILE; |
167 if (IsArchitectureX86_64() || IsArchitectureI386() || IsArchitectureMips()) | 170 if (IsArchitectureX86_64() || IsArchitectureI386() || IsArchitectureMips()) |
168 kOLargeFileFlag = 0100000; | 171 kOLargeFileFlag = 0100000; |
169 | 172 |
170 const Arg<int> cmd(1); | 173 const Arg<int> cmd(1); |
171 const Arg<long> long_arg(2); | 174 const Arg<long> long_arg(2); |
172 | 175 |
173 unsigned long denied_mask = ~(O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC | | 176 unsigned long denied_mask = ~(O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC | |
174 kOLargeFileFlag | O_CLOEXEC | O_NOATIME); | 177 kOLargeFileFlag | O_CLOEXEC | O_NOATIME); |
175 return If(cmd == F_GETFL || cmd == F_GETFD || cmd == F_SETFD || | 178 return Switch(cmd) |
176 cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK || | 179 .CASES((F_GETFL, |
177 cmd == F_DUPFD || cmd == F_DUPFD_CLOEXEC || | 180 F_GETFD, |
178 (cmd == F_SETFL && (long_arg & denied_mask) == 0), | 181 F_SETFD, |
179 Allow()).Else(CrashSIGSYS()); | 182 F_SETLK, |
| 183 F_SETLKW, |
| 184 F_GETLK, |
| 185 F_DUPFD, |
| 186 F_DUPFD_CLOEXEC), |
| 187 Allow()) |
| 188 .Case(F_SETFL, |
| 189 If((long_arg & denied_mask) == 0, Allow()).Else(CrashSIGSYS())) |
| 190 .Default(CrashSIGSYS()); |
180 } | 191 } |
181 | 192 |
182 #if defined(__i386__) || defined(__mips__) | 193 #if defined(__i386__) || defined(__mips__) |
183 ResultExpr RestrictSocketcallCommand() { | 194 ResultExpr RestrictSocketcallCommand() { |
184 // Unfortunately, we are unable to restrict the first parameter to | 195 // Unfortunately, we are unable to restrict the first parameter to |
185 // socketpair(2). Whilst initially sounding bad, it's noteworthy that very | 196 // socketpair(2). Whilst initially sounding bad, it's noteworthy that very |
186 // few protocols actually support socketpair(2). The scary call that we're | 197 // few protocols actually support socketpair(2). The scary call that we're |
187 // worried about, socket(2), remains blocked. | 198 // worried about, socket(2), remains blocked. |
188 const Arg<int> call(0); | 199 const Arg<int> call(0); |
189 return If(call == SYS_SOCKETPAIR || call == SYS_SHUTDOWN || | 200 return Switch(call) |
190 call == SYS_RECV || call == SYS_SEND || | 201 .CASES((SYS_SOCKETPAIR, |
191 call == SYS_RECVFROM || call == SYS_SENDTO || | 202 SYS_SHUTDOWN, |
192 call == SYS_RECVMSG || call == SYS_SENDMSG, | 203 SYS_RECV, |
193 Allow()).Else(Error(EPERM)); | 204 SYS_SEND, |
| 205 SYS_RECVFROM, |
| 206 SYS_SENDTO, |
| 207 SYS_RECVMSG, |
| 208 SYS_SENDMSG), |
| 209 Allow()) |
| 210 .Default(Error(EPERM)); |
194 } | 211 } |
195 #endif | 212 #endif |
196 | 213 |
197 ResultExpr RestrictKillTarget(pid_t target_pid, int sysno) { | 214 ResultExpr RestrictKillTarget(pid_t target_pid, int sysno) { |
198 switch (sysno) { | 215 switch (sysno) { |
199 case __NR_kill: | 216 case __NR_kill: |
200 case __NR_tgkill: { | 217 case __NR_tgkill: { |
201 const Arg<pid_t> pid(0); | 218 const Arg<pid_t> pid(0); |
202 return If(pid == target_pid, Allow()).Else(CrashSIGSYSKill()); | 219 return If(pid == target_pid, Allow()).Else(CrashSIGSYSKill()); |
203 } | 220 } |
204 case __NR_tkill: | 221 case __NR_tkill: |
205 return CrashSIGSYSKill(); | 222 return CrashSIGSYSKill(); |
206 default: | 223 default: |
207 NOTREACHED(); | 224 NOTREACHED(); |
208 return CrashSIGSYS(); | 225 return CrashSIGSYS(); |
209 } | 226 } |
210 } | 227 } |
211 | 228 |
212 ResultExpr RestrictFutex() { | 229 ResultExpr RestrictFutex() { |
213 const int kAllowedFutexFlags = FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME; | 230 const int kAllowedFutexFlags = FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME; |
214 const int kOperationMask = ~kAllowedFutexFlags; | 231 const int kOperationMask = ~kAllowedFutexFlags; |
215 const int kAllowedFutexOperations[] = { | |
216 FUTEX_WAIT, FUTEX_WAKE, FUTEX_FD, FUTEX_REQUEUE, | |
217 FUTEX_CMP_REQUEUE, FUTEX_WAKE_OP, FUTEX_WAIT_BITSET, FUTEX_WAKE_BITSET}; | |
218 | 232 |
219 const Arg<int> op(1); | 233 const Arg<int> op(1); |
220 | 234 return Switch(op & kOperationMask) |
221 BoolExpr IsAllowedOp = (op & kOperationMask) == kAllowedFutexOperations[0]; | 235 .CASES((FUTEX_WAIT, |
222 for (size_t i = 1; i < arraysize(kAllowedFutexOperations); ++i) { | 236 FUTEX_WAKE, |
223 IsAllowedOp = | 237 FUTEX_FD, |
224 IsAllowedOp || ((op & kOperationMask) == kAllowedFutexOperations[i]); | 238 FUTEX_REQUEUE, |
225 } | 239 FUTEX_CMP_REQUEUE, |
226 return If(IsAllowedOp, Allow()).Else(CrashSIGSYSFutex()); | 240 FUTEX_WAKE_OP, |
| 241 FUTEX_WAIT_BITSET, |
| 242 FUTEX_WAKE_BITSET), |
| 243 Allow()) |
| 244 .Default(CrashSIGSYSFutex()); |
227 } | 245 } |
228 | 246 |
229 } // namespace sandbox. | 247 } // namespace sandbox. |
OLD | NEW |