| Index: sandbox/linux/seccomp-bpf/sandbox_bpf.cc
|
| diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
|
| index 773a47141252d173ff09240b4dd9489f331b51cc..c2f422ed3eb32523abb0e79c7e544499f5545c40 100644
|
| --- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
|
| +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
|
| @@ -3,6 +3,7 @@
|
| // found in the LICENSE file.
|
|
|
| #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
|
| +#include "sandbox/linux/seccomp-bpf/verifier.h"
|
|
|
| // The kernel gives us a sandbox, we turn it into a playground :-)
|
| // This is version 2 of the playground; version 1 was built on top of
|
| @@ -255,7 +256,7 @@ void Sandbox::installFilter() {
|
| // O(log_2(M)) with M being the number of system calls that need special
|
| // treatment.
|
| EvaluateSyscall evaluateSyscall = evaluators_.begin()->first;
|
| - for (int sysnum = MIN_SYSCALL; sysnum <= MAX_SYSCALL; ++sysnum) {
|
| + for (uint32_t sysnum = MIN_SYSCALL; sysnum <= MAX_SYSCALL+1; ++sysnum) {
|
| ErrorCode err = evaluateSyscall(sysnum);
|
| int ret;
|
| switch (err) {
|
| @@ -278,17 +279,28 @@ void Sandbox::installFilter() {
|
| }
|
| break;
|
| }
|
| - program.push_back((struct sock_filter)
|
| - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, sysnum, 0, 1));
|
| + if (sysnum <= MAX_SYSCALL) {
|
| + // We compute the default behavior (e.g. fail open or fail closed) by
|
| + // calling the system call evaluator with a system call bigger than
|
| + // MAX_SYSCALL.
|
| + // In other words, the very last iteration in our loop becomes the
|
| + // fallback case and we don't need to do any comparisons.
|
| + program.push_back((struct sock_filter)
|
| + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, sysnum, 0, 1));
|
| + }
|
| program.push_back((struct sock_filter)
|
| BPF_STMT(BPF_RET+BPF_K, ret));
|
| }
|
|
|
| - // Everything that isn't allowed is forbidden. Eventually, we would
|
| - // like to have a way to log forbidden calls, when in debug mode.
|
| - // TODO: raise a suitable SIGSYS signal
|
| - program.push_back((struct sock_filter)
|
| - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL));
|
| + // Make sure compilation resulted in BPF program that executes
|
| + // correctly. Otherwise, there is an internal error in our BPF compiler.
|
| + // There is really nothing the caller can do until the bug is fixed.
|
| +#ifndef NDEBUG
|
| + const char *err = NULL;
|
| + if (!Verifier::verifyBPF(program, evaluators_, &err)) {
|
| + die(err);
|
| + }
|
| +#endif
|
|
|
| // Install BPF filter program
|
| const struct sock_fprog prog = { program.size(), &program[0] };
|
| @@ -334,7 +346,6 @@ void Sandbox::sigSys(int nr, siginfo_t *info, void *void_context) {
|
| bool Sandbox::suppressLogging_ = false;
|
| Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN;
|
| int Sandbox::proc_fd_ = -1;
|
| -std::vector<std::pair<Sandbox::EvaluateSyscall,
|
| - Sandbox::EvaluateArguments> > Sandbox::evaluators_;
|
| +Sandbox::Evaluators Sandbox::evaluators_;
|
|
|
| } // namespace
|
|
|