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