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