X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fsandbox%2Flinux%2Fbpf_dsl%2Fbpf_dsl.cc;h=8144d805490722e9806d85d3e079f0154a322696;hb=3545e9f2671f595d2a2f3ee75ca0393b01e35ef6;hp=66cd09c22027902a5e7d4ed057a24d0883911365;hpb=7d210d4c7e9ba36e635eabc5b5780495f8a63292;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/sandbox/linux/bpf_dsl/bpf_dsl.cc b/src/sandbox/linux/bpf_dsl/bpf_dsl.cc index 66cd09c..8144d80 100644 --- a/src/sandbox/linux/bpf_dsl/bpf_dsl.cc +++ b/src/sandbox/linux/bpf_dsl/bpf_dsl.cc @@ -6,67 +6,128 @@ #include +#include + #include "base/logging.h" #include "base/memory/ref_counted.h" #include "sandbox/linux/seccomp-bpf/errorcode.h" #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -using namespace sandbox::bpf_dsl::internal; -typedef ::sandbox::Trap::TrapFnc TrapFnc; - namespace sandbox { namespace bpf_dsl { namespace { -class AllowResultExprImpl : public ResultExprImpl { +class AllowResultExprImpl : public internal::ResultExprImpl { public: AllowResultExprImpl() {} + virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { return ErrorCode(ErrorCode::ERR_ALLOWED); } private: virtual ~AllowResultExprImpl() {} + DISALLOW_COPY_AND_ASSIGN(AllowResultExprImpl); }; -class ErrorResultExprImpl : public ResultExprImpl { +class ErrorResultExprImpl : public internal::ResultExprImpl { public: explicit ErrorResultExprImpl(int err) : err_(err) { CHECK(err_ >= ErrorCode::ERR_MIN_ERRNO && err_ <= ErrorCode::ERR_MAX_ERRNO); } + virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { return ErrorCode(err_); } private: virtual ~ErrorResultExprImpl() {} + int err_; + DISALLOW_COPY_AND_ASSIGN(ErrorResultExprImpl); }; -class TrapResultExprImpl : public ResultExprImpl { +class KillResultExprImpl : public internal::ResultExprImpl { public: - TrapResultExprImpl(TrapFnc func, void* arg) : func_(func), arg_(arg) { + explicit KillResultExprImpl(const char* msg) : msg_(msg) { DCHECK(msg_); } + + virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { + return sb->Kill(msg_); + } + + private: + virtual ~KillResultExprImpl() {} + + const char* msg_; + + DISALLOW_COPY_AND_ASSIGN(KillResultExprImpl); +}; + +class TraceResultExprImpl : public internal::ResultExprImpl { + public: + TraceResultExprImpl(uint16_t aux) : aux_(aux) {} + + virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { + return ErrorCode(ErrorCode::ERR_TRACE + aux_); + } + + private: + virtual ~TraceResultExprImpl() {} + + uint16_t aux_; + + DISALLOW_COPY_AND_ASSIGN(TraceResultExprImpl); +}; + +class TrapResultExprImpl : public internal::ResultExprImpl { + public: + TrapResultExprImpl(Trap::TrapFnc func, const void* arg) + : func_(func), arg_(arg) { DCHECK(func_); } + virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { return sb->Trap(func_, arg_); } private: virtual ~TrapResultExprImpl() {} - TrapFnc func_; - void* arg_; + + Trap::TrapFnc func_; + const void* arg_; + DISALLOW_COPY_AND_ASSIGN(TrapResultExprImpl); }; -class IfThenResultExprImpl : public ResultExprImpl { +class UnsafeTrapResultExprImpl : public internal::ResultExprImpl { + public: + UnsafeTrapResultExprImpl(Trap::TrapFnc func, const void* arg) + : func_(func), arg_(arg) { + DCHECK(func_); + } + + virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { + return sb->UnsafeTrap(func_, arg_); + } + + private: + virtual ~UnsafeTrapResultExprImpl() {} + + Trap::TrapFnc func_; + const void* arg_; + + DISALLOW_COPY_AND_ASSIGN(UnsafeTrapResultExprImpl); +}; + +class IfThenResultExprImpl : public internal::ResultExprImpl { public: - IfThenResultExprImpl(BoolExpr cond, - ResultExpr then_result, - ResultExpr else_result) + IfThenResultExprImpl(const BoolExpr& cond, + const ResultExpr& then_result, + const ResultExpr& else_result) : cond_(cond), then_result_(then_result), else_result_(else_result) {} + virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { return cond_->Compile( sb, then_result_->Compile(sb), else_result_->Compile(sb)); @@ -74,37 +135,62 @@ class IfThenResultExprImpl : public ResultExprImpl { private: virtual ~IfThenResultExprImpl() {} + BoolExpr cond_; ResultExpr then_result_; ResultExpr else_result_; + DISALLOW_COPY_AND_ASSIGN(IfThenResultExprImpl); }; -class PrimitiveBoolExprImpl : public BoolExprImpl { +class ConstBoolExprImpl : public internal::BoolExprImpl { + public: + ConstBoolExprImpl(bool value) : value_(value) {} + + virtual ErrorCode Compile(SandboxBPF* sb, + ErrorCode true_ec, + ErrorCode false_ec) const OVERRIDE { + return value_ ? true_ec : false_ec; + } + + private: + virtual ~ConstBoolExprImpl() {} + + bool value_; + + DISALLOW_COPY_AND_ASSIGN(ConstBoolExprImpl); +}; + +class PrimitiveBoolExprImpl : public internal::BoolExprImpl { public: PrimitiveBoolExprImpl(int argno, ErrorCode::ArgType is_32bit, - ErrorCode::Operation op, + uint64_t mask, uint64_t value) - : argno_(argno), is_32bit_(is_32bit), op_(op), value_(value) {} + : argno_(argno), is_32bit_(is_32bit), mask_(mask), value_(value) {} + virtual ErrorCode Compile(SandboxBPF* sb, ErrorCode true_ec, ErrorCode false_ec) const OVERRIDE { - return sb->Cond(argno_, is_32bit_, op_, value_, true_ec, false_ec); + return sb->CondMaskedEqual( + argno_, is_32bit_, mask_, value_, true_ec, false_ec); } private: virtual ~PrimitiveBoolExprImpl() {} + int argno_; ErrorCode::ArgType is_32bit_; - ErrorCode::Operation op_; + uint64_t mask_; uint64_t value_; + DISALLOW_COPY_AND_ASSIGN(PrimitiveBoolExprImpl); }; -class NegateBoolExprImpl : public BoolExprImpl { +class NegateBoolExprImpl : public internal::BoolExprImpl { public: - explicit NegateBoolExprImpl(BoolExpr cond) : cond_(cond) {} + explicit NegateBoolExprImpl(const BoolExpr& cond) : cond_(cond) {} + virtual ErrorCode Compile(SandboxBPF* sb, ErrorCode true_ec, ErrorCode false_ec) const OVERRIDE { @@ -113,13 +199,17 @@ class NegateBoolExprImpl : public BoolExprImpl { private: virtual ~NegateBoolExprImpl() {} + BoolExpr cond_; + DISALLOW_COPY_AND_ASSIGN(NegateBoolExprImpl); }; -class AndBoolExprImpl : public BoolExprImpl { +class AndBoolExprImpl : public internal::BoolExprImpl { public: - AndBoolExprImpl(BoolExpr lhs, BoolExpr rhs) : lhs_(lhs), rhs_(rhs) {} + AndBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs) + : lhs_(lhs), rhs_(rhs) {} + virtual ErrorCode Compile(SandboxBPF* sb, ErrorCode true_ec, ErrorCode false_ec) const OVERRIDE { @@ -128,13 +218,18 @@ class AndBoolExprImpl : public BoolExprImpl { private: virtual ~AndBoolExprImpl() {} - BoolExpr lhs_, rhs_; + + BoolExpr lhs_; + BoolExpr rhs_; + DISALLOW_COPY_AND_ASSIGN(AndBoolExprImpl); }; -class OrBoolExprImpl : public BoolExprImpl { +class OrBoolExprImpl : public internal::BoolExprImpl { public: - OrBoolExprImpl(BoolExpr lhs, BoolExpr rhs) : lhs_(lhs), rhs_(rhs) {} + OrBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs) + : lhs_(lhs), rhs_(rhs) {} + virtual ErrorCode Compile(SandboxBPF* sb, ErrorCode true_ec, ErrorCode false_ec) const OVERRIDE { @@ -143,7 +238,10 @@ class OrBoolExprImpl : public BoolExprImpl { private: virtual ~OrBoolExprImpl() {} - BoolExpr lhs_, rhs_; + + BoolExpr lhs_; + BoolExpr rhs_; + DISALLOW_COPY_AND_ASSIGN(OrBoolExprImpl); }; @@ -151,33 +249,26 @@ class OrBoolExprImpl : public BoolExprImpl { namespace internal { +uint64_t DefaultMask(size_t size) { + switch (size) { + case 4: + return std::numeric_limits::max(); + case 8: + return std::numeric_limits::max(); + default: + CHECK(false) << "Unimplemented DefaultMask case"; + return 0; + } +} + BoolExpr ArgEq(int num, size_t size, uint64_t mask, uint64_t val) { - CHECK(num >= 0 && num < 6); - CHECK(size >= 1 && size <= 8); - CHECK_NE(0U, mask) << "zero mask doesn't make sense"; - CHECK_EQ(val, val & mask) << "val contains masked out bits"; + CHECK(size == 4 || size == 8); // TODO(mdempsky): Should we just always use TP_64BIT? const ErrorCode::ArgType arg_type = - (size <= 4) ? ErrorCode::TP_32BIT : ErrorCode::TP_64BIT; - - if (mask == static_cast(-1)) { - // Arg == Val - return BoolExpr(new const PrimitiveBoolExprImpl( - num, arg_type, ErrorCode::OP_EQUAL, val)); - } else if (mask == val) { - // (Arg & Mask) == Mask - return BoolExpr(new const PrimitiveBoolExprImpl( - num, arg_type, ErrorCode::OP_HAS_ALL_BITS, mask)); - } else if (val == 0) { - // (Arg & Mask) == 0, which is semantically equivalent to !((arg & mask) != - // 0). - return !BoolExpr(new const PrimitiveBoolExprImpl( - num, arg_type, ErrorCode::OP_HAS_ANY_BITS, mask)); - } else { - CHECK(false) << "Unimplemented ArgEq case"; - return BoolExpr(); - } + (size == 4) ? ErrorCode::TP_32BIT : ErrorCode::TP_64BIT; + + return BoolExpr(new const PrimitiveBoolExprImpl(num, arg_type, mask, val)); } } // namespace internal @@ -190,23 +281,39 @@ ResultExpr Error(int err) { return ResultExpr(new const ErrorResultExprImpl(err)); } -ResultExpr Trap(TrapFnc trap_func, void* aux) { +ResultExpr Kill(const char* msg) { + return ResultExpr(new const KillResultExprImpl(msg)); +} + +ResultExpr Trace(uint16_t aux) { + return ResultExpr(new const TraceResultExprImpl(aux)); +} + +ResultExpr Trap(Trap::TrapFnc trap_func, const void* aux) { return ResultExpr(new const TrapResultExprImpl(trap_func, aux)); } -BoolExpr operator!(BoolExpr cond) { +ResultExpr UnsafeTrap(Trap::TrapFnc trap_func, const void* aux) { + return ResultExpr(new const UnsafeTrapResultExprImpl(trap_func, aux)); +} + +BoolExpr BoolConst(bool value) { + return BoolExpr(new const ConstBoolExprImpl(value)); +} + +BoolExpr operator!(const BoolExpr& cond) { return BoolExpr(new const NegateBoolExprImpl(cond)); } -BoolExpr operator&&(BoolExpr lhs, BoolExpr rhs) { +BoolExpr operator&&(const BoolExpr& lhs, const BoolExpr& rhs) { return BoolExpr(new const AndBoolExprImpl(lhs, rhs)); } -BoolExpr operator||(BoolExpr lhs, BoolExpr rhs) { +BoolExpr operator||(const BoolExpr& lhs, const BoolExpr& rhs) { return BoolExpr(new const OrBoolExprImpl(lhs, rhs)); } -Elser If(BoolExpr cond, ResultExpr then_result) { +Elser If(const BoolExpr& cond, const ResultExpr& then_result) { return Elser(Cons::List()).ElseIf(cond, then_result); } @@ -219,12 +326,12 @@ Elser::Elser(const Elser& elser) : clause_list_(elser.clause_list_) { Elser::~Elser() { } -Elser Elser::ElseIf(BoolExpr cond, ResultExpr then_result) const { +Elser Elser::ElseIf(const BoolExpr& cond, const ResultExpr& then_result) const { return Elser( Cons::Make(std::make_pair(cond, then_result), clause_list_)); } -ResultExpr Elser::Else(ResultExpr else_result) const { +ResultExpr Elser::Else(const ResultExpr& else_result) const { // We finally have the default result expression for this // if/then/else sequence. Also, we've already accumulated all // if/then pairs into a list of reverse order (i.e., lower priority @@ -248,7 +355,7 @@ ResultExpr Elser::Else(ResultExpr else_result) const { // and end up with an appropriately chained tree. ResultExpr expr = else_result; - for (Cons::List it = clause_list_; it; it = it->tail()) { + for (Cons::List it = clause_list_; it.get(); it = it->tail()) { Clause clause = it->head(); expr = ResultExpr( new const IfThenResultExprImpl(clause.first, clause.second, expr)); @@ -269,8 +376,7 @@ ErrorCode SandboxBPFDSLPolicy::InvalidSyscall(SandboxBPF* sb) const { return InvalidSyscall()->Compile(sb); } -ResultExpr SandboxBPFDSLPolicy::Trap(::sandbox::Trap::TrapFnc trap_func, - void* aux) { +ResultExpr SandboxBPFDSLPolicy::Trap(Trap::TrapFnc trap_func, const void* aux) { return bpf_dsl::Trap(trap_func, aux); }