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

Unified Diff: sandbox/linux/seccomp-bpf/sandbox_bpf.cc

Issue 12223109: SECCOMP-BPF: Refactor the BPF sandbox API to use fewer "static" fields and methods. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make sure unnamed namespaces are always top-level Created 7 years, 10 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 side-by-side diff with in-line comments
Download patch
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 cb688deae2d67e78c6913d8a9a483b70b6bb2f83..1dc5eae04280aaccc03022606f191e77016eaa6c 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -8,8 +8,15 @@
#include <sys/cdefs.h>
#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
#include <sys/prctl.h>
+#include <sys/stat.h>
#include <sys/syscall.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
#ifndef SECCOMP_BPF_STANDALONE
#include "base/logging.h"
@@ -24,16 +31,13 @@
namespace {
-void WriteFailedStderrSetupMessage(int out_fd) {
- const char* error_string = strerror(errno);
- static const char msg[] = "You have reproduced a puzzling issue.\n"
- "Please, report to crbug.com/152530!\n"
- "Failed to set up stderr: ";
- if (HANDLE_EINTR(write(out_fd, msg, sizeof(msg)-1)) > 0 && error_string &&
- HANDLE_EINTR(write(out_fd, error_string, strlen(error_string))) > 0 &&
- HANDLE_EINTR(write(out_fd, "\n", 1))) {
- }
-}
+using playground2::ErrorCode;
+using playground2::Instruction;
+using playground2::Sandbox;
+using playground2::Trap;
+using playground2::arch_seccomp_data;
+
+const int kExpectedExitCode = 100;
template<class T> int popcount(T x);
template<> int popcount<unsigned int>(unsigned int x) {
@@ -46,18 +50,21 @@ template<> int popcount<unsigned long long>(unsigned long long x) {
return __builtin_popcountll(x);
}
-} // namespace
-
-// 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
-// pre-BPF seccomp mode.
-namespace playground2 {
-
-const int kExpectedExitCode = 100;
+void WriteFailedStderrSetupMessage(int out_fd) {
+ const char* error_string = strerror(errno);
+ static const char msg[] = "You have reproduced a puzzling issue.\n"
+ "Please, report to crbug.com/152530!\n"
+ "Failed to set up stderr: ";
+ if (HANDLE_EINTR(write(out_fd, msg, sizeof(msg)-1)) > 0 && error_string &&
+ HANDLE_EINTR(write(out_fd, error_string, strlen(error_string))) > 0 &&
+ HANDLE_EINTR(write(out_fd, "\n", 1))) {
+ }
+}
// We define a really simple sandbox policy. It is just good enough for us
// to tell that the sandbox has actually been activated.
-ErrorCode Sandbox::ProbeEvaluator(int sysnum, void *) {
+ErrorCode ProbeEvaluator(Sandbox *, int sysnum, void *) __attribute__((const));
+ErrorCode ProbeEvaluator(Sandbox *, int sysnum, void *) {
switch (sysnum) {
case __NR_getpid:
// Return EPERM so that we can check that the filter actually ran.
@@ -71,24 +78,20 @@ ErrorCode Sandbox::ProbeEvaluator(int sysnum, void *) {
}
}
-void Sandbox::ProbeProcess(void) {
+void ProbeProcess(void) {
if (syscall(__NR_getpid) < 0 && errno == EPERM) {
syscall(__NR_exit_group, static_cast<intptr_t>(kExpectedExitCode));
}
}
-bool Sandbox::IsValidSyscallNumber(int sysnum) {
- return SyscallIterator::IsValid(sysnum);
-}
-
-ErrorCode Sandbox::AllowAllEvaluator(int sysnum, void *) {
- if (!IsValidSyscallNumber(sysnum)) {
+ErrorCode AllowAllEvaluator(Sandbox *, int sysnum, void *) {
+ if (!Sandbox::IsValidSyscallNumber(sysnum)) {
return ErrorCode(ENOSYS);
}
return ErrorCode(ErrorCode::ERR_ALLOWED);
}
-void Sandbox::TryVsyscallProcess(void) {
+void TryVsyscallProcess(void) {
time_t current_time;
// time() is implemented as a vsyscall. With an older glibc, with
// vsyscall=emulate and some versions of the seccomp BPF patch
@@ -98,10 +101,151 @@ void Sandbox::TryVsyscallProcess(void) {
}
}
+bool IsSingleThreaded(int proc_fd) {
+ if (proc_fd < 0) {
+ // Cannot determine whether program is single-threaded. Hope for
+ // the best...
+ return true;
+ }
+
+ struct stat sb;
+ int task = -1;
+ if ((task = openat(proc_fd, "self/task", O_RDONLY|O_DIRECTORY)) < 0 ||
+ fstat(task, &sb) != 0 ||
+ sb.st_nlink != 3 ||
+ HANDLE_EINTR(close(task))) {
+ if (task >= 0) {
+ if (HANDLE_EINTR(close(task))) { }
+ }
+ return false;
+ }
+ return true;
+}
+
+bool IsDenied(const ErrorCode& code) {
+ return (code.err() & SECCOMP_RET_ACTION) == SECCOMP_RET_TRAP ||
+ (code.err() >= (SECCOMP_RET_ERRNO + ErrorCode::ERR_MIN_ERRNO) &&
+ code.err() <= (SECCOMP_RET_ERRNO + ErrorCode::ERR_MAX_ERRNO));
+}
+
+// Function that can be passed as a callback function to CodeGen::Traverse().
+// Checks whether the "insn" returns an UnsafeTrap() ErrorCode. If so, it
+// sets the "bool" variable pointed to by "aux".
+void CheckForUnsafeErrorCodes(Instruction *insn, void *aux) {
+ bool *is_unsafe = static_cast<bool *>(aux);
+ if (!*is_unsafe) {
+ if (BPF_CLASS(insn->code) == BPF_RET &&
+ insn->k > SECCOMP_RET_TRAP &&
+ insn->k - SECCOMP_RET_TRAP <= SECCOMP_RET_DATA) {
+ const ErrorCode& err =
+ Trap::ErrorCodeFromTrapId(insn->k & SECCOMP_RET_DATA);
+ if (err.error_type() != ErrorCode::ET_INVALID && !err.safe()) {
+ *is_unsafe = true;
+ }
+ }
+ }
+}
+
+// A Trap() handler that returns an "errno" value. The value is encoded
+// in the "aux" parameter.
+intptr_t ReturnErrno(const struct arch_seccomp_data&, void *aux) {
+ // TrapFnc functions report error by following the native kernel convention
+ // of returning an exit code in the range of -1..-4096. They do not try to
+ // set errno themselves. The glibc wrapper that triggered the SIGSYS will
+ // ultimately do so for us.
+ int err = reinterpret_cast<intptr_t>(aux) & SECCOMP_RET_DATA;
+ return -err;
+}
+
+// Function that can be passed as a callback function to CodeGen::Traverse().
+// Checks whether the "insn" returns an errno value from a BPF filter. If so,
+// it rewrites the instruction to instead call a Trap() handler that does
+// the same thing. "aux" is ignored.
+void RedirectToUserspace(Instruction *insn, void *aux) {
+ // When inside an UnsafeTrap() callback, we want to allow all system calls.
+ // This means, we must conditionally disable the sandbox -- and that's not
+ // something that kernel-side BPF filters can do, as they cannot inspect
+ // any state other than the syscall arguments.
+ // But if we redirect all error handlers to user-space, then we can easily
+ // make this decision.
+ // The performance penalty for this extra round-trip to user-space is not
+ // actually that bad, as we only ever pay it for denied system calls; and a
+ // typical program has very few of these.
+ Sandbox *sandbox = static_cast<Sandbox *>(aux);
+ if (BPF_CLASS(insn->code) == BPF_RET &&
+ (insn->k & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
+ insn->k = sandbox->Trap(ReturnErrno,
+ reinterpret_cast<void *>(insn->k & SECCOMP_RET_DATA)).err();
+ }
+}
+
+// Stackable wrapper around an Evaluators handler. Changes ErrorCodes
+// returned by a system call evaluator to match the changes made by
+// RedirectToUserspace(). "aux" should be pointer to wrapped system call
+// evaluator.
+ErrorCode RedirectToUserspaceEvalWrapper(Sandbox *sandbox, int sysnum,
+ void *aux) {
+ // We need to replicate the behavior of RedirectToUserspace(), so that our
+ // Verifier can still work correctly.
+ Sandbox::Evaluators *evaluators =
+ reinterpret_cast<Sandbox::Evaluators *>(aux);
+ const std::pair<Sandbox::EvaluateSyscall, void *>& evaluator =
+ *evaluators->begin();
+
+ ErrorCode err = evaluator.first(sandbox, sysnum, evaluator.second);
+ if ((err.err() & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
+ return sandbox->Trap(ReturnErrno,
+ reinterpret_cast<void *>(err.err() & SECCOMP_RET_DATA));
+ }
+ return err;
+}
+
+intptr_t BpfFailure(const struct arch_seccomp_data&, void *aux) {
+ SANDBOX_DIE(static_cast<char *>(aux));
+}
+
+} // namespace
+
+// 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
+// pre-BPF seccomp mode.
+namespace playground2 {
+
+Sandbox::Sandbox()
+ : quiet_(false),
+ proc_fd_(-1),
+ evaluators_(new Evaluators),
+ conds_(new Conds) {
+}
+
+Sandbox::~Sandbox() {
+ // It is generally unsafe to call any memory allocator operations or to even
+ // call arbitrary destructors after having installed a new policy. We just
+ // have no way to tell whether this policy would allow the system calls that
+ // the constructors can trigger.
+ // So, we normally destroy all of our complex state prior to starting the
+ // sandbox. But this won't happen, if the Sandbox object was created and
+ // never actually used to set up a sandbox. So, just in case, we are
+ // destroying any remaining state.
+ // The "if ()" statements are technically superfluous. But let's be explicit
+ // that we really don't want to run any code, when we already destroyed
+ // objects before setting up the sandbox.
+ if (evaluators_) {
+ delete evaluators_;
+ }
+ if (conds_) {
+ delete conds_;
+ }
+}
+
+bool Sandbox::IsValidSyscallNumber(int sysnum) {
+ return SyscallIterator::IsValid(sysnum);
+}
+
+
bool Sandbox::RunFunctionInPolicy(void (*code_in_sandbox)(),
- EvaluateSyscall syscall_evaluator,
- void *aux,
- int proc_fd) {
+ Sandbox::EvaluateSyscall syscall_evaluator,
+ void *aux) {
// Block all signals before forking a child process. This prevents an
// attacker from manipulating our test by sending us an unexpected signal.
sigset_t old_mask, new_mask;
@@ -168,14 +312,8 @@ bool Sandbox::RunFunctionInPolicy(void (*code_in_sandbox)(),
#endif
}
- evaluators_.clear();
SetSandboxPolicy(syscall_evaluator, aux);
- set_proc_fd(proc_fd);
-
- // By passing "quiet=true" to "startSandboxInternal()" we suppress
- // messages for expected and benign failures (e.g. if the current
- // kernel lacks support for BPF filters).
- StartSandboxInternal(true);
+ StartSandbox();
// Run our code in the sandbox.
code_in_sandbox();
@@ -220,11 +358,10 @@ bool Sandbox::RunFunctionInPolicy(void (*code_in_sandbox)(),
return rc;
}
-bool Sandbox::KernelSupportSeccompBPF(int proc_fd) {
+bool Sandbox::KernelSupportSeccompBPF() {
return
- RunFunctionInPolicy(ProbeProcess, Sandbox::ProbeEvaluator, 0, proc_fd) &&
- RunFunctionInPolicy(TryVsyscallProcess, Sandbox::AllowAllEvaluator, 0,
- proc_fd);
+ RunFunctionInPolicy(ProbeProcess, ProbeEvaluator, 0) &&
+ RunFunctionInPolicy(TryVsyscallProcess, AllowAllEvaluator, 0);
}
Sandbox::SandboxStatus Sandbox::SupportsSeccompSandbox(int proc_fd) {
@@ -259,7 +396,16 @@ Sandbox::SandboxStatus Sandbox::SupportsSeccompSandbox(int proc_fd) {
// we otherwise don't believe to have a good cached value, we have to
// perform a thorough check now.
if (status_ == STATUS_UNKNOWN) {
- status_ = KernelSupportSeccompBPF(proc_fd)
+ // We create our own private copy of a "Sandbox" object. This ensures that
+ // the object does not have any policies configured, that might interfere
+ // with the tests done by "KernelSupportSeccompBPF()".
+ Sandbox sandbox;
+
+ // By setting "quiet_ = true" we suppress messages for expected and benign
+ // failures (e.g. if the current kernel lacks support for BPF filters).
+ sandbox.quiet_ = true;
+ sandbox.set_proc_fd(proc_fd);
+ status_ = sandbox.KernelSupportSeccompBPF()
? STATUS_AVAILABLE : STATUS_UNSUPPORTED;
// As we are performing our tests from a child process, the run-time
@@ -277,13 +423,13 @@ void Sandbox::set_proc_fd(int proc_fd) {
proc_fd_ = proc_fd;
}
-void Sandbox::StartSandboxInternal(bool quiet) {
+void Sandbox::StartSandbox() {
if (status_ == STATUS_UNSUPPORTED || status_ == STATUS_UNAVAILABLE) {
SANDBOX_DIE("Trying to start sandbox, even though it is known to be "
"unavailable");
- } else if (status_ == STATUS_ENABLED) {
- SANDBOX_DIE("Cannot start sandbox recursively. Use multiple calls to "
- "setSandboxPolicy() to stack policies instead");
+ } else if (!evaluators_ || !conds_) {
+ SANDBOX_DIE("Cannot repeatedly start sandbox. Create a separate Sandbox "
+ "object instead.");
}
if (proc_fd_ < 0) {
proc_fd_ = open("/proc", O_RDONLY|O_DIRECTORY);
@@ -307,44 +453,17 @@ void Sandbox::StartSandboxInternal(bool quiet) {
}
// Install the filters.
- InstallFilter(quiet);
+ InstallFilter();
// We are now inside the sandbox.
status_ = STATUS_ENABLED;
}
-bool Sandbox::IsSingleThreaded(int proc_fd) {
- if (proc_fd < 0) {
- // Cannot determine whether program is single-threaded. Hope for
- // the best...
- return true;
- }
-
- struct stat sb;
- int task = -1;
- if ((task = openat(proc_fd, "self/task", O_RDONLY|O_DIRECTORY)) < 0 ||
- fstat(task, &sb) != 0 ||
- sb.st_nlink != 3 ||
- HANDLE_EINTR(close(task))) {
- if (task >= 0) {
- if (HANDLE_EINTR(close(task))) { }
- }
- return false;
- }
- return true;
-}
-
-bool Sandbox::IsDenied(const ErrorCode& code) {
- return (code.err() & SECCOMP_RET_ACTION) == SECCOMP_RET_TRAP ||
- (code.err() >= (SECCOMP_RET_ERRNO + ErrorCode::ERR_MIN_ERRNO) &&
- code.err() <= (SECCOMP_RET_ERRNO + ErrorCode::ERR_MAX_ERRNO));
-}
-
void Sandbox::PolicySanityChecks(EvaluateSyscall syscall_evaluator,
void *aux) {
for (SyscallIterator iter(true); !iter.Done(); ) {
uint32_t sysnum = iter.Next();
- if (!IsDenied(syscall_evaluator(sysnum, aux))) {
+ if (!IsDenied(syscall_evaluator(this, sysnum, aux))) {
SANDBOX_DIE("Policies should deny system calls that are outside the "
"expected range (typically MIN_SYSCALL..MAX_SYSCALL)");
}
@@ -352,60 +471,15 @@ void Sandbox::PolicySanityChecks(EvaluateSyscall syscall_evaluator,
return;
}
-void Sandbox::CheckForUnsafeErrorCodes(Instruction *insn, void *aux) {
- bool *is_unsafe = static_cast<bool *>(aux);
- if (!*is_unsafe) {
- if (BPF_CLASS(insn->code) == BPF_RET &&
- insn->k > SECCOMP_RET_TRAP &&
- insn->k - SECCOMP_RET_TRAP <= SECCOMP_RET_DATA) {
- const ErrorCode& err =
- Trap::ErrorCodeFromTrapId(insn->k & SECCOMP_RET_DATA);
- if (err.error_type_ != ErrorCode::ET_INVALID && !err.safe_) {
- *is_unsafe = true;
- }
- }
- }
-}
-
-void Sandbox::RedirectToUserspace(Instruction *insn, void *) {
- // When inside an UnsafeTrap() callback, we want to allow all system calls.
- // This means, we must conditionally disable the sandbox -- and that's not
- // something that kernel-side BPF filters can do, as they cannot inspect
- // any state other than the syscall arguments.
- // But if we redirect all error handlers to user-space, then we can easily
- // make this decision.
- // The performance penalty for this extra round-trip to user-space is not
- // actually that bad, as we only ever pay it for denied system calls; and a
- // typical program has very few of these.
- if (BPF_CLASS(insn->code) == BPF_RET &&
- (insn->k & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
- insn->k = Trap(ReturnErrno,
- reinterpret_cast<void *>(insn->k & SECCOMP_RET_DATA)).err();
- }
-}
-
-ErrorCode Sandbox::RedirectToUserspaceEvalWrapper(int sysnum, void *aux) {
- // We need to replicate the behavior of RedirectToUserspace(), so that our
- // Verifier can still work correctly.
- Evaluators *evaluators = reinterpret_cast<Evaluators *>(aux);
- const std::pair<EvaluateSyscall, void *>& evaluator = *evaluators->begin();
- ErrorCode err = evaluator.first(sysnum, evaluator.second);
- if ((err.err() & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
- return Trap(ReturnErrno,
- reinterpret_cast<void *>(err.err() & SECCOMP_RET_DATA));
- }
- return err;
-}
-
void Sandbox::SetSandboxPolicy(EvaluateSyscall syscall_evaluator, void *aux) {
- if (status_ == STATUS_ENABLED) {
+ if (!evaluators_ || !conds_) {
SANDBOX_DIE("Cannot change policy after sandbox has started");
}
PolicySanityChecks(syscall_evaluator, aux);
- evaluators_.push_back(std::make_pair(syscall_evaluator, aux));
+ evaluators_->push_back(std::make_pair(syscall_evaluator, aux));
}
-void Sandbox::InstallFilter(bool quiet) {
+void Sandbox::InstallFilter() {
// We want to be very careful in not imposing any requirements on the
// policies that are set with SetSandboxPolicy(). This means, as soon as
// the sandbox is active, we shouldn't be relying on libraries that could
@@ -426,15 +500,17 @@ void Sandbox::InstallFilter(bool quiet) {
delete program;
// Release memory that is no longer needed
- evaluators_.clear();
- conds_.clear();
+ delete evaluators_;
+ delete conds_;
+ evaluators_ = NULL;
+ conds_ = NULL;
// Install BPF filter program
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
- SANDBOX_DIE(quiet ? NULL : "Kernel refuses to enable no-new-privs");
+ SANDBOX_DIE(quiet_ ? NULL : "Kernel refuses to enable no-new-privs");
} else {
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
- SANDBOX_DIE(quiet ? NULL : "Kernel refuses to turn on BPF filters");
+ SANDBOX_DIE(quiet_ ? NULL : "Kernel refuses to turn on BPF filters");
}
}
@@ -447,13 +523,13 @@ Sandbox::Program *Sandbox::AssembleFilter(bool force_verification) {
#endif
// Verify that the user pushed a policy.
- if (evaluators_.empty()) {
+ if (evaluators_->empty()) {
SANDBOX_DIE("Failed to configure system call filters");
}
// We can't handle stacked evaluators, yet. We'll get there eventually
// though. Hang tight.
- if (evaluators_.size() != 1) {
+ if (evaluators_->size() != 1) {
SANDBOX_DIE("Not implemented");
}
@@ -509,18 +585,18 @@ Sandbox::Program *Sandbox::AssembleFilter(bool force_verification) {
"architecture");
}
- EvaluateSyscall evaluateSyscall = evaluators_.begin()->first;
- void *aux = evaluators_.begin()->second;
- if (!evaluateSyscall(__NR_rt_sigprocmask, aux).
+ EvaluateSyscall evaluateSyscall = evaluators_->begin()->first;
+ void *aux = evaluators_->begin()->second;
+ if (!evaluateSyscall(this, __NR_rt_sigprocmask, aux).
Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) ||
- !evaluateSyscall(__NR_rt_sigreturn, aux).
+ !evaluateSyscall(this, __NR_rt_sigreturn, aux).
Equals(ErrorCode(ErrorCode::ERR_ALLOWED))
#if defined(__NR_sigprocmask)
- || !evaluateSyscall(__NR_sigprocmask, aux).
+ || !evaluateSyscall(this, __NR_sigprocmask, aux).
Equals(ErrorCode(ErrorCode::ERR_ALLOWED))
#endif
#if defined(__NR_sigreturn)
- || !evaluateSyscall(__NR_sigreturn, aux).
+ || !evaluateSyscall(this, __NR_sigreturn, aux).
Equals(ErrorCode(ErrorCode::ERR_ALLOWED))
#endif
) {
@@ -536,7 +612,7 @@ Sandbox::Program *Sandbox::AssembleFilter(bool force_verification) {
// than enabling dangerous code.
SANDBOX_DIE("We'd rather die than enable unsafe traps");
}
- gen->Traverse(jumptable, RedirectToUserspace, NULL);
+ gen->Traverse(jumptable, RedirectToUserspace, this);
// Allow system calls, if they originate from our magic return address
// (which we can query by calling SandboxSyscall(-1)).
@@ -615,12 +691,13 @@ void Sandbox::VerifyProgram(const Program& program, bool has_unsafe_traps) {
// the verifier would also report a mismatch in return codes.
Evaluators redirected_evaluators;
redirected_evaluators.push_back(
- std::make_pair(RedirectToUserspaceEvalWrapper, &evaluators_));
+ std::make_pair(RedirectToUserspaceEvalWrapper, evaluators_));
const char *err = NULL;
if (!Verifier::VerifyBPF(
+ this,
program,
- has_unsafe_traps ? redirected_evaluators : evaluators_,
+ has_unsafe_traps ? redirected_evaluators : *evaluators_,
&err)) {
CodeGen::PrintProgram(program);
SANDBOX_DIE(err);
@@ -633,14 +710,15 @@ void Sandbox::FindRanges(Ranges *ranges) {
// deal with this disparity by enumerating from MIN_SYSCALL to MAX_SYSCALL,
// and then verifying that the rest of the number range (both positive and
// negative) all return the same ErrorCode.
- EvaluateSyscall evaluate_syscall = evaluators_.begin()->first;
- void *aux = evaluators_.begin()->second;
+ EvaluateSyscall evaluate_syscall = evaluators_->begin()->first;
+ void *aux = evaluators_->begin()->second;
uint32_t old_sysnum = 0;
- ErrorCode old_err = evaluate_syscall(old_sysnum, aux);
- ErrorCode invalid_err = evaluate_syscall(MIN_SYSCALL - 1, aux);
+ ErrorCode old_err = evaluate_syscall(this, old_sysnum, aux);
+ ErrorCode invalid_err = evaluate_syscall(this, MIN_SYSCALL - 1,
+ aux);
for (SyscallIterator iter(false); !iter.Done(); ) {
uint32_t sysnum = iter.Next();
- ErrorCode err = evaluate_syscall(static_cast<int>(sysnum), aux);
+ ErrorCode err = evaluate_syscall(this, static_cast<int>(sysnum), aux);
if (!iter.IsValid(sysnum) && !invalid_err.Equals(err)) {
// A proper sandbox policy should always treat system calls outside of
// the range MIN_SYSCALL..MAX_SYSCALL (i.e. anything that returns
@@ -890,25 +968,12 @@ intptr_t Sandbox::ForwardSyscall(const struct arch_seccomp_data& args) {
static_cast<intptr_t>(args.args[5]));
}
-intptr_t Sandbox::ReturnErrno(const struct arch_seccomp_data&, void *aux) {
- // TrapFnc functions report error by following the native kernel convention
- // of returning an exit code in the range of -1..-4096. They do not try to
- // set errno themselves. The glibc wrapper that triggered the SIGSYS will
- // ultimately do so for us.
- int err = reinterpret_cast<intptr_t>(aux) & SECCOMP_RET_DATA;
- return -err;
-}
-
ErrorCode Sandbox::Cond(int argno, ErrorCode::ArgType width,
ErrorCode::Operation op, uint64_t value,
const ErrorCode& passed, const ErrorCode& failed) {
return ErrorCode(argno, width, op, value,
- &*conds_.insert(passed).first,
- &*conds_.insert(failed).first);
-}
-
-intptr_t Sandbox::BpfFailure(const struct arch_seccomp_data&, void *aux) {
- SANDBOX_DIE(static_cast<char *>(aux));
+ &*conds_->insert(passed).first,
+ &*conds_->insert(failed).first);
}
ErrorCode Sandbox::Kill(const char *msg) {
@@ -916,8 +981,5 @@ ErrorCode Sandbox::Kill(const char *msg) {
}
Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN;
-int Sandbox::proc_fd_ = -1;
-Sandbox::Evaluators Sandbox::evaluators_;
-Sandbox::Conds Sandbox::conds_;
} // namespace

Powered by Google App Engine
This is Rietveld 408576698