1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "sandbox/linux/seccomp-bpf/errorcode.h" 6 7#include "sandbox/linux/seccomp-bpf/die.h" 8#include "sandbox/linux/seccomp-bpf/linux_seccomp.h" 9 10namespace sandbox { 11 12ErrorCode::ErrorCode() : error_type_(ET_INVALID), err_(SECCOMP_RET_INVALID) { 13} 14 15ErrorCode::ErrorCode(int err) { 16 switch (err) { 17 case ERR_ALLOWED: 18 err_ = SECCOMP_RET_ALLOW; 19 error_type_ = ET_SIMPLE; 20 break; 21 case ERR_MIN_ERRNO... ERR_MAX_ERRNO: 22 err_ = SECCOMP_RET_ERRNO + err; 23 error_type_ = ET_SIMPLE; 24 break; 25 default: 26 if ((err & ~SECCOMP_RET_DATA) == ERR_TRACE) { 27 err_ = SECCOMP_RET_TRACE + (err & SECCOMP_RET_DATA); 28 error_type_ = ET_SIMPLE; 29 break; 30 } 31 SANDBOX_DIE("Invalid use of ErrorCode object"); 32 } 33} 34 35ErrorCode::ErrorCode(Trap::TrapFnc fnc, const void* aux, bool safe) 36 : error_type_(ET_TRAP), 37 fnc_(fnc), 38 aux_(const_cast<void*>(aux)), 39 safe_(safe), 40 err_(SECCOMP_RET_TRAP + Trap::MakeTrap(fnc, aux, safe)) { 41} 42 43ErrorCode::ErrorCode(int argno, 44 ArgType width, 45 uint64_t mask, 46 uint64_t value, 47 const ErrorCode* passed, 48 const ErrorCode* failed) 49 : error_type_(ET_COND), 50 mask_(mask), 51 value_(value), 52 argno_(argno), 53 width_(width), 54 passed_(passed), 55 failed_(failed), 56 err_(SECCOMP_RET_INVALID) { 57} 58 59bool ErrorCode::Equals(const ErrorCode& err) const { 60 if (error_type_ == ET_INVALID || err.error_type_ == ET_INVALID) { 61 SANDBOX_DIE("Dereferencing invalid ErrorCode"); 62 } 63 if (error_type_ != err.error_type_) { 64 return false; 65 } 66 if (error_type_ == ET_SIMPLE || error_type_ == ET_TRAP) { 67 return err_ == err.err_; 68 } else if (error_type_ == ET_COND) { 69 return mask_ == err.mask_ && value_ == err.value_ && argno_ == err.argno_ && 70 width_ == err.width_ && passed_->Equals(*err.passed_) && 71 failed_->Equals(*err.failed_); 72 } else { 73 SANDBOX_DIE("Corrupted ErrorCode"); 74 } 75} 76 77bool ErrorCode::LessThan(const ErrorCode& err) const { 78 // Implementing a "LessThan()" operator allows us to use ErrorCode objects 79 // as keys in STL containers; most notably, it also allows us to put them 80 // into std::set<>. Actual ordering is not important as long as it is 81 // deterministic. 82 if (error_type_ == ET_INVALID || err.error_type_ == ET_INVALID) { 83 SANDBOX_DIE("Dereferencing invalid ErrorCode"); 84 } 85 if (error_type_ != err.error_type_) { 86 return error_type_ < err.error_type_; 87 } else { 88 if (error_type_ == ET_SIMPLE || error_type_ == ET_TRAP) { 89 return err_ < err.err_; 90 } else if (error_type_ == ET_COND) { 91 if (mask_ != err.mask_) { 92 return mask_ < err.mask_; 93 } else if (value_ != err.value_) { 94 return value_ < err.value_; 95 } else if (argno_ != err.argno_) { 96 return argno_ < err.argno_; 97 } else if (width_ != err.width_) { 98 return width_ < err.width_; 99 } else if (!passed_->Equals(*err.passed_)) { 100 return passed_->LessThan(*err.passed_); 101 } else if (!failed_->Equals(*err.failed_)) { 102 return failed_->LessThan(*err.failed_); 103 } else { 104 return false; 105 } 106 } else { 107 SANDBOX_DIE("Corrupted ErrorCode"); 108 } 109 } 110} 111 112} // namespace sandbox 113