Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(933)

Side by Side Diff: sandbox/linux/seccomp-bpf/sandbox_bpf.cc

Issue 10542028: Explicitly test bit 30 in the system call number to distinguish between the new x32 API and older I… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Switched return codes to kill on error Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "sandbox/linux/seccomp-bpf/sandbox_bpf.h" 5 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
6 6
7 // The kernel gives us a sandbox, we turn it into a playground :-) 7 // The kernel gives us a sandbox, we turn it into a playground :-)
8 // This is version 2 of the playground; version 1 was built on top of 8 // This is version 2 of the playground; version 1 was built on top of
9 // pre-BPF seccomp mode. 9 // pre-BPF seccomp mode.
10 namespace playground2 { 10 namespace playground2 {
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 // We can't handle stacked evaluators, yet. We'll get there eventually 208 // We can't handle stacked evaluators, yet. We'll get there eventually
209 // though. Hang tight. 209 // though. Hang tight.
210 if (evaluators_.size() != 1) { 210 if (evaluators_.size() != 1) {
211 die("Not implemented"); 211 die("Not implemented");
212 } 212 }
213 213
214 // If the architecture doesn't match SECCOMP_ARCH, disallow the 214 // If the architecture doesn't match SECCOMP_ARCH, disallow the
215 // system call. 215 // system call.
216 std::vector<struct sock_filter> program; 216 std::vector<struct sock_filter> program;
217 program.push_back((struct sock_filter) 217 program.push_back((struct sock_filter)
218 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 218 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct arch_seccomp_data, arch)));
219 offsetof(struct arch_seccomp_data, arch)));
220 program.push_back((struct sock_filter) 219 program.push_back((struct sock_filter)
221 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_ARCH, 1, 0)); 220 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_ARCH, 1, 0));
221
222 // TODO: Instead of killing outright, we should raise a SIGSYS and
223 // report a useful error message. SIGKILL cannot be trapped by the
224 // debugger and essentially makes the program fail in a way that is
225 // almost impossible to debug.
222 program.push_back((struct sock_filter) 226 program.push_back((struct sock_filter)
223 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO + SECCOMP_DENY_ERRNO)); 227 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL));
224 228
225 // Grab the system call number, so that we can implement jump tables. 229 // Grab the system call number, so that we can implement jump tables.
226 program.push_back((struct sock_filter) 230 program.push_back((struct sock_filter)
227 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct arch_seccomp_data, nr))); 231 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct arch_seccomp_data, nr)));
228 232
233 // On Intel architectures, verify that system call numbers are in the
234 // expected number range. The older i386 and x86-64 APIs clear bit 30
235 // on all system calls. The newer x86-32 API always sets bit 30.
236 #if defined(__i386__) || defined(__x86_64__)
Chris Evans 2012/06/07 23:01:36 I'd be tempted to remove this outer conditional. I
237 #if defined(__x86_64__) && defined(__ILP32__)
238 program.push_back((struct sock_filter)
239 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x40000000, 1, 0));
240 #else
241 program.push_back((struct sock_filter)
242 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x40000000, 0, 1));
243 #endif
244 // TODO: raise a suitable SIGSYS signal
245 program.push_back((struct sock_filter)
246 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL));
247 #endif
248
229 // Evaluate all possible system calls and depending on their 249 // Evaluate all possible system calls and depending on their
230 // exit codes generate a BPF filter. 250 // exit codes generate a BPF filter.
231 // This is very inefficient right now. We need to be much smarter 251 // This is very inefficient right now. We need to be much smarter
232 // eventually. 252 // eventually.
233 // We currently incur a O(N) overhead on each system call, with N 253 // We currently incur a O(N) overhead on each system call, with N
234 // being the number of system calls. It is easy to get this down to 254 // being the number of system calls. It is easy to get this down to
235 // O(log_2(M)) with M being the number of system calls that need special 255 // O(log_2(M)) with M being the number of system calls that need special
236 // treatment. 256 // treatment.
237 EvaluateSyscall evaluateSyscall = evaluators_.begin()->first; 257 EvaluateSyscall evaluateSyscall = evaluators_.begin()->first;
238 for (int sysnum = MIN_SYSCALL; sysnum <= MAX_SYSCALL; ++sysnum) { 258 for (int sysnum = MIN_SYSCALL; sysnum <= MAX_SYSCALL; ++sysnum) {
(...skipping 20 matching lines...) Expand all
259 break; 279 break;
260 } 280 }
261 program.push_back((struct sock_filter) 281 program.push_back((struct sock_filter)
262 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, sysnum, 0, 1)); 282 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, sysnum, 0, 1));
263 program.push_back((struct sock_filter) 283 program.push_back((struct sock_filter)
264 BPF_STMT(BPF_RET+BPF_K, ret)); 284 BPF_STMT(BPF_RET+BPF_K, ret));
265 } 285 }
266 286
267 // Everything that isn't allowed is forbidden. Eventually, we would 287 // Everything that isn't allowed is forbidden. Eventually, we would
268 // like to have a way to log forbidden calls, when in debug mode. 288 // like to have a way to log forbidden calls, when in debug mode.
289 // TODO: raise a suitable SIGSYS signal
269 program.push_back((struct sock_filter) 290 program.push_back((struct sock_filter)
270 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO + SECCOMP_DENY_ERRNO)); 291 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL));
271 292
272 // Install BPF filter program 293 // Install BPF filter program
273 const struct sock_fprog prog = { program.size(), &program[0] }; 294 const struct sock_fprog prog = { program.size(), &program[0] };
274 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) || 295 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) ||
275 prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { 296 prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
276 goto filter_failed; 297 goto filter_failed;
277 } 298 }
278 299
279 return; 300 return;
280 } 301 }
(...skipping 29 matching lines...) Expand all
310 } 331 }
311 332
312 333
313 bool Sandbox::suppressLogging_ = false; 334 bool Sandbox::suppressLogging_ = false;
314 Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN; 335 Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN;
315 int Sandbox::proc_fd_ = -1; 336 int Sandbox::proc_fd_ = -1;
316 std::vector<std::pair<Sandbox::EvaluateSyscall, 337 std::vector<std::pair<Sandbox::EvaluateSyscall,
317 Sandbox::EvaluateArguments> > Sandbox::evaluators_; 338 Sandbox::EvaluateArguments> > Sandbox::evaluators_;
318 339
319 } // namespace 340 } // namespace
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698