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 #ifndef SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__ 6 #define SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__ 7 8 #include <stdint.h> 9 10 #include <iterator> 11 12 #include "base/macros.h" 13 #include "sandbox/sandbox_export.h" 14 15 namespace sandbox { 16 17 // Iterates over the entire system call range from 0..0xFFFFFFFFu. This 18 // iterator is aware of how system calls look like and will skip quickly 19 // over ranges that can't contain system calls. It iterates more slowly 20 // whenever it reaches a range that is potentially problematic, returning 21 // the last invalid value before a valid range of system calls, and the 22 // first invalid value after a valid range of syscalls. It iterates over 23 // individual values whenever it is in the normal range for system calls 24 // (typically MIN_SYSCALL..MAX_SYSCALL). 25 // 26 // Example usage: 27 // for (uint32_t sysnum : SyscallSet::All()) { 28 // // Do something with sysnum. 29 // } 30 class SANDBOX_EXPORT SyscallSet { 31 public: 32 class Iterator; 33 SyscallSet(const SyscallSet & ss)34 SyscallSet(const SyscallSet& ss) : set_(ss.set_) {} ~SyscallSet()35 ~SyscallSet() {} 36 37 Iterator begin() const; 38 Iterator end() const; 39 40 // All returns a SyscallSet that contains both valid and invalid 41 // system call numbers. All()42 static SyscallSet All() { return SyscallSet(Set::ALL); } 43 44 // ValidOnly returns a SyscallSet that contains only valid system 45 // call numbers. ValidOnly()46 static SyscallSet ValidOnly() { return SyscallSet(Set::VALID_ONLY); } 47 48 // InvalidOnly returns a SyscallSet that contains only invalid 49 // system call numbers, but still omits numbers in the middle of a 50 // range of invalid system call numbers. InvalidOnly()51 static SyscallSet InvalidOnly() { return SyscallSet(Set::INVALID_ONLY); } 52 53 // IsValid returns whether |num| specifies a valid system call 54 // number. 55 static bool IsValid(uint32_t num); 56 57 private: 58 enum class Set { ALL, VALID_ONLY, INVALID_ONLY }; 59 SyscallSet(Set set)60 explicit SyscallSet(Set set) : set_(set) {} 61 62 Set set_; 63 64 friend bool operator==(const SyscallSet&, const SyscallSet&); 65 DISALLOW_ASSIGN(SyscallSet); 66 }; 67 68 SANDBOX_EXPORT bool operator==(const SyscallSet& lhs, const SyscallSet& rhs); 69 70 // Iterator provides C++ input iterator semantics for traversing a 71 // SyscallSet. 72 class SyscallSet::Iterator 73 : public std::iterator<std::input_iterator_tag, uint32_t> { 74 public: Iterator(const Iterator & it)75 Iterator(const Iterator& it) 76 : set_(it.set_), done_(it.done_), num_(it.num_) {} ~Iterator()77 ~Iterator() {} 78 79 uint32_t operator*() const; 80 Iterator& operator++(); 81 82 private: 83 Iterator(Set set, bool done); 84 85 uint32_t NextSyscall() const; 86 87 Set set_; 88 bool done_; 89 uint32_t num_; 90 91 friend SyscallSet; 92 friend bool operator==(const Iterator&, const Iterator&); 93 DISALLOW_ASSIGN(Iterator); 94 }; 95 96 SANDBOX_EXPORT bool operator==(const SyscallSet::Iterator& lhs, 97 const SyscallSet::Iterator& rhs); 98 SANDBOX_EXPORT bool operator!=(const SyscallSet::Iterator& lhs, 99 const SyscallSet::Iterator& rhs); 100 101 } // namespace sandbox 102 103 #endif // SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__ 104