15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sandbox/linux/seccomp-bpf/die.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sandbox/linux/seccomp-bpf/errorcode.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace playground2 {
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ErrorCode::ErrorCode(int err) {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (err) {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case ERR_ALLOWED:
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    err_ = SECCOMP_RET_ALLOW;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_type_ = ET_SIMPLE;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    break;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case ERR_MIN_ERRNO ... ERR_MAX_ERRNO:
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    err_ = SECCOMP_RET_ERRNO + err;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_type_ = ET_SIMPLE;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    break;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default:
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SANDBOX_DIE("Invalid use of ErrorCode object");
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ErrorCode::ErrorCode(Trap::TrapFnc fnc, const void *aux, bool safe,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     uint16_t id)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : error_type_(ET_TRAP),
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fnc_(fnc),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aux_(const_cast<void *>(aux)),
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      safe_(safe),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      err_(SECCOMP_RET_TRAP + id) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ErrorCode::ErrorCode(int argno, ArgType width, Operation op, uint64_t value,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const ErrorCode *passed, const ErrorCode *failed)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : error_type_(ET_COND),
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      value_(value),
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      argno_(argno),
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width_(width),
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      op_(op),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      passed_(passed),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      failed_(failed),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      err_(SECCOMP_RET_INVALID) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (op < 0 || op >= OP_NUM_OPS) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SANDBOX_DIE("Invalid opcode in BPF sandbox rules");
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ErrorCode::Equals(const ErrorCode& err) const {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_type_ == ET_INVALID || err.error_type_ == ET_INVALID) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SANDBOX_DIE("Dereferencing invalid ErrorCode");
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_type_ != err.error_type_) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_type_ == ET_SIMPLE || error_type_ == ET_TRAP) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return err_ == err.err_;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (error_type_ == ET_COND) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value_   == err.value_   &&
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           argno_   == err.argno_   &&
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           width_   == err.width_   &&
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           op_      == err.op_      &&
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           passed_->Equals(*err.passed_) &&
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           failed_->Equals(*err.failed_);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SANDBOX_DIE("Corrupted ErrorCode");
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ErrorCode::LessThan(const ErrorCode& err) const {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementing a "LessThan()" operator allows us to use ErrorCode objects
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as keys in STL containers; most notably, it also allows us to put them
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // into std::set<>. Actual ordering is not important as long as it is
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deterministic.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_type_ == ET_INVALID || err.error_type_ == ET_INVALID) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SANDBOX_DIE("Dereferencing invalid ErrorCode");
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_type_ != err.error_type_) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return error_type_ < err.error_type_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (error_type_ == ET_SIMPLE || error_type_ == ET_TRAP) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return err_ < err.err_;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (error_type_ == ET_COND) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (value_ != err.value_) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return value_ < err.value_;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (argno_ != err.argno_) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return argno_ < err.argno_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (width_ != err.width_) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return width_ < err.width_;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (op_ != err.op_) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return op_ < err.op_;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (!passed_->Equals(*err.passed_)) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return passed_->LessThan(*err.passed_);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (!failed_->Equals(*err.failed_)) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return failed_->LessThan(*err.failed_);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SANDBOX_DIE("Corrupted ErrorCode");
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
107