#include <limits>
+#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
+#include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h"
+#include "sandbox/linux/bpf_dsl/policy.h"
+#include "sandbox/linux/bpf_dsl/policy_compiler.h"
+#include "sandbox/linux/seccomp-bpf/errorcode.h"
#include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
-#include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h"
#include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
namespace sandbox {
DISALLOW_IMPLICIT_CONSTRUCTORS(State);
};
-uint32_t EvaluateErrorCode(SandboxBPF* sandbox,
+uint32_t EvaluateErrorCode(bpf_dsl::PolicyCompiler* compiler,
const ErrorCode& code,
const struct arch_seccomp_data& data) {
if (code.error_type() == ErrorCode::ET_SIMPLE ||
(data.args[code.argno()] >> 32) &&
(data.args[code.argno()] & 0xFFFFFFFF80000000ull) !=
0xFFFFFFFF80000000ull) {
- return sandbox->Unexpected64bitArgument().err();
+ return compiler->Unexpected64bitArgument().err();
}
bool equal = (data.args[code.argno()] & code.mask()) == code.value();
return EvaluateErrorCode(
- sandbox, equal ? *code.passed() : *code.failed(), data);
+ compiler, equal ? *code.passed() : *code.failed(), data);
} else {
return SECCOMP_RET_INVALID;
}
}
-bool VerifyErrorCode(SandboxBPF* sandbox,
+bool VerifyErrorCode(bpf_dsl::PolicyCompiler* compiler,
const std::vector<struct sock_filter>& program,
struct arch_seccomp_data* data,
const ErrorCode& root_code,
uint32_t computed_ret = Verifier::EvaluateBPF(program, *data, err);
if (*err) {
return false;
- } else if (computed_ret != EvaluateErrorCode(sandbox, root_code, *data)) {
+ } else if (computed_ret != EvaluateErrorCode(compiler, root_code, *data)) {
// For efficiency's sake, we'd much rather compare "computed_ret"
// against "code.err()". This works most of the time, but it doesn't
// always work for nested conditional expressions. The test values
// Verify that we can check a value for simple equality.
data->args[code.argno()] = code.value();
if (!VerifyErrorCode(
- sandbox, program, data, root_code, *code.passed(), err)) {
+ compiler, program, data, root_code, *code.passed(), err)) {
return false;
}
if ((ignored_bits & kLower32Bits) != 0) {
data->args[code.argno()] = code.value() | (ignored_bits & kLower32Bits);
if (!VerifyErrorCode(
- sandbox, program, data, root_code, *code.passed(), err)) {
+ compiler, program, data, root_code, *code.passed(), err)) {
return false;
}
}
if ((ignored_bits & kUpper32Bits) != 0) {
data->args[code.argno()] = code.value() | (ignored_bits & kUpper32Bits);
if (!VerifyErrorCode(
- sandbox, program, data, root_code, *code.passed(), err)) {
+ compiler, program, data, root_code, *code.passed(), err)) {
return false;
}
}
if ((code.mask() & kLower32Bits) != 0) {
data->args[code.argno()] = code.value() ^ (code.mask() & kLower32Bits);
if (!VerifyErrorCode(
- sandbox, program, data, root_code, *code.failed(), err)) {
+ compiler, program, data, root_code, *code.failed(), err)) {
return false;
}
}
if ((code.mask() & kUpper32Bits) != 0) {
data->args[code.argno()] = code.value() ^ (code.mask() & kUpper32Bits);
if (!VerifyErrorCode(
- sandbox, program, data, root_code, *code.failed(), err)) {
+ compiler, program, data, root_code, *code.failed(), err)) {
return false;
}
}
// Arbitrary 64-bit values should be rejected.
data->args[code.argno()] = 1ULL << 32;
- if (!VerifyErrorCode(sandbox,
+ if (!VerifyErrorCode(compiler,
program,
data,
root_code,
- sandbox->Unexpected64bitArgument(),
+ compiler->Unexpected64bitArgument(),
err)) {
return false;
}
// Upper 32-bits set without the MSB of the lower 32-bits set should be
// rejected too.
data->args[code.argno()] = kUpper32Bits;
- if (!VerifyErrorCode(sandbox,
+ if (!VerifyErrorCode(compiler,
program,
data,
root_code,
- sandbox->Unexpected64bitArgument(),
+ compiler->Unexpected64bitArgument(),
err)) {
return false;
}
}
void Ld(State* state, const struct sock_filter& insn, const char** err) {
- if (BPF_SIZE(insn.code) != BPF_W || BPF_MODE(insn.code) != BPF_ABS) {
+ if (BPF_SIZE(insn.code) != BPF_W || BPF_MODE(insn.code) != BPF_ABS ||
+ insn.jt != 0 || insn.jf != 0) {
*err = "Invalid BPF_LD instruction";
return;
}
} // namespace
-bool Verifier::VerifyBPF(SandboxBPF* sandbox,
+bool Verifier::VerifyBPF(bpf_dsl::PolicyCompiler* compiler,
const std::vector<struct sock_filter>& program,
- const SandboxBPFPolicy& policy,
+ const bpf_dsl::Policy& policy,
const char** err) {
*err = NULL;
- for (SyscallIterator iter(false); !iter.Done();) {
- uint32_t sysnum = iter.Next();
+ for (uint32_t sysnum : SyscallSet::All()) {
// We ideally want to iterate over the full system call range and values
// just above and just below this range. This gives us the full result set
// of the "evaluators".
}
#endif
#endif
- ErrorCode code = iter.IsValid(sysnum)
- ? policy.EvaluateSyscall(sandbox, sysnum)
- : policy.InvalidSyscall(sandbox);
- if (!VerifyErrorCode(sandbox, program, &data, code, code, err)) {
+ ErrorCode code = SyscallSet::IsValid(sysnum)
+ ? policy.EvaluateSyscall(sysnum)->Compile(compiler)
+ : policy.InvalidSyscall()->Compile(compiler);
+ if (!VerifyErrorCode(compiler, program, &data, code, code, err)) {
return false;
}
}