summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-20 12:30:35 +0000
committerjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-20 12:30:35 +0000
commit4a72e663d062df7ba73d97a25ae3e397b65f8aea (patch)
treea1b57b5b4bffcc03a16c41e3e453b955fff5c769 /sandbox
parent933b7483adef1676e75b88183d0d8768063fe839 (diff)
downloadchromium_src-4a72e663d062df7ba73d97a25ae3e397b65f8aea.zip
chromium_src-4a72e663d062df7ba73d97a25ae3e397b65f8aea.tar.gz
chromium_src-4a72e663d062df7ba73d97a25ae3e397b65f8aea.tar.bz2
Revert 174135
> SECCOMP-BPF: Added support for checking system call arguments against bit masks. > > > BUG=130662 > TEST=sandbox_linux_unittests > > > Review URL: https://chromiumcodereview.appspot.com/11613016 Tests fail on Linux Precise bot: http://build.chromium.org/p/chromium.linux/buildstatus?builder=Linux%20Precise%20%28dbg%29&number=410 TBR=markus@chromium.org Review URL: https://codereview.chromium.org/11618035 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@174147 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/linux/seccomp-bpf/codegen.cc15
-rw-r--r--sandbox/linux/seccomp-bpf/errorcode.h47
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf.cc118
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf.h7
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc478
-rw-r--r--sandbox/linux/seccomp-bpf/verifier.cc104
-rw-r--r--sandbox/linux/seccomp-bpf/verifier.h2
7 files changed, 19 insertions, 752 deletions
diff --git a/sandbox/linux/seccomp-bpf/codegen.cc b/sandbox/linux/seccomp-bpf/codegen.cc
index 4fab5c8..649793c 100644
--- a/sandbox/linux/seccomp-bpf/codegen.cc
+++ b/sandbox/linux/seccomp-bpf/codegen.cc
@@ -79,21 +79,6 @@ void CodeGen::PrintProgram(const Sandbox::Program& program) {
case BPF_RET:
fprintf(stderr, "RET 0x%x\n", iter->k);
break;
- case BPF_ALU:
- fprintf(stderr, BPF_OP(iter->code) == BPF_NEG
- ? "A := -A\n" : "A := A %s 0x%x\n",
- BPF_OP(iter->code) == BPF_ADD ? "+" :
- BPF_OP(iter->code) == BPF_SUB ? "-" :
- BPF_OP(iter->code) == BPF_MUL ? "*" :
- BPF_OP(iter->code) == BPF_DIV ? "/" :
- BPF_OP(iter->code) == BPF_MOD ? "%" :
- BPF_OP(iter->code) == BPF_OR ? "|" :
- BPF_OP(iter->code) == BPF_XOR ? "^" :
- BPF_OP(iter->code) == BPF_AND ? "&" :
- BPF_OP(iter->code) == BPF_LSH ? "<<" :
- BPF_OP(iter->code) == BPF_RSH ? ">>" : "???",
- (int)iter->k);
- break;
default:
fprintf(stderr, "???\n");
break;
diff --git a/sandbox/linux/seccomp-bpf/errorcode.h b/sandbox/linux/seccomp-bpf/errorcode.h
index 67890c6..d2661db 100644
--- a/sandbox/linux/seccomp-bpf/errorcode.h
+++ b/sandbox/linux/seccomp-bpf/errorcode.h
@@ -20,17 +20,11 @@ struct arch_seccomp_data;
class ErrorCode {
public:
enum {
- // Allow this system call. The value of ERR_ALLOWED is pretty much
- // completely arbitrary. But we want to pick it so that is is unlikely
- // to be passed in accidentally, when the user intended to return an
- // "errno" (see below) value instead.
- ERR_ALLOWED = 0x04000000,
+ // Allow this system call.
+ ERR_ALLOWED = 0x0000,
// Deny the system call with a particular "errno" value.
- // N.B.: It is also possible to return "0" here. That would normally
- // indicate success, but it won't actually run the system call.
- // This is very different from return ERR_ALLOWED.
- ERR_MIN_ERRNO = 0,
+ ERR_MIN_ERRNO = 1,
ERR_MAX_ERRNO = 4095,
// This code should never be used directly, it is used internally only.
@@ -48,42 +42,11 @@ class ErrorCode {
typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void *aux);
enum ArgType {
- // A conditional test should operate on the 32bit part of the system call
- // argument.
- // On 64bit architectures, this verifies that the caller did not actually
- // pass in a 64bit value. If they did, that will be interpreted as an
- // attempt at breaking the sandbox and results in the program getting
- // terminated.
- // In other words, only perform a 32bit test, if you are sure this
- // particular system call would never legitimately take a 64bit argument.
- TP_32BIT,
-
- // A conditional test should operate on 64bit arguments. It is harmless
- // to perform a 64bit test on a 32bit system, as the top 32 bits of all
- // arguments will always be zero.
- TP_64BIT,
+ TP_32BIT, TP_64BIT,
};
enum Operation {
- // Test whether the system call argument is equal to the operand.
- OP_EQUAL,
-
- // Test whether the system call argument is greater (or equal) to the
- // operand. Please note that all tests always operate on unsigned
- // values. You can generally emulate signed tests, if that's what you
- // need.
- // TODO(markus): Check whether we should automatically emulate signed
- // operations.
- OP_GREATER_UNSIGNED, OP_GREATER_EQUAL_UNSIGNED,
-
- // Tests a system call argument against a bit mask.
- // The "ALL_BITS" variant performs this test: "arg & mask == mask"
- // This implies that a mask of zero always results in a passing test.
- // The "ANY_BITS" variant performs this test: "arg & mask != 0"
- // This implies that a mask of zero always results in a failing test.
- OP_HAS_ALL_BITS, OP_HAS_ANY_BITS,
-
- // Total number of operations.
+ OP_EQUAL, OP_GREATER, OP_GREATER_EQUAL, OP_HAS_BITS,
OP_NUM_OPS,
};
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
index 130845f..366706f 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -60,17 +60,6 @@ void SetIsInSigHandler() {
sigprocmask(SIG_BLOCK, &mask, NULL);
}
-template<class T> int popcount(T x);
-template<> int popcount<unsigned int>(unsigned int x) {
- return __builtin_popcount(x);
-}
-template<> int popcount<unsigned long>(unsigned long x) {
- return __builtin_popcountl(x);
-}
-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 :-)
@@ -759,114 +748,13 @@ Instruction *Sandbox::CondExpression(CodeGen *gen, const ErrorCode& cond) {
if (cond.width_ == ErrorCode::TP_64BIT) {
msb_tail = gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K,
static_cast<uint32_t>(cond.value_ >> 32),
- lsb_head,
+ NULL,
RetExpression(gen, *cond.failed_));
gen->JoinInstructions(msb_head, msb_tail);
}
break;
- case ErrorCode::OP_HAS_ALL_BITS:
- // Check the bits in the LSB half of the system call argument. Our
- // OP_HAS_ALL_BITS operator passed, iff all of the bits are set. This is
- // different from the kernel's BPF_JSET operation which passes, if any of
- // the bits are set.
- // Of course, if there is only a single set bit (or none at all), then
- // things get easier.
- {
- uint32_t lsb_bits = static_cast<uint32_t>(cond.value_);
- int lsb_bit_count = popcount(lsb_bits);
- if (lsb_bit_count == 0) {
- // No bits are set in the LSB half. The test will always pass.
- lsb_head = RetExpression(gen, *cond.passed_);
- lsb_tail = NULL;
- } else if (lsb_bit_count == 1) {
- // Exactly one bit is set in the LSB half. We can use the BPF_JSET
- // operator.
- lsb_tail = gen->MakeInstruction(BPF_JMP+BPF_JSET+BPF_K,
- lsb_bits,
- RetExpression(gen, *cond.passed_),
- RetExpression(gen, *cond.failed_));
- gen->JoinInstructions(lsb_head, lsb_tail);
- } else {
- // More than one bit is set in the LSB half. We need to combine
- // BPF_AND and BPF_JEQ to test whether all of these bits are in fact
- // set in the system call argument.
- gen->JoinInstructions(lsb_head,
- gen->MakeInstruction(BPF_ALU+BPF_AND+BPF_K,
- lsb_bits,
- lsb_tail = gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K,
- lsb_bits,
- RetExpression(gen, *cond.passed_),
- RetExpression(gen, *cond.failed_))));
- }
- }
-
- // If we are looking at a 64bit argument, we need to also check the bits
- // in the MSB half of the system call argument.
- if (cond.width_ == ErrorCode::TP_64BIT) {
- uint32_t msb_bits = static_cast<uint32_t>(cond.value_ >> 32);
- int msb_bit_count = popcount(msb_bits);
- if (msb_bit_count == 0) {
- // No bits are set in the MSB half. The test will always pass.
- msb_head = lsb_head;
- } else if (msb_bit_count == 1) {
- // Exactly one bit is set in the MSB half. We can use the BPF_JSET
- // operator.
- msb_tail = gen->MakeInstruction(BPF_JMP+BPF_JSET+BPF_K,
- msb_bits,
- lsb_head,
- RetExpression(gen, *cond.failed_));
- gen->JoinInstructions(msb_head, msb_tail);
- } else {
- // More than one bit is set in the MSB half. We need to combine
- // BPF_AND and BPF_JEQ to test whether all of these bits are in fact
- // set in the system call argument.
- gen->JoinInstructions(msb_head,
- gen->MakeInstruction(BPF_ALU+BPF_AND+BPF_K,
- msb_bits,
- gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K,
- msb_bits,
- lsb_head,
- RetExpression(gen, *cond.failed_))));
- }
- }
- break;
- case ErrorCode::OP_HAS_ANY_BITS:
- // Check the bits in the LSB half of the system call argument. Our
- // OP_HAS_ANY_BITS operator passed, iff any of the bits are set. This maps
- // nicely to the kernel's BPF_JSET operation.
- {
- uint32_t lsb_bits = static_cast<uint32_t>(cond.value_);
- if (!lsb_bits) {
- // No bits are set in the LSB half. The test will always fail.
- lsb_head = RetExpression(gen, *cond.failed_);
- lsb_tail = NULL;
- } else {
- lsb_tail = gen->MakeInstruction(BPF_JMP+BPF_JSET+BPF_K,
- lsb_bits,
- RetExpression(gen, *cond.passed_),
- RetExpression(gen, *cond.failed_));
- gen->JoinInstructions(lsb_head, lsb_tail);
- }
- }
-
- // If we are looking at a 64bit argument, we need to also check the bits
- // in the MSB half of the system call argument.
- if (cond.width_ == ErrorCode::TP_64BIT) {
- uint32_t msb_bits = static_cast<uint32_t>(cond.value_ >> 32);
- if (!msb_bits) {
- // No bits are set in the MSB half. The test will always fail.
- msb_head = lsb_head;
- } else {
- msb_tail = gen->MakeInstruction(BPF_JMP+BPF_JSET+BPF_K,
- msb_bits,
- RetExpression(gen, *cond.passed_),
- lsb_head);
- gen->JoinInstructions(msb_head, msb_tail);
- }
- }
- break;
default:
- // TODO(markus): Need to add support for OP_GREATER
+ // TODO(markus): We can only check for equality so far.
SANDBOX_DIE("Not implemented");
break;
}
@@ -897,6 +785,8 @@ Instruction *Sandbox::CondExpression(CodeGen *gen, const ErrorCode& cond) {
gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K, 0,
lsb_head,
invalid_64bit));
+ } else {
+ gen->JoinInstructions(msb_tail, lsb_head);
}
return msb_head;
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
index 1142ce5..aee03fa 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.h
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
@@ -97,13 +97,6 @@
#define IPC_64 0x0100
#endif
-#ifndef BPF_MOD
-#define BPF_MOD 0x90
-#endif
-#ifndef BPF_XOR
-#define BPF_XOR 0xA0
-#endif
-
// In order to build will older tool chains, we currently have to avoid
// including <linux/seccomp.h>. Until that can be fixed (if ever). Rely on
// our own definitions of the seccomp kernel ABI.
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
index 015e2d2..90ec8ff 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <errno.h>
-#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/utsname.h>
@@ -18,10 +16,7 @@
#include "testing/gtest/include/gtest/gtest.h"
// Workaround for Android's prctl.h file.
-#ifndef PR_GET_ENDIAN
-#define PR_GET_ENDIAN 19
-#endif
-#ifndef PR_CAPBSET_READ
+#if !defined(PR_CAPBSET_READ)
#define PR_CAPBSET_READ 23
#define PR_CAPBSET_DROP 24
#endif
@@ -185,51 +180,6 @@ BPF_TEST(SandboxBpf, BasicBlacklistWithSigsys,
BPF_ASSERT(BPF_AUX == kExpectedReturnValue);
}
-// A simple test that verifies we can return arbitrary errno values.
-
-ErrorCode ErrnoTestPolicy(int sysno, void *) {
- if (!Sandbox::IsValidSyscallNumber(sysno)) {
- // FIXME: we should really not have to do that in a trivial policy
- return ErrorCode(ENOSYS);
- }
-
- switch (sysno) {
- case __NR_dup2:
- // Pretend that dup2() worked, but don't actually do anything.
- return ErrorCode(0);
- case __NR_setuid:
- // Return errno = 1
- return ErrorCode(1);
- case __NR_setgid:
- // Return maximum errno value (typically 4095).
- return ErrorCode(ErrorCode::ERR_MAX_ERRNO);
- default:
- return ErrorCode(ErrorCode::ERR_ALLOWED);
- }
-}
-
-BPF_TEST(SandboxBpf, ErrnoTest, ErrnoTestPolicy) {
- // Verify that dup2() returns success, but doesn't actually run.
- int fds[4];
- BPF_ASSERT(pipe(fds) == 0);
- BPF_ASSERT(pipe(fds+2) == 0);
- BPF_ASSERT(dup2(fds[2], fds[0]) == 0);
- char buf[1] = { };
- BPF_ASSERT(write(fds[1], "\x55", 1) == 1);
- BPF_ASSERT(write(fds[3], "\xAA", 1) == 1);
- BPF_ASSERT(read(fds[0], buf, 1) == 1);
-
- // If dup2() executed, we will read \xAA, but it dup2() has been turned
- // into a no-op by our policy, then we will read \x55.
- BPF_ASSERT(buf[0] == '\x55');
-
- // Verify that we can return the minimum and maximum errno values.
- BPF_ASSERT(setuid(0) == -1);
- BPF_ASSERT(errno == 1);
- BPF_ASSERT(setgid(0) == -1);
- BPF_ASSERT(errno == ErrorCode::ERR_MAX_ERRNO);
-}
-
// A more complex, but synthetic policy. This tests the correctness of the BPF
// program by iterating through all syscalls and checking for an errno that
// depends on the syscall number. Unlike the Verifier, this exercises the BPF
@@ -640,54 +590,6 @@ BPF_TEST(SandboxBpf, UseOpenBroker, DenyOpenPolicy,
BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0);
}
-// Simple test demonstrating how to use Sandbox::Cond()
-
-ErrorCode SimpleCondTestPolicy(int sysno, void *) {
- if (!Sandbox::IsValidSyscallNumber(sysno)) {
- // FIXME: we should really not have to do that in a trivial policy
- return ErrorCode(ENOSYS);
- }
-
- // We deliberately return unusual errno values upon failure, so that we
- // can uniquely test for these values. In a "real" policy, you would want
- // to return more traditional values.
- switch (sysno) {
- case __NR_open:
- // Allow opening files for reading, but don't allow writing.
- COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits);
- return Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
- O_ACCMODE /* 0x3 */,
- ErrorCode(EROFS),
- ErrorCode(ErrorCode::ERR_ALLOWED));
- case __NR_prctl:
- // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but
- // disallow everything else.
- return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
- PR_SET_DUMPABLE,
- ErrorCode(ErrorCode::ERR_ALLOWED),
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
- PR_GET_DUMPABLE,
- ErrorCode(ErrorCode::ERR_ALLOWED),
- ErrorCode(ENOMEM)));
- default:
- return ErrorCode(ErrorCode::ERR_ALLOWED);
- }
-}
-
-BPF_TEST(SandboxBpf, SimpleCondTest, SimpleCondTestPolicy) {
- int fd;
- BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1);
- BPF_ASSERT(errno == EROFS);
- BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0);
- close(fd);
-
- int ret;
- BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0);
- BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1-ret) == 0);
- BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1);
- BPF_ASSERT(errno == ENOMEM);
-}
-
// This test exercises the Sandbox::Cond() method by building a complex
// tree of conditional equality operations. It then makes system calls and
// verifies that they return the values that we expected from our BPF
@@ -1006,7 +908,7 @@ ErrorCode EqualityArgumentWidthPolicy(int sysno, void *) {
Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
0x55555555, ErrorCode(1), ErrorCode(2)),
Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_EQUAL,
- 0x55555555AAAAAAAAULL, ErrorCode(1), ErrorCode(2)));
+ 0x55555555AAAAAAAAull, ErrorCode(1), ErrorCode(2)));
} else {
return ErrorCode(ErrorCode::ERR_ALLOWED);
}
@@ -1019,10 +921,10 @@ BPF_TEST(SandboxBpf, EqualityArgumentWidth, EqualityArgumentWidthPolicy) {
// On 32bit machines, there is no way to pass a 64bit argument through the
// syscall interface. So, we have to skip the part of the test that requires
// 64bit arguments.
- BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1);
- BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2);
- BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2);
- BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2);
+ BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAull) == -1);
+ BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ull) == -2);
+ BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ull) == -2);
+ BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAull) == -2);
#endif
}
@@ -1033,7 +935,7 @@ BPF_TEST(SandboxBpf, EqualityArgumentWidth, EqualityArgumentWidthPolicy) {
BPF_DEATH_TEST(SandboxBpf, EqualityArgumentUnallowed64bit,
DEATH_MESSAGE("Unexpected 64bit argument detected"),
EqualityArgumentWidthPolicy) {
- SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL);
+ SandboxSyscall(__NR_uname, 0, 0x5555555555555555ull);
}
#endif
@@ -1053,7 +955,7 @@ BPF_TEST(SandboxBpf, EqualityWithNegativeArguments,
EqualityWithNegativeArgumentsPolicy) {
BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1);
BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1);
- BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1);
+ BPF_ASSERT(SandboxSyscall(__NR_uname, -1ll) == -1);
}
#if __SIZEOF_POINTER__ > 4
@@ -1063,370 +965,8 @@ BPF_DEATH_TEST(SandboxBpf, EqualityWithNegative64bitArguments,
// When expecting a 32bit system call argument, we look at the MSB of the
// 64bit value and allow both "0" and "-1". But the latter is allowed only
// iff the LSB was negative. So, this death test should error out.
- BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1);
+ BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000ll) == -1);
}
#endif
-ErrorCode AllBitTestPolicy(int sysno, void *) {
- // Test the OP_HAS_ALL_BITS conditional test operator with a couple of
- // different bitmasks. We try to find bitmasks that could conceivably
- // touch corner cases.
- // For all of these tests, we override the uname(). We can make use with
- // a single system call number, as we use the first system call argument to
- // select the different bit masks that we want to test against.
- if (!Sandbox::IsValidSyscallNumber(sysno)) {
- // FIXME: we should really not have to do that in a trivial policy
- return ErrorCode(ENOSYS);
- } else if (sysno == __NR_uname) {
- return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0,
- Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x0,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1,
- Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x1,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 2,
- Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x3,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 3,
- Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x80000000,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 4,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x0,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 5,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x1,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 6,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x3,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 7,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x80000000,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 8,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x100000000ULL,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 9,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x300000000ULL,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS,
- 0x100000001ULL,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Kill("Invalid test case number"))))))))))));
-
- } else {
- return ErrorCode(ErrorCode::ERR_ALLOWED);
- }
-}
-
-BPF_TEST(SandboxBpf, AllBitTests, AllBitTestPolicy) {
- // Our uname() system call returns ErrorCode(1) for success and
- // ErrorCode(0) for failure. SandboxSyscall() turns this into an
- // exit code of -1 or 0. This is compatible with traditional
- // C-style boolean test values.
-
- // 32bit test: all of 0x0 (should always be true)
- BPF_ASSERT( SandboxSyscall(__NR_uname, 0, 0));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 0, 1));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 0, 3));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 0, 0xFFFFFFFFU));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 0, -1LL));
-
- // 32bit test: all of 0x1
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 1, 0));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 1, 1));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 1, 2));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 1, 3));
-
- // 32bit test: all of 0x3
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 2, 0));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 2, 1));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 2, 2));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 2, 3));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 2, 7));
-
- // 32bit test: all of 0x80000000
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 3, 0));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 3, 0x40000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 3, 0x80000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 3, 0xC0000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 3,-0x80000000LL));
-
- // 64bit test: all of 0x0 (should always be true)
- BPF_ASSERT( SandboxSyscall(__NR_uname, 4, 0));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 4, 1));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 4, 3));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 4, 0xFFFFFFFFU));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 4, 0x100000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 4, 0x300000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 4, 0x8000000000000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 4, -1LL));
-
- // 64bit test: all of 0x1
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 5, 0));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 5, 1));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 5, 2));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 5, 3));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 5, 0x100000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 5, 0x100000001LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 5, 0x100000002LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 5, 0x100000003LL));
-
- // 64bit test: all of 0x3
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 6, 0));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 6, 1));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 6, 2));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 3));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 7));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 6, 0x100000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 6, 0x100000001LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 6, 0x100000002LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 0x100000003LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 0x100000007LL));
-
- // 64bit test: all of 0x80000000
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 7, 0));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 7, 0x40000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7, 0x80000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7, 0xC0000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7,-0x80000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 7, 0x100000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 7, 0x140000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7, 0x180000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7, 0x1C0000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7,-0x180000000LL));
-
- // 64bit test: all of 0x100000000
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 8, 0x000000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 8, 0x100000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 8, 0x200000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 8, 0x300000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 8, 0x000000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 8, 0x100000001LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 8, 0x200000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 8, 0x300000001LL));
-
- // 64bit test: all of 0x300000000
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 9, 0x000000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 9, 0x100000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 9, 0x200000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x300000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x700000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 9, 0x000000001LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 9, 0x100000001LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 9, 0x200000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x300000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x700000001LL));
-
- // 64bit test: all of 0x100000001
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 10, 0x000000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 10, 0x000000001LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 10, 0x100000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 10, 0x100000001LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 10, 0xFFFFFFFFU));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 10, -1L));
-}
-
-ErrorCode AnyBitTestPolicy(int sysno, void *) {
- // Test the OP_HAS_ANY_BITS conditional test operator with a couple of
- // different bitmasks. We try to find bitmasks that could conceivably
- // touch corner cases.
- // For all of these tests, we override the uname(). We can make use with
- // a single system call number, as we use the first system call argument to
- // select the different bit masks that we want to test against.
- if (!Sandbox::IsValidSyscallNumber(sysno)) {
- // FIXME: we should really not have to do that in a trivial policy
- return ErrorCode(ENOSYS);
- } else if (sysno == __NR_uname) {
- return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0,
- Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x0,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1,
- Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x1,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 2,
- Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x3,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 3,
- Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x80000000,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 4,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x0,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 5,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x1,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 6,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x3,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 7,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x80000000,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 8,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x100000000ULL,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 9,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x300000000ULL,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10,
- Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS,
- 0x100000001ULL,
- ErrorCode(1), ErrorCode(0)),
-
- Sandbox::Kill("Invalid test case number"))))))))))));
-
- } else {
- return ErrorCode(ErrorCode::ERR_ALLOWED);
- }
-}
-
-BPF_TEST(SandboxBpf, AnyBitTests, AnyBitTestPolicy) {
- // Our uname() system call returns ErrorCode(1) for success and
- // ErrorCode(0) for failure. SandboxSyscall() turns this into an
- // exit code of -1 or 0. This is compatible with traditional
- // C-style boolean test values.
-
- // 32bit test: any of 0x0 (should always be false)
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 0, 0));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 0, 1));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 0, 3));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 0, 0xFFFFFFFFU));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 0, -1LL));
-
- // 32bit test: any of 0x1
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 1, 0));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 1, 1));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 1, 2));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 1, 3));
-
- // 32bit test: any of 0x3
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 2, 0));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 2, 1));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 2, 2));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 2, 3));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 2, 7));
-
- // 32bit test: any of 0x80000000
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 3, 0));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 3, 0x40000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 3, 0x80000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 3, 0xC0000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 3,-0x80000000LL));
-
- // 64bit test: any of 0x0 (should always be false)
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 4, 0));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 4, 1));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 4, 3));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 4, 0xFFFFFFFFU));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 4, 0x100000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 4, 0x300000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 4, 0x8000000000000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 4, -1LL));
-
- // 64bit test: any of 0x1
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 5, 0));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 5, 1));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 5, 2));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 5, 3));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 5, 0x100000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 5, 0x100000001LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 5, 0x100000002LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 5, 0x100000003LL));
-
- // 64bit test: any of 0x3
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 6, 0));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 1));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 2));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 3));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 7));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 6, 0x100000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 0x100000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 0x100000002LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 0x100000003LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 6, 0x100000007LL));
-
- // 64bit test: any of 0x80000000
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 7, 0));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 7, 0x40000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7, 0x80000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7, 0xC0000000U));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7,-0x80000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 7, 0x100000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 7, 0x140000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7, 0x180000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7, 0x1C0000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 7,-0x180000000LL));
-
- // 64bit test: any of 0x100000000
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 8, 0x000000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 8, 0x100000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 8, 0x200000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 8, 0x300000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 8, 0x000000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 8, 0x100000001LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 8, 0x200000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 8, 0x300000001LL));
-
- // 64bit test: any of 0x300000000
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 9, 0x000000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x100000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x200000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x300000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x700000000LL));
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 9, 0x000000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x100000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x200000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x300000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 9, 0x700000001LL));
-
- // 64bit test: any of 0x100000001
- BPF_ASSERT(!SandboxSyscall(__NR_uname, 10, 0x000000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 10, 0x000000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 10, 0x100000000LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 10, 0x100000001LL));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 10, 0xFFFFFFFFU));
- BPF_ASSERT( SandboxSyscall(__NR_uname, 10, -1L));
-}
-
} // namespace
diff --git a/sandbox/linux/seccomp-bpf/verifier.cc b/sandbox/linux/seccomp-bpf/verifier.cc
index 0403e1b..1c99619 100644
--- a/sandbox/linux/seccomp-bpf/verifier.cc
+++ b/sandbox/linux/seccomp-bpf/verifier.cc
@@ -112,41 +112,7 @@ bool Verifier::VerifyErrorCode(const std::vector<struct sock_filter>& program,
}
}
break;
- case ErrorCode::OP_HAS_ALL_BITS:
- case ErrorCode::OP_HAS_ANY_BITS:
- // A comprehensive test of bit values is difficult and potentially rather
- // time-expensive. We avoid doing so at run-time and instead rely on the
- // unittest for full testing. The test that we have here covers just the
- // common cases. We test against the bitmask itself, all zeros and all
- // ones.
- {
- // Testing "any" bits against a zero mask is always false. So, there
- // are some cases, where we expect tests to take the "failed_" branch
- // even though this is a test that normally should take "passed_".
- const ErrorCode& passed =
- !code.value_ && code.op_ == ErrorCode::OP_HAS_ANY_BITS
- ? *code.failed_ : *code.passed_;
- // Similary, testing for "all" bits in a zero mask is always true. So,
- // some cases pass despite them normally failing.
- const ErrorCode& failed =
- !code.value_ && code.op_ == ErrorCode::OP_HAS_ALL_BITS
- ? *code.passed_ : *code.failed_;
-
- data->args[code.argno_] = code.value_;
- if (!VerifyErrorCode(program, data, passed, err)) {
- return false;
- }
- data->args[code.argno_] = -1LL;
- if (!VerifyErrorCode(program, data, passed, err)) {
- return false;
- }
- data->args[code.argno_] = 0;
- if (!VerifyErrorCode(program, data, failed, err)) {
- return false;
- }
- }
- break;
- default: // TODO(markus): Need to add support for OP_GREATER
+ default: // TODO(markus): We can only check for equality so far.
*err = "Unsupported operation in conditional error code";
return false;
}
@@ -193,9 +159,6 @@ uint32_t Verifier::EvaluateBPF(const std::vector<struct sock_filter>& program,
return 0;
}
return r; }
- case BPF_ALU:
- Alu(&state, insn, err);
- break;
default:
*err = "Unexpected instruction in BPF program";
break;
@@ -285,69 +248,4 @@ uint32_t Verifier::Ret(State *, const struct sock_filter& insn,
return insn.k;
}
-void Verifier::Alu(State *state, const struct sock_filter& insn,
- const char **err) {
- if (BPF_OP(insn.code) == BPF_NEG) {
- state->accumulator = -state->accumulator;
- return;
- } else {
- if (BPF_SRC(insn.code) != BPF_K) {
- *err = "Unexpected source operand in arithmetic operation";
- return;
- }
- switch (BPF_OP(insn.code)) {
- case BPF_ADD:
- state->accumulator += insn.k;
- break;
- case BPF_SUB:
- state->accumulator -= insn.k;
- break;
- case BPF_MUL:
- state->accumulator *= insn.k;
- break;
- case BPF_DIV:
- if (!insn.k) {
- *err = "Illegal division by zero";
- break;
- }
- state->accumulator /= insn.k;
- break;
- case BPF_MOD:
- if (!insn.k) {
- *err = "Illegal division by zero";
- break;
- }
- state->accumulator %= insn.k;
- break;
- case BPF_OR:
- state->accumulator |= insn.k;
- break;
- case BPF_XOR:
- state->accumulator ^= insn.k;
- break;
- case BPF_AND:
- state->accumulator &= insn.k;
- break;
- case BPF_LSH:
- if (insn.k > 32) {
- *err = "Illegal shift operation";
- break;
- }
- state->accumulator <<= insn.k;
- break;
- case BPF_RSH:
- if (insn.k > 32) {
- *err = "Illegal shift operation";
- break;
- }
- state->accumulator >>= insn.k;
- break;
- default:
- *err = "Invalid operator in arithmetic operation";
- break;
- }
- }
-}
-
-
} // namespace
diff --git a/sandbox/linux/seccomp-bpf/verifier.h b/sandbox/linux/seccomp-bpf/verifier.h
index 26a3156..f66e7e93 100644
--- a/sandbox/linux/seccomp-bpf/verifier.h
+++ b/sandbox/linux/seccomp-bpf/verifier.h
@@ -69,8 +69,6 @@ class Verifier {
const char **err);
static uint32_t Ret(State *state, const struct sock_filter& insn,
const char **err);
- static void Alu(State *state, const struct sock_filter& insn,
- const char **err);
DISALLOW_IMPLICIT_CONSTRUCTORS(Verifier);
};