blob: b9f076d9321a392b5a6f85b99430ccbe1bd008e3 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__
#define SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__
#include <stdint.h>
#include <iterator>
#include "base/macros.h"
#include "sandbox/sandbox_export.h"
namespace sandbox {
// Iterates over the entire system call range from 0..0xFFFFFFFFu. This
// iterator is aware of how system calls look like and will skip quickly
// over ranges that can't contain system calls. It iterates more slowly
// whenever it reaches a range that is potentially problematic, returning
// the last invalid value before a valid range of system calls, and the
// first invalid value after a valid range of syscalls. It iterates over
// individual values whenever it is in the normal range for system calls
// (typically MIN_SYSCALL..MAX_SYSCALL).
//
// Example usage:
// for (uint32_t sysnum : SyscallSet::All()) {
// // Do something with sysnum.
// }
class SANDBOX_EXPORT SyscallSet {
public:
class Iterator;
SyscallSet(const SyscallSet& ss) : set_(ss.set_) {}
~SyscallSet() {}
Iterator begin() const;
Iterator end() const;
// All returns a SyscallSet that contains both valid and invalid
// system call numbers.
static SyscallSet All() { return SyscallSet(Set::ALL); }
// ValidOnly returns a SyscallSet that contains only valid system
// call numbers.
static SyscallSet ValidOnly() { return SyscallSet(Set::VALID_ONLY); }
// InvalidOnly returns a SyscallSet that contains only invalid
// system call numbers, but still omits numbers in the middle of a
// range of invalid system call numbers.
static SyscallSet InvalidOnly() { return SyscallSet(Set::INVALID_ONLY); }
// IsValid returns whether |num| specifies a valid system call
// number.
static bool IsValid(uint32_t num);
private:
enum class Set { ALL, VALID_ONLY, INVALID_ONLY };
explicit SyscallSet(Set set) : set_(set) {}
Set set_;
friend bool operator==(const SyscallSet&, const SyscallSet&);
DISALLOW_ASSIGN(SyscallSet);
};
SANDBOX_EXPORT bool operator==(const SyscallSet& lhs, const SyscallSet& rhs);
// Iterator provides C++ input iterator semantics for traversing a
// SyscallSet.
class SyscallSet::Iterator
: public std::iterator<std::input_iterator_tag, uint32_t> {
public:
Iterator(const Iterator& it)
: set_(it.set_), done_(it.done_), num_(it.num_) {}
~Iterator() {}
uint32_t operator*() const;
Iterator& operator++();
private:
Iterator(Set set, bool done);
uint32_t NextSyscall() const;
Set set_;
bool done_;
uint32_t num_;
friend SyscallSet;
friend bool operator==(const Iterator&, const Iterator&);
DISALLOW_ASSIGN(Iterator);
};
SANDBOX_EXPORT bool operator==(const SyscallSet::Iterator& lhs,
const SyscallSet::Iterator& rhs);
SANDBOX_EXPORT bool operator!=(const SyscallSet::Iterator& lhs,
const SyscallSet::Iterator& rhs);
} // namespace sandbox
#endif // SANDBOX_LINUX_BPF_DSL_SYSCALL_SET_H__