summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authormarkus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-31 08:22:25 +0000
committermarkus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-31 08:22:25 +0000
commit7ecfa14fb92867f827de6853a058ccbde556c663 (patch)
tree25b0094d959e4afa1e4a698850192375daffac3a /sandbox
parentcbfd582f44dbd2b3b25ac0f02049f4d5b72e0d62 (diff)
downloadchromium_src-7ecfa14fb92867f827de6853a058ccbde556c663.zip
chromium_src-7ecfa14fb92867f827de6853a058ccbde556c663.tar.gz
chromium_src-7ecfa14fb92867f827de6853a058ccbde556c663.tar.bz2
Pass a pointer with auxilliary data to a policy function.
This data can be used by the policy to communicate with the method that set up policy. In BPF_TEST()s it allows us to avoid global variables. BUG=130662 TEST=sandbox_linux_unittests Review URL: https://chromiumcodereview.appspot.com/11230048 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@165123 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/linux/sandbox_linux.gypi1
-rw-r--r--sandbox/linux/seccomp-bpf/bpf_tests.cc35
-rw-r--r--sandbox/linux/seccomp-bpf/bpf_tests.h60
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf.cc34
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf.h40
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc67
-rw-r--r--sandbox/linux/seccomp-bpf/verifier.cc3
7 files changed, 143 insertions, 97 deletions
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi
index 1d49b47..c02cd31 100644
--- a/sandbox/linux/sandbox_linux.gypi
+++ b/sandbox/linux/sandbox_linux.gypi
@@ -53,7 +53,6 @@
[ 'OS=="linux" and (target_arch=="ia32" or target_arch=="x64" '
'or target_arch=="arm")', {
'sources': [
- 'seccomp-bpf/bpf_tests.cc',
'seccomp-bpf/bpf_tests.h',
'seccomp-bpf/codegen_unittest.cc',
'seccomp-bpf/errorcode_unittest.cc',
diff --git a/sandbox/linux/seccomp-bpf/bpf_tests.cc b/sandbox/linux/seccomp-bpf/bpf_tests.cc
deleted file mode 100644
index efe4020..0000000
--- a/sandbox/linux/seccomp-bpf/bpf_tests.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/linux/seccomp-bpf/bpf_tests.h"
-
-using playground2::Die;
-using playground2::Sandbox;
-
-namespace sandbox {
-
-void BpfTests::TestWrapper(void *void_arg) {
- TestArgs *arg = reinterpret_cast<TestArgs *>(void_arg);
- Die::EnableSimpleExit();
- if (Sandbox::supportsSeccompSandbox(-1) ==
- Sandbox::STATUS_AVAILABLE) {
- // Ensure the the sandbox is actually available at this time
- int proc_fd;
- BPF_ASSERT((proc_fd = open("/proc", O_RDONLY|O_DIRECTORY)) >= 0);
- BPF_ASSERT(Sandbox::supportsSeccompSandbox(proc_fd) ==
- Sandbox::STATUS_AVAILABLE);
-
- // Initialize and then start the sandbox with our custom policy
- Sandbox::setProcFd(proc_fd);
- Sandbox::setSandboxPolicy(arg->policy(), NULL);
- Sandbox::startSandbox();
- arg->test()();
- } else {
- // TODO(markus): (crbug.com/141545) Call the compiler and verify the
- // policy. That's the least we can do, if we don't have kernel support.
- Sandbox::setSandboxPolicy(arg->policy(), NULL);
- }
-}
-
-} // namespace
diff --git a/sandbox/linux/seccomp-bpf/bpf_tests.h b/sandbox/linux/seccomp-bpf/bpf_tests.h
index ace0ce3..8da25f9 100644
--- a/sandbox/linux/seccomp-bpf/bpf_tests.h
+++ b/sandbox/linux/seccomp-bpf/bpf_tests.h
@@ -16,36 +16,74 @@ namespace sandbox {
// Also, it takes advantage of the Die class to avoid calling LOG(FATAL), from
// inside our tests, as we don't need or even want all the error handling that
// LOG(FATAL) would do.
-#define BPF_TEST(test_case_name, test_name, policy) \
- void BPF_TEST_##test_name(); \
+// BPF_TEST() takes a C++ data type as an optional fourth parameter. If
+// present, this sets up a variable that can be accessed as "BPF_AUX". This
+// variable will be passed as an argument to the "policy" function. Policies
+// would typically use it as an argument to Sandbox::Trap(), if they want to
+// communicate data between the BPF_TEST() and a Trap() function.
+#define BPF_TEST(test_case_name, test_name, policy, aux...) \
+ void BPF_TEST_##test_name(sandbox::BpfTests<aux>::AuxType& BPF_AUX); \
TEST(test_case_name, test_name) { \
- sandbox::BpfTests::TestArgs arg(BPF_TEST_##test_name, policy); \
- sandbox::BpfTests::RunTestInProcess(sandbox::BpfTests::TestWrapper, &arg);\
+ sandbox::BpfTests<aux>::TestArgs arg(BPF_TEST_##test_name, policy); \
+ sandbox::BpfTests<aux>::RunTestInProcess( \
+ sandbox::BpfTests<aux>::TestWrapper, &arg);\
} \
- void BPF_TEST_##test_name()
+ void BPF_TEST_##test_name(sandbox::BpfTests<aux>::AuxType& BPF_AUX)
// Assertions are handled exactly the same as with a normal SANDBOX_TEST()
#define BPF_ASSERT SANDBOX_ASSERT
+// The "Aux" type is optional. We use an "empty" type by default, so that if
+// the caller doesn't provide any type, all the BPF_AUX related data compiles
+// to nothing.
+template<class Aux = int[0]>
class BpfTests : public UnitTests {
public:
+ typedef Aux AuxType;
+
class TestArgs {
public:
- TestArgs(void (*test)(), playground2::Sandbox::EvaluateSyscall policy)
- : test_(test),
- policy_(policy) {
+ TestArgs(void (*t)(AuxType&), playground2::Sandbox::EvaluateSyscall p)
+ : test_(t),
+ policy_(p),
+ aux_() {
}
- void (*test() const)() { return test_; }
+ void (*test() const)(AuxType&) { return test_; }
playground2::Sandbox::EvaluateSyscall policy() const { return policy_; }
private:
- void (*test_)();
+ friend class BpfTests;
+
+ void (*test_)(AuxType&);
playground2::Sandbox::EvaluateSyscall policy_;
+ AuxType aux_;
};
- static void TestWrapper(void *void_arg);
+ static void TestWrapper(void *void_arg) {
+ TestArgs *arg = reinterpret_cast<TestArgs *>(void_arg);
+ playground2::Die::EnableSimpleExit();
+ if (playground2::Sandbox::supportsSeccompSandbox(-1) ==
+ playground2::Sandbox::STATUS_AVAILABLE) {
+ // Ensure the the sandbox is actually available at this time
+ int proc_fd;
+ BPF_ASSERT((proc_fd = open("/proc", O_RDONLY|O_DIRECTORY)) >= 0);
+ BPF_ASSERT(playground2::Sandbox::supportsSeccompSandbox(proc_fd) ==
+ playground2::Sandbox::STATUS_AVAILABLE);
+
+ // Initialize and then start the sandbox with our custom policy
+ playground2::Sandbox::setProcFd(proc_fd);
+ playground2::Sandbox::setSandboxPolicy(arg->policy(), &arg->aux_);
+ playground2::Sandbox::startSandbox();
+
+ arg->test()(arg->aux_);
+ } else {
+ // TODO(markus): (crbug.com/141545) Call the compiler and verify the
+ // policy. That's the least we can do, if we don't have kernel support.
+ playground2::Sandbox::setSandboxPolicy(arg->policy(), NULL);
+ }
+ }
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(BpfTests);
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
index 6e3a6ba..eb03995 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -29,8 +29,8 @@ const int kExpectedExitCode = 100;
// 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 signo) {
- switch (signo) {
+ErrorCode Sandbox::probeEvaluator(int sysnum, void *) {
+ switch (sysnum) {
case __NR_getpid:
// Return EPERM so that we can check that the filter actually ran.
return ErrorCode(EPERM);
@@ -53,7 +53,7 @@ bool Sandbox::isValidSyscallNumber(int sysnum) {
return SyscallIterator::IsValid(sysnum);
}
-ErrorCode Sandbox::allowAllEvaluator(int sysnum) {
+ErrorCode Sandbox::allowAllEvaluator(int sysnum, void *) {
if (!isValidSyscallNumber(sysnum)) {
return ErrorCode(ENOSYS);
}
@@ -72,6 +72,7 @@ void Sandbox::tryVsyscallProcess(void) {
bool Sandbox::RunFunctionInPolicy(void (*CodeInSandbox)(),
EvaluateSyscall syscallEvaluator,
+ void *aux,
int proc_fd) {
// Block all signals before forking a child process. This prevents an
// attacker from manipulating our test by sending us an unexpected signal.
@@ -126,7 +127,7 @@ bool Sandbox::RunFunctionInPolicy(void (*CodeInSandbox)(),
}
evaluators_.clear();
- setSandboxPolicy(syscallEvaluator, NULL);
+ setSandboxPolicy(syscallEvaluator, aux);
setProcFd(proc_fd);
// By passing "quiet=true" to "startSandboxInternal()" we suppress
@@ -187,9 +188,10 @@ bool Sandbox::kernelSupportSeccompBPF(int proc_fd) {
}
#endif
- return RunFunctionInPolicy(probeProcess, Sandbox::probeEvaluator, proc_fd) &&
- RunFunctionInPolicy(tryVsyscallProcess, Sandbox::allowAllEvaluator,
- proc_fd);
+ return
+ RunFunctionInPolicy(probeProcess, Sandbox::probeEvaluator, 0, proc_fd) &&
+ RunFunctionInPolicy(tryVsyscallProcess, Sandbox::allowAllEvaluator, 0,
+ proc_fd);
}
Sandbox::SandboxStatus Sandbox::supportsSeccompSandbox(int proc_fd) {
@@ -306,10 +308,10 @@ bool Sandbox::isDenied(const ErrorCode& code) {
}
void Sandbox::policySanityChecks(EvaluateSyscall syscallEvaluator,
- EvaluateArguments) {
+ void *aux) {
for (SyscallIterator iter(true); !iter.Done(); ) {
uint32_t sysnum = iter.Next();
- if (!isDenied(syscallEvaluator(sysnum))) {
+ if (!isDenied(syscallEvaluator(sysnum, aux))) {
SANDBOX_DIE("Policies should deny system calls that are outside the "
"expected range (typically MIN_SYSCALL..MAX_SYSCALL)");
}
@@ -317,13 +319,12 @@ void Sandbox::policySanityChecks(EvaluateSyscall syscallEvaluator,
return;
}
-void Sandbox::setSandboxPolicy(EvaluateSyscall syscallEvaluator,
- EvaluateArguments argumentEvaluator) {
+void Sandbox::setSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux) {
if (status_ == STATUS_ENABLED) {
SANDBOX_DIE("Cannot change policy after sandbox has started");
}
- policySanityChecks(syscallEvaluator, argumentEvaluator);
- evaluators_.push_back(std::make_pair(syscallEvaluator, argumentEvaluator));
+ policySanityChecks(syscallEvaluator, aux);
+ evaluators_.push_back(std::make_pair(syscallEvaluator, aux));
}
void Sandbox::installFilter(bool quiet) {
@@ -472,12 +473,13 @@ void Sandbox::findRanges(Ranges *ranges) {
// and then verifying that the rest of the number range (both positive and
// negative) all return the same ErrorCode.
EvaluateSyscall evaluateSyscall = evaluators_.begin()->first;
+ void *aux = evaluators_.begin()->second;
uint32_t oldSysnum = 0;
- ErrorCode oldErr = evaluateSyscall(oldSysnum);
- ErrorCode invalidErr = evaluateSyscall(MIN_SYSCALL - 1);
+ ErrorCode oldErr = evaluateSyscall(oldSysnum, aux);
+ ErrorCode invalidErr = evaluateSyscall(MIN_SYSCALL - 1, aux);
for (SyscallIterator iter(false); !iter.Done(); ) {
uint32_t sysnum = iter.Next();
- ErrorCode err = evaluateSyscall(static_cast<int>(sysnum));
+ ErrorCode err = evaluateSyscall(static_cast<int>(sysnum), aux);
if (!iter.IsValid(sysnum) && !invalidErr.Equals(err)) {
// A proper sandbox policy should always treat system calls outside of
// the range MIN_SYSCALL..MAX_SYSCALL (i.e. anything that returns
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
index d0764dd..a50ddb3 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.h
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
@@ -223,10 +223,13 @@ class Sandbox {
ErrorCode failed;
};
- typedef ErrorCode (*EvaluateSyscall)(int sysno);
- typedef int (*EvaluateArguments)(int sysno, int arg,
- Constraint *constraint);
- typedef std::vector<std::pair<EvaluateSyscall,EvaluateArguments> >Evaluators;
+ // When calling setSandboxPolicy(), the caller can provide an arbitrary
+ // pointer. This pointer will then be forwarded to the sandbox policy
+ // each time a call is made through an EvaluateSyscall function pointer.
+ // One common use case would be to pass the "aux" pointer as an argument
+ // to Trap() functions.
+ typedef ErrorCode (*EvaluateSyscall)(int sysnum, void *aux);
+ typedef std::vector<std::pair<EvaluateSyscall, void *> >Evaluators;
// Checks whether a particular system call number is valid on the current
// architecture. E.g. on ARM there's a non-contiguous range of private
@@ -249,21 +252,23 @@ class Sandbox {
// The system call evaluator function is called with the system
// call number. It can decide to allow the system call unconditionally
- // by returning "0"; it can deny the system call unconditionally by
+ // by returning ERR_ALLOWED; it can deny the system call unconditionally by
// returning an appropriate "errno" value; or it can request inspection
- // of system call argument(s) by returning a suitable combination of
- // SB_INSPECT_ARG_x bits.
- // The system argument evaluator is called (if needed) to query additional
- // constraints for the system call arguments. In the vast majority of
- // cases, it will set a "Constraint" that forces a new "errno" value.
- // But for more complex filters, it is possible to return another mask
- // of SB_INSPECT_ARG_x bits.
- static void setSandboxPolicy(EvaluateSyscall syscallEvaluator,
- EvaluateArguments argumentEvaluator);
+ // of system call argument(s) by returning a suitable ErrorCode.
+ // The "aux" parameter can be used to pass optional data to the system call
+ // evaluator. There are different possible uses for this data, but one of the
+ // use cases would be for the policy to then forward this pointer to a Trap()
+ // handler. In this case, of course, the data that is pointed to must remain
+ // valid for the entire time that Trap() handlers can be called; typically,
+ // this would be the lifetime of the program.
+ static void setSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux);
// We can use ErrorCode to request calling of a trap handler. This method
// performs the required wrapping of the callback function into an
// ErrorCode object.
+ // The "aux" field can carry a pointer to arbitrary data. See EvaluateSyscall
+ // for a description of how to pass data from setSandboxPolicy() to a Trap()
+ // handler.
static ErrorCode Trap(ErrorCode::TrapFnc fnc, const void *aux);
// Kill the program and print an error message.
@@ -300,20 +305,21 @@ class Sandbox {
// Get a file descriptor pointing to "/proc", if currently available.
static int proc_fd() { return proc_fd_; }
- static ErrorCode probeEvaluator(int signo) __attribute__((const));
+ static ErrorCode probeEvaluator(int sysnum, void *) __attribute__((const));
static void probeProcess(void);
- static ErrorCode allowAllEvaluator(int sysnum);
+ static ErrorCode allowAllEvaluator(int sysnum, void *aux);
static void tryVsyscallProcess(void);
static bool kernelSupportSeccompBPF(int proc_fd);
static bool RunFunctionInPolicy(void (*function)(),
EvaluateSyscall syscallEvaluator,
+ void *aux,
int proc_fd);
static void startSandboxInternal(bool quiet);
static bool isSingleThreaded(int proc_fd);
static bool isDenied(const ErrorCode& code);
static bool disableFilesystem();
static void policySanityChecks(EvaluateSyscall syscallEvaluator,
- EvaluateArguments argumentEvaluator);
+ void *aux);
static void installFilter(bool quiet);
static void findRanges(Ranges *ranges);
static Instruction *assembleJumpTable(CodeGen *gen,
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
index 91d30ae..8ea23d9 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
@@ -35,9 +35,51 @@ SANDBOX_TEST(SandboxBpf, CallSupportsTwice) {
Sandbox::supportsSeccompSandbox(-1);
}
+// BPF_TEST does a lot of the boiler-plate code around setting up a
+// policy and optional passing data between the caller, the policy and
+// any Trap() handlers. This is great for writing short and concise tests,
+// and it helps us accidentally forgetting any of the crucial steps in
+// setting up the sandbox. But it wouldn't hurt to have at least one test
+// that explicitly walks through all these steps.
+
+intptr_t FakeGetPid(const struct arch_seccomp_data& args, void *aux) {
+ BPF_ASSERT(aux);
+ pid_t *pid_ptr = static_cast<pid_t *>(aux);
+ return (*pid_ptr)++;
+}
+
+ErrorCode VerboseAPITestingPolicy(int sysno, void *aux) {
+ if (!Sandbox::isValidSyscallNumber(sysno)) {
+ return ErrorCode(ENOSYS);
+ } else if (sysno == __NR_getpid) {
+ return Sandbox::Trap(FakeGetPid, aux);
+ } else {
+ return ErrorCode(ErrorCode::ERR_ALLOWED);
+ }
+}
+
+SANDBOX_TEST(SandboxBpf, VerboseAPITesting) {
+ if (Sandbox::supportsSeccompSandbox(-1) ==
+ playground2::Sandbox::STATUS_AVAILABLE) {
+ pid_t test_var = 0;
+ playground2::Sandbox::setSandboxPolicy(VerboseAPITestingPolicy, &test_var);
+ playground2::Sandbox::startSandbox();
+
+ BPF_ASSERT(test_var == 0);
+ BPF_ASSERT(syscall(__NR_getpid) == 0);
+ BPF_ASSERT(test_var == 1);
+ BPF_ASSERT(syscall(__NR_getpid) == 1);
+ BPF_ASSERT(test_var == 2);
+
+ // N.B.: Any future call to getpid() would corrupt the stack.
+ // This is OK. The SANDBOX_TEST() macro is guaranteed to
+ // only ever call _exit() after the test completes.
+ }
+}
+
// A simple blacklist test
-ErrorCode BlacklistNanosleepPolicy(int sysno) {
+ErrorCode BlacklistNanosleepPolicy(int sysno, void *) {
if (!Sandbox::isValidSyscallNumber(sysno)) {
// FIXME: we should really not have to do that in a trivial policy
return ErrorCode(ENOSYS);
@@ -61,7 +103,7 @@ BPF_TEST(SandboxBpf, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) {
// Now do a simple whitelist test
-ErrorCode WhitelistGetpidPolicy(int sysno) {
+ErrorCode WhitelistGetpidPolicy(int sysno, void *) {
switch (sysno) {
case __NR_getpid:
case __NR_exit_group:
@@ -84,11 +126,6 @@ BPF_TEST(SandboxBpf, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) {
// A simple blacklist policy, with a SIGSYS handler
-// TODO: provide an API to provide the auxiliary data pointer
-// to the evaluator
-
-static int BlacklistNanosleepPolicySigsysAuxData;
-
intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) {
// We also check that the auxiliary data is correct
SANDBOX_ASSERT(aux);
@@ -96,7 +133,7 @@ intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) {
return -ENOMEM;
}
-ErrorCode BlacklistNanosleepPolicySigsys(int sysno) {
+ErrorCode BlacklistNanosleepPolicySigsys(int sysno, void *aux) {
if (!Sandbox::isValidSyscallNumber(sysno)) {
// FIXME: we should really not have to do that in a trivial policy
return ErrorCode(ENOSYS);
@@ -104,29 +141,27 @@ ErrorCode BlacklistNanosleepPolicySigsys(int sysno) {
switch (sysno) {
case __NR_nanosleep:
- return Sandbox::Trap(EnomemHandler,
- static_cast<void *>(&BlacklistNanosleepPolicySigsysAuxData));
+ return Sandbox::Trap(EnomemHandler, aux);
default:
return ErrorCode(ErrorCode::ERR_ALLOWED);
}
}
BPF_TEST(SandboxBpf, BasicBlacklistWithSigsys,
- BlacklistNanosleepPolicySigsys) {
+ BlacklistNanosleepPolicySigsys, int /* BPF_AUX */) {
// getpid() should work properly
errno = 0;
BPF_ASSERT(syscall(__NR_getpid) > 0);
BPF_ASSERT(errno == 0);
// Our Auxiliary Data, should be reset by the signal handler
- BlacklistNanosleepPolicySigsysAuxData = -1;
+ BPF_AUX = -1;
const struct timespec ts = {0, 0};
BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1);
BPF_ASSERT(errno == ENOMEM);
// We expect the signal handler to modify AuxData
- BPF_ASSERT(
- BlacklistNanosleepPolicySigsysAuxData == kExpectedReturnValue);
+ BPF_ASSERT(BPF_AUX == kExpectedReturnValue);
}
// A more complex, but synthetic policy. This tests the correctness of the BPF
@@ -144,7 +179,7 @@ int SysnoToRandomErrno(int sysno) {
return ((sysno & ~3) >> 2) % 29 + 1;
}
-ErrorCode SyntheticPolicy(int sysno) {
+ErrorCode SyntheticPolicy(int sysno, void *) {
if (!Sandbox::isValidSyscallNumber(sysno)) {
// FIXME: we should really not have to do that in a trivial policy
return ErrorCode(ENOSYS);
@@ -202,7 +237,7 @@ int ArmPrivateSysnoToErrno(int sysno) {
}
}
-ErrorCode ArmPrivatePolicy(int sysno) {
+ErrorCode ArmPrivatePolicy(int sysno, void *) {
if (!Sandbox::isValidSyscallNumber(sysno)) {
// FIXME: we should really not have to do that in a trivial policy.
return ErrorCode(ENOSYS);
diff --git a/sandbox/linux/seccomp-bpf/verifier.cc b/sandbox/linux/seccomp-bpf/verifier.cc
index 641e433..40a1aa2 100644
--- a/sandbox/linux/seccomp-bpf/verifier.cc
+++ b/sandbox/linux/seccomp-bpf/verifier.cc
@@ -18,6 +18,7 @@ bool Verifier::VerifyBPF(const std::vector<struct sock_filter>& program,
return false;
}
Sandbox::EvaluateSyscall evaluate_syscall = evaluators.begin()->first;
+ void *aux = evaluators.begin()->second;
for (SyscallIterator iter(false); !iter.Done(); ) {
uint32_t sysnum = iter.Next();
// We ideally want to iterate over the full system call range and values
@@ -40,7 +41,7 @@ bool Verifier::VerifyBPF(const std::vector<struct sock_filter>& program,
}
#endif
#endif
- ErrorCode code = evaluate_syscall(sysnum);
+ ErrorCode code = evaluate_syscall(sysnum, aux);
uint32_t computed_ret = EvaluateBPF(program, data, err);
if (*err) {
return false;